Browse Source

use file-scoped namespacing for audit-logging module

pull/10696/head
Ahmet Çotur 5 years ago
parent
commit
312995263a
  1. 15
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/AbpAuditLoggingDomainSharedModule.cs
  2. 31
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/AuditLogActionConsts.cs
  3. 115
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/AuditLogConsts.cs
  4. 23
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/EntityChangeConsts.cs
  5. 39
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/EntityPropertyChangeConsts.cs
  6. 9
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/AuditLoggingResource.cs
  7. 51
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/ObjectExtending/AuditLoggingModuleExtensionConfiguration.cs
  8. 23
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/ObjectExtending/AuditLoggingModuleExtensionConfigurationDictionaryExtensions.cs
  9. 23
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/ObjectExtending/AuditLoggingModuleExtensionConsts.cs
  10. 13
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/AbpAuditLoggingDbProperties.cs
  11. 57
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/AbpAuditLoggingDomainModule.cs
  12. 155
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/AuditLog.cs
  13. 53
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/AuditLogAction.cs
  14. 129
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/AuditLogInfoToAuditLogConverter.cs
  15. 79
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/AuditingStore.cs
  16. 81
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/EntityChange.cs
  17. 15
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/EntityChangeWithUsername.cs
  18. 55
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/EntityPropertyChange.cs
  19. 9
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/IAuditLogInfoToAuditLogConverter.cs
  20. 129
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/IAuditLogRepository.cs
  21. 43
      modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/AbpAuditLoggingEfCoreQueryableExtensions.cs
  22. 27
      modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingDbContext.cs
  23. 161
      modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingDbContextModelBuilderExtensions.cs
  24. 19
      modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingEntityFrameworkCoreModule.cs
  25. 461
      modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs
  26. 13
      modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/IAuditLoggingDbContext.cs
  27. 23
      modules/audit-logging/src/Volo.Abp.AuditLogging.Installer/Volo/Abp/AuditLogging/AbpAuditLoggingInstallerModule.cs
  28. 29
      modules/audit-logging/src/Volo.Abp.AuditLogging.Installer/Volo/Abp/AuditLogging/AuditLoggingInstallerPipelineBuilder.cs
  29. 21
      modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbContextExtensions.cs
  30. 19
      modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbModule.cs
  31. 19
      modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/AuditLoggingMongoDbContext.cs
  32. 11
      modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/IAuditLoggingMongoDbContext.cs
  33. 456
      modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs
  34. 51
      modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingEntityFrameworkCoreTestModule.cs
  35. 7
      modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo/Abp/AuditLogging/EntityFrameworkCore/AuditLogRepository_Tests.cs
  36. 7
      modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo/Abp/AuditLogging/EntityFrameworkCore/AuditStore_Basic_Tests.cs
  37. 33
      modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs
  38. 9
      modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AuditLogRepository_Tests.cs
  39. 9
      modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AuditStore_Basic_Tests.cs
  40. 27
      modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoDbFixture.cs
  41. 13
      modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoTestCollection.cs
  42. 33
      modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AbpAuditLoggingTestBaseModule.cs
  43. 877
      modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditLogRepository_Tests.cs
  44. 13
      modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditLoggingTestBase.cs
  45. 9
      modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditLogging_Repository_Resolve_Tests.cs
  46. 177
      modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditStore_Basic_Tests.cs
  47. 23
      modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditingTestDataBuilder.cs
  48. 13
      modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo/Abp/AuditLogging/AbpAuditLoggingTestModule.cs
  49. 37
      modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo/Abp/AuditLogging/AuditLogsTestBase.cs
  50. 111
      modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo/Abp/AuditLogging/MultiTenantAuditLog_Tests.cs

15
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/AbpAuditLoggingDomainSharedModule.cs

@ -2,16 +2,15 @@
using Volo.Abp.Localization; using Volo.Abp.Localization;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
public class AbpAuditLoggingDomainSharedModule : AbpModule
{ {
public class AbpAuditLoggingDomainSharedModule : AbpModule public override void ConfigureServices(ServiceConfigurationContext context)
{ {
public override void ConfigureServices(ServiceConfigurationContext context) Configure<AbpLocalizationOptions>(options =>
{ {
Configure<AbpLocalizationOptions>(options => options.Resources.Add<AuditLoggingResource>("en");
{ });
options.Resources.Add<AuditLoggingResource>("en");
});
}
} }
} }

31
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/AuditLogActionConsts.cs

@ -1,20 +1,19 @@
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
public class AuditLogActionConsts
{ {
public class AuditLogActionConsts /// <summary>
{ /// Default value: 256
/// <summary> /// </summary>
/// Default value: 256 public static int MaxServiceNameLength { get; set; } = 256;
/// </summary>
public static int MaxServiceNameLength { get; set; } = 256;
/// <summary> /// <summary>
/// Default value: 128 /// Default value: 128
/// </summary> /// </summary>
public static int MaxMethodNameLength { get; set; } = 128; public static int MaxMethodNameLength { get; set; } = 128;
/// <summary> /// <summary>
/// Default value: 2000 /// Default value: 2000
/// </summary> /// </summary>
public static int MaxParametersLength { get; set; } = 2000; public static int MaxParametersLength { get; set; } = 2000;
}
} }

115
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/AuditLogConsts.cs

@ -1,60 +1,59 @@
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
public static class AuditLogConsts
{ {
public static class AuditLogConsts /// <summary>
{ /// Default value: 96
/// <summary> /// </summary>
/// Default value: 96 public static int MaxApplicationNameLength { get; set; } = 96;
/// </summary>
public static int MaxApplicationNameLength { get; set; } = 96; /// <summary>
/// Default value: 64
/// <summary> /// </summary>
/// Default value: 64 public static int MaxClientIpAddressLength { get; set; } = 64;
/// </summary>
public static int MaxClientIpAddressLength { get; set; } = 64; /// <summary>
/// Default value: 128
/// <summary> /// </summary>
/// Default value: 128 public static int MaxClientNameLength { get; set; } = 128;
/// </summary>
public static int MaxClientNameLength { get; set; } = 128; /// <summary>
/// Default value: 64
/// <summary> /// </summary>
/// Default value: 64 public static int MaxClientIdLength { get; set; } = 64;
/// </summary>
public static int MaxClientIdLength { get; set; } = 64; /// <summary>
/// Default value: 64
/// <summary> /// </summary>
/// Default value: 64 public static int MaxCorrelationIdLength { get; set; } = 64;
/// </summary>
public static int MaxCorrelationIdLength { get; set; } = 64; /// <summary>
/// Default value: 512
/// <summary> /// </summary>
/// Default value: 512 public static int MaxBrowserInfoLength { get; set; } = 512;
/// </summary>
public static int MaxBrowserInfoLength { get; set; } = 512; /// <summary>
/// Default value: 256
/// <summary> /// </summary>
/// Default value: 256 public static int MaxCommentsLength { get; set; } = 256;
/// </summary>
public static int MaxCommentsLength { get; set; } = 256; /// <summary>
/// Default value: 256
/// <summary> /// </summary>
/// Default value: 256 public static int MaxUrlLength { get; set; } = 256;
/// </summary>
public static int MaxUrlLength { get; set; } = 256; /// <summary>
/// Default value: 16
/// <summary> /// </summary>
/// Default value: 16 public static int MaxHttpMethodLength { get; set; } = 16;
/// </summary>
public static int MaxHttpMethodLength { get; set; } = 16; /// <summary>
/// Default value: 256
/// <summary> /// </summary>
/// Default value: 256 public static int MaxUserNameLength { get; set; } = 256;
/// </summary>
public static int MaxUserNameLength { get; set; } = 256; /// <summary>
/// Default value: 64
/// <summary> /// </summary>
/// Default value: 64 public static int MaxTenantNameLength { get; set; } = 64;
/// </summary>
public static int MaxTenantNameLength { get; set; } = 64;
}
} }

23
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/EntityChangeConsts.cs

@ -1,15 +1,14 @@
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
public class EntityChangeConsts
{ {
public class EntityChangeConsts /// <summary>
{ /// Default value: 128
/// <summary> /// </summary>
/// Default value: 128 public static int MaxEntityTypeFullNameLength { get; set; } = 128;
/// </summary>
public static int MaxEntityTypeFullNameLength { get; set; } = 128;
/// <summary> /// <summary>
/// Default value: 128 /// Default value: 128
/// </summary> /// </summary>
public static int MaxEntityIdLength { get; set; } = 128; public static int MaxEntityIdLength { get; set; } = 128;
}
} }

39
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/EntityPropertyChangeConsts.cs

@ -1,25 +1,24 @@
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
public class EntityPropertyChangeConsts
{ {
public class EntityPropertyChangeConsts /// <summary>
{ /// Default value: 512
/// <summary> /// </summary>
/// Default value: 512 public static int MaxNewValueLength { get; set; } = 512;
/// </summary>
public static int MaxNewValueLength { get; set; } = 512;
/// <summary> /// <summary>
/// Default value: 512 /// Default value: 512
/// </summary> /// </summary>
public static int MaxOriginalValueLength { get; set; } = 512; public static int MaxOriginalValueLength { get; set; } = 512;
/// <summary> /// <summary>
/// Default value: 128 /// Default value: 128
/// </summary> /// </summary>
public static int MaxPropertyNameLength { get; set; } = 128; public static int MaxPropertyNameLength { get; set; } = 128;
/// <summary> /// <summary>
/// Default value: 64 /// Default value: 64
/// </summary> /// </summary>
public static int MaxPropertyTypeFullNameLength { get; set; } = 64; public static int MaxPropertyTypeFullNameLength { get; set; } = 64;
}
} }

9
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/AuditLoggingResource.cs

@ -1,9 +1,8 @@
using Volo.Abp.Localization; using Volo.Abp.Localization;
namespace Volo.Abp.AuditLogging.Localization namespace Volo.Abp.AuditLogging.Localization;
[LocalizationResourceName("AbpAuditLogging")]
public class AuditLoggingResource
{ {
[LocalizationResourceName("AbpAuditLogging")]
public class AuditLoggingResource
{
}
} }

51
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/ObjectExtending/AuditLoggingModuleExtensionConfiguration.cs

@ -1,35 +1,34 @@
using System; using System;
using Volo.Abp.ObjectExtending.Modularity; using Volo.Abp.ObjectExtending.Modularity;
namespace Volo.Abp.ObjectExtending namespace Volo.Abp.ObjectExtending;
public class AuditLoggingModuleExtensionConfiguration : ModuleExtensionConfiguration
{ {
public class AuditLoggingModuleExtensionConfiguration : ModuleExtensionConfiguration public AuditLoggingModuleExtensionConfiguration ConfigureAuditLog(
Action<EntityExtensionConfiguration> configureAction)
{ {
public AuditLoggingModuleExtensionConfiguration ConfigureAuditLog( return this.ConfigureEntity(
Action<EntityExtensionConfiguration> configureAction) AuditLoggingModuleExtensionConsts.EntityNames.AuditLog,
{ configureAction
return this.ConfigureEntity( );
AuditLoggingModuleExtensionConsts.EntityNames.AuditLog, }
configureAction
);
}
public AuditLoggingModuleExtensionConfiguration ConfigureAuditLogAction( public AuditLoggingModuleExtensionConfiguration ConfigureAuditLogAction(
Action<EntityExtensionConfiguration> configureAction) Action<EntityExtensionConfiguration> configureAction)
{ {
return this.ConfigureEntity( return this.ConfigureEntity(
AuditLoggingModuleExtensionConsts.EntityNames.AuditLogAction, AuditLoggingModuleExtensionConsts.EntityNames.AuditLogAction,
configureAction configureAction
); );
} }
public AuditLoggingModuleExtensionConfiguration ConfigureEntityChange( public AuditLoggingModuleExtensionConfiguration ConfigureEntityChange(
Action<EntityExtensionConfiguration> configureAction) Action<EntityExtensionConfiguration> configureAction)
{ {
return this.ConfigureEntity( return this.ConfigureEntity(
AuditLoggingModuleExtensionConsts.EntityNames.EntityChange, AuditLoggingModuleExtensionConsts.EntityNames.EntityChange,
configureAction configureAction
); );
}
} }
} }

23
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/ObjectExtending/AuditLoggingModuleExtensionConfigurationDictionaryExtensions.cs

@ -1,18 +1,17 @@
using System; using System;
using Volo.Abp.ObjectExtending.Modularity; using Volo.Abp.ObjectExtending.Modularity;
namespace Volo.Abp.ObjectExtending namespace Volo.Abp.ObjectExtending;
public static class AuditLoggingModuleExtensionConfigurationDictionaryExtensions
{ {
public static class AuditLoggingModuleExtensionConfigurationDictionaryExtensions public static ModuleExtensionConfigurationDictionary ConfigureAuditLogging(
this ModuleExtensionConfigurationDictionary modules,
Action<AuditLoggingModuleExtensionConfiguration> configureAction)
{ {
public static ModuleExtensionConfigurationDictionary ConfigureAuditLogging( return modules.ConfigureModule(
this ModuleExtensionConfigurationDictionary modules, AuditLoggingModuleExtensionConsts.ModuleName,
Action<AuditLoggingModuleExtensionConfiguration> configureAction) configureAction
{ );
return modules.ConfigureModule(
AuditLoggingModuleExtensionConsts.ModuleName,
configureAction
);
}
} }
} }

23
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/ObjectExtending/AuditLoggingModuleExtensionConsts.cs

@ -1,16 +1,15 @@
namespace Volo.Abp.ObjectExtending namespace Volo.Abp.ObjectExtending;
public static class AuditLoggingModuleExtensionConsts
{ {
public static class AuditLoggingModuleExtensionConsts public const string ModuleName = "AuditLogging";
public static class EntityNames
{ {
public const string ModuleName = "AuditLogging"; public const string AuditLog = "AuditLog";
public const string AuditLogAction = "AuditLogAction";
public static class EntityNames public const string EntityChange = "EntityChange";
{
public const string AuditLog = "AuditLog";
public const string AuditLogAction = "AuditLogAction";
public const string EntityChange = "EntityChange";
}
} }
} }

13
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/AbpAuditLoggingDbProperties.cs

@ -1,13 +1,12 @@
using Volo.Abp.Data; using Volo.Abp.Data;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
public static class AbpAuditLoggingDbProperties
{ {
public static class AbpAuditLoggingDbProperties public static string DbTablePrefix { get; set; } = AbpCommonDbProperties.DbTablePrefix;
{
public static string DbTablePrefix { get; set; } = AbpCommonDbProperties.DbTablePrefix;
public static string DbSchema { get; set; } = AbpCommonDbProperties.DbSchema; public static string DbSchema { get; set; } = AbpCommonDbProperties.DbSchema;
public const string ConnectionStringName = "AbpAuditLogging"; public const string ConnectionStringName = "AbpAuditLogging";
}
} }

57
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/AbpAuditLoggingDomainModule.cs

@ -7,39 +7,38 @@ using Volo.Abp.ObjectExtending;
using Volo.Abp.ObjectExtending.Modularity; using Volo.Abp.ObjectExtending.Modularity;
using Volo.Abp.Threading; using Volo.Abp.Threading;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
[DependsOn(typeof(AbpAuditingModule))]
[DependsOn(typeof(AbpDddDomainModule))]
[DependsOn(typeof(AbpAuditLoggingDomainSharedModule))]
[DependsOn(typeof(AbpExceptionHandlingModule))]
[DependsOn(typeof(AbpJsonModule))]
public class AbpAuditLoggingDomainModule : AbpModule
{ {
[DependsOn(typeof(AbpAuditingModule))] private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
[DependsOn(typeof(AbpDddDomainModule))]
[DependsOn(typeof(AbpAuditLoggingDomainSharedModule))]
[DependsOn(typeof(AbpExceptionHandlingModule))]
[DependsOn(typeof(AbpJsonModule))]
public class AbpAuditLoggingDomainModule : AbpModule
{
private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
public override void PostConfigureServices(ServiceConfigurationContext context) public override void PostConfigureServices(ServiceConfigurationContext context)
{
OneTimeRunner.Run(() =>
{ {
OneTimeRunner.Run(() => ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity(
{ AuditLoggingModuleExtensionConsts.ModuleName,
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity( AuditLoggingModuleExtensionConsts.EntityNames.AuditLog,
AuditLoggingModuleExtensionConsts.ModuleName, typeof(AuditLog)
AuditLoggingModuleExtensionConsts.EntityNames.AuditLog, );
typeof(AuditLog)
);
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity( ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity(
AuditLoggingModuleExtensionConsts.ModuleName, AuditLoggingModuleExtensionConsts.ModuleName,
AuditLoggingModuleExtensionConsts.EntityNames.AuditLogAction, AuditLoggingModuleExtensionConsts.EntityNames.AuditLogAction,
typeof(AuditLogAction) typeof(AuditLogAction)
); );
ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity( ModuleExtensionConfigurationHelper.ApplyEntityConfigurationToEntity(
AuditLoggingModuleExtensionConsts.ModuleName, AuditLoggingModuleExtensionConsts.ModuleName,
AuditLoggingModuleExtensionConsts.EntityNames.EntityChange, AuditLoggingModuleExtensionConsts.EntityNames.EntityChange,
typeof(EntityChange) typeof(EntityChange)
); );
}); });
}
} }
} }

155
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/AuditLog.cs

@ -7,107 +7,106 @@ using Volo.Abp.Domain.Entities;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
{
[DisableAuditing]
public class AuditLog : AggregateRoot<Guid>, IMultiTenant
{
public virtual string ApplicationName { get; set; }
public virtual Guid? UserId { get; protected set; } [DisableAuditing]
public class AuditLog : AggregateRoot<Guid>, IMultiTenant
{
public virtual string ApplicationName { get; set; }
public virtual string UserName { get; protected set; } public virtual Guid? UserId { get; protected set; }
public virtual Guid? TenantId { get; protected set; } public virtual string UserName { get; protected set; }
public virtual string TenantName { get; protected set; } public virtual Guid? TenantId { get; protected set; }
public virtual Guid? ImpersonatorUserId { get; protected set; } public virtual string TenantName { get; protected set; }
public virtual Guid? ImpersonatorTenantId { get; protected set; } public virtual Guid? ImpersonatorUserId { get; protected set; }
public virtual DateTime ExecutionTime { get; protected set; } public virtual Guid? ImpersonatorTenantId { get; protected set; }
public virtual int ExecutionDuration { get; protected set; } public virtual DateTime ExecutionTime { get; protected set; }
public virtual string ClientIpAddress { get; protected set; } public virtual int ExecutionDuration { get; protected set; }
public virtual string ClientName { get; protected set; } public virtual string ClientIpAddress { get; protected set; }
public virtual string ClientId { get; set; } public virtual string ClientName { get; protected set; }
public virtual string CorrelationId { get; set; } public virtual string ClientId { get; set; }
public virtual string BrowserInfo { get; protected set; } public virtual string CorrelationId { get; set; }
public virtual string HttpMethod { get; protected set; } public virtual string BrowserInfo { get; protected set; }
public virtual string Url { get; protected set; } public virtual string HttpMethod { get; protected set; }
public virtual string Exceptions { get; protected set; } public virtual string Url { get; protected set; }
public virtual string Comments { get; protected set; } public virtual string Exceptions { get; protected set; }
public virtual int? HttpStatusCode { get; set; } public virtual string Comments { get; protected set; }
public virtual ICollection<EntityChange> EntityChanges { get; protected set; } public virtual int? HttpStatusCode { get; set; }
public virtual ICollection<AuditLogAction> Actions { get; protected set; } public virtual ICollection<EntityChange> EntityChanges { get; protected set; }
protected AuditLog() public virtual ICollection<AuditLogAction> Actions { get; protected set; }
{
} protected AuditLog()
{
public AuditLog( }
Guid id,
string applicationName,
Guid? tenantId,
string tenantName,
Guid? userId,
string userName,
DateTime executionTime,
int executionDuration,
string clientIpAddress,
string clientName,
string clientId,
string correlationId,
string browserInfo,
string httpMethod,
string url,
int? httpStatusCode,
Guid? impersonatorUserId,
Guid? impersonatorTenantId,
ExtraPropertyDictionary extraPropertyDictionary,
List<EntityChange> entityChanges,
List<AuditLogAction> actions,
string exceptions,
string comments)
: base(id)
{
ApplicationName = applicationName.Truncate(AuditLogConsts.MaxApplicationNameLength);
TenantId = tenantId;
TenantName = tenantName.Truncate(AuditLogConsts.MaxTenantNameLength);
UserId = userId;
UserName = userName.Truncate(AuditLogConsts.MaxUserNameLength);
ExecutionTime = executionTime;
ExecutionDuration = executionDuration;
ClientIpAddress = clientIpAddress.Truncate(AuditLogConsts.MaxClientIpAddressLength);
ClientName = clientName.Truncate(AuditLogConsts.MaxClientNameLength);
ClientId = clientId.Truncate(AuditLogConsts.MaxClientIdLength);
CorrelationId = correlationId.Truncate(AuditLogConsts.MaxCorrelationIdLength);
BrowserInfo = browserInfo.Truncate(AuditLogConsts.MaxBrowserInfoLength);
HttpMethod = httpMethod.Truncate(AuditLogConsts.MaxHttpMethodLength);
Url = url.Truncate(AuditLogConsts.MaxUrlLength);
HttpStatusCode = httpStatusCode;
ImpersonatorUserId = impersonatorUserId;
ImpersonatorTenantId = impersonatorTenantId;
ExtraProperties = extraPropertyDictionary; public AuditLog(
EntityChanges = entityChanges; Guid id,
Actions = actions; string applicationName,
Exceptions = exceptions; Guid? tenantId,
Comments = comments.Truncate(AuditLogConsts.MaxCommentsLength); string tenantName,
} Guid? userId,
string userName,
DateTime executionTime,
int executionDuration,
string clientIpAddress,
string clientName,
string clientId,
string correlationId,
string browserInfo,
string httpMethod,
string url,
int? httpStatusCode,
Guid? impersonatorUserId,
Guid? impersonatorTenantId,
ExtraPropertyDictionary extraPropertyDictionary,
List<EntityChange> entityChanges,
List<AuditLogAction> actions,
string exceptions,
string comments)
: base(id)
{
ApplicationName = applicationName.Truncate(AuditLogConsts.MaxApplicationNameLength);
TenantId = tenantId;
TenantName = tenantName.Truncate(AuditLogConsts.MaxTenantNameLength);
UserId = userId;
UserName = userName.Truncate(AuditLogConsts.MaxUserNameLength);
ExecutionTime = executionTime;
ExecutionDuration = executionDuration;
ClientIpAddress = clientIpAddress.Truncate(AuditLogConsts.MaxClientIpAddressLength);
ClientName = clientName.Truncate(AuditLogConsts.MaxClientNameLength);
ClientId = clientId.Truncate(AuditLogConsts.MaxClientIdLength);
CorrelationId = correlationId.Truncate(AuditLogConsts.MaxCorrelationIdLength);
BrowserInfo = browserInfo.Truncate(AuditLogConsts.MaxBrowserInfoLength);
HttpMethod = httpMethod.Truncate(AuditLogConsts.MaxHttpMethodLength);
Url = url.Truncate(AuditLogConsts.MaxUrlLength);
HttpStatusCode = httpStatusCode;
ImpersonatorUserId = impersonatorUserId;
ImpersonatorTenantId = impersonatorTenantId;
ExtraProperties = extraPropertyDictionary;
EntityChanges = entityChanges;
Actions = actions;
Exceptions = exceptions;
Comments = comments.Truncate(AuditLogConsts.MaxCommentsLength);
} }
} }

53
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/AuditLogAction.cs

@ -4,43 +4,42 @@ using Volo.Abp.Data;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
[DisableAuditing]
public class AuditLogAction : Entity<Guid>, IMultiTenant, IHasExtraProperties
{ {
[DisableAuditing] public virtual Guid? TenantId { get; protected set; }
public class AuditLogAction : Entity<Guid>, IMultiTenant, IHasExtraProperties
{
public virtual Guid? TenantId { get; protected set; }
public virtual Guid AuditLogId { get; protected set; } public virtual Guid AuditLogId { get; protected set; }
public virtual string ServiceName { get; protected set; } public virtual string ServiceName { get; protected set; }
public virtual string MethodName { get; protected set; } public virtual string MethodName { get; protected set; }
public virtual string Parameters { get; protected set; } public virtual string Parameters { get; protected set; }
public virtual DateTime ExecutionTime { get; protected set; } public virtual DateTime ExecutionTime { get; protected set; }
public virtual int ExecutionDuration { get; protected set; } public virtual int ExecutionDuration { get; protected set; }
public virtual ExtraPropertyDictionary ExtraProperties { get; protected set; } public virtual ExtraPropertyDictionary ExtraProperties { get; protected set; }
protected AuditLogAction() protected AuditLogAction()
{ {
} }
public AuditLogAction(Guid id, Guid auditLogId, AuditLogActionInfo actionInfo, Guid? tenantId = null) public AuditLogAction(Guid id, Guid auditLogId, AuditLogActionInfo actionInfo, Guid? tenantId = null)
{ {
Id = id; Id = id;
TenantId = tenantId; TenantId = tenantId;
AuditLogId = auditLogId; AuditLogId = auditLogId;
ExecutionTime = actionInfo.ExecutionTime; ExecutionTime = actionInfo.ExecutionTime;
ExecutionDuration = actionInfo.ExecutionDuration; ExecutionDuration = actionInfo.ExecutionDuration;
ExtraProperties = new ExtraPropertyDictionary(actionInfo.ExtraProperties); ExtraProperties = new ExtraPropertyDictionary(actionInfo.ExtraProperties);
ServiceName = actionInfo.ServiceName.TruncateFromBeginning(AuditLogActionConsts.MaxServiceNameLength); ServiceName = actionInfo.ServiceName.TruncateFromBeginning(AuditLogActionConsts.MaxServiceNameLength);
MethodName = actionInfo.MethodName.TruncateFromBeginning(AuditLogActionConsts.MaxMethodNameLength); MethodName = actionInfo.MethodName.TruncateFromBeginning(AuditLogActionConsts.MaxMethodNameLength);
Parameters = actionInfo.Parameters.Length > AuditLogActionConsts.MaxParametersLength ? "" : actionInfo.Parameters; Parameters = actionInfo.Parameters.Length > AuditLogActionConsts.MaxParametersLength ? "" : actionInfo.Parameters;
}
} }
} }

129
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/AuditLogInfoToAuditLogConverter.cs

@ -10,84 +10,83 @@ using Volo.Abp.Guids;
using Volo.Abp.Http; using Volo.Abp.Http;
using Volo.Abp.Json; using Volo.Abp.Json;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
public class AuditLogInfoToAuditLogConverter : IAuditLogInfoToAuditLogConverter, ITransientDependency
{ {
public class AuditLogInfoToAuditLogConverter : IAuditLogInfoToAuditLogConverter, ITransientDependency protected IGuidGenerator GuidGenerator { get; }
protected IExceptionToErrorInfoConverter ExceptionToErrorInfoConverter { get; }
protected IJsonSerializer JsonSerializer { get; }
public AuditLogInfoToAuditLogConverter(IGuidGenerator guidGenerator, IExceptionToErrorInfoConverter exceptionToErrorInfoConverter, IJsonSerializer jsonSerializer)
{ {
protected IGuidGenerator GuidGenerator { get; } GuidGenerator = guidGenerator;
protected IExceptionToErrorInfoConverter ExceptionToErrorInfoConverter { get; } ExceptionToErrorInfoConverter = exceptionToErrorInfoConverter;
protected IJsonSerializer JsonSerializer { get; } JsonSerializer = jsonSerializer;
}
public AuditLogInfoToAuditLogConverter(IGuidGenerator guidGenerator, IExceptionToErrorInfoConverter exceptionToErrorInfoConverter, IJsonSerializer jsonSerializer) public virtual Task<AuditLog> ConvertAsync(AuditLogInfo auditLogInfo)
{ {
GuidGenerator = guidGenerator; var auditLogId = GuidGenerator.Create();
ExceptionToErrorInfoConverter = exceptionToErrorInfoConverter;
JsonSerializer = jsonSerializer;
}
public virtual Task<AuditLog> ConvertAsync(AuditLogInfo auditLogInfo) var extraProperties = new ExtraPropertyDictionary();
if (auditLogInfo.ExtraProperties != null)
{ {
var auditLogId = GuidGenerator.Create(); foreach (var pair in auditLogInfo.ExtraProperties)
var extraProperties = new ExtraPropertyDictionary();
if (auditLogInfo.ExtraProperties != null)
{ {
foreach (var pair in auditLogInfo.ExtraProperties) extraProperties.Add(pair.Key, pair.Value);
{
extraProperties.Add(pair.Key, pair.Value);
}
} }
}
var entityChanges = auditLogInfo var entityChanges = auditLogInfo
.EntityChanges? .EntityChanges?
.Select(entityChangeInfo => new EntityChange(GuidGenerator, auditLogId, entityChangeInfo, tenantId: auditLogInfo.TenantId)) .Select(entityChangeInfo => new EntityChange(GuidGenerator, auditLogId, entityChangeInfo, tenantId: auditLogInfo.TenantId))
.ToList() .ToList()
?? new List<EntityChange>(); ?? new List<EntityChange>();
var actions = auditLogInfo var actions = auditLogInfo
.Actions? .Actions?
.Select(auditLogActionInfo => new AuditLogAction(GuidGenerator.Create(), auditLogId, auditLogActionInfo, tenantId: auditLogInfo.TenantId)) .Select(auditLogActionInfo => new AuditLogAction(GuidGenerator.Create(), auditLogId, auditLogActionInfo, tenantId: auditLogInfo.TenantId))
.ToList() .ToList()
?? new List<AuditLogAction>(); ?? new List<AuditLogAction>();
var remoteServiceErrorInfos = auditLogInfo.Exceptions?.Select(exception => ExceptionToErrorInfoConverter.Convert(exception, true)) var remoteServiceErrorInfos = auditLogInfo.Exceptions?.Select(exception => ExceptionToErrorInfoConverter.Convert(exception, true))
?? new List<RemoteServiceErrorInfo>(); ?? new List<RemoteServiceErrorInfo>();
var exceptions = remoteServiceErrorInfos.Any() var exceptions = remoteServiceErrorInfos.Any()
? JsonSerializer.Serialize(remoteServiceErrorInfos, indented: true) ? JsonSerializer.Serialize(remoteServiceErrorInfos, indented: true)
: null; : null;
var comments = auditLogInfo var comments = auditLogInfo
.Comments? .Comments?
.JoinAsString(Environment.NewLine); .JoinAsString(Environment.NewLine);
var auditLog = new AuditLog( var auditLog = new AuditLog(
auditLogId, auditLogId,
auditLogInfo.ApplicationName, auditLogInfo.ApplicationName,
auditLogInfo.TenantId, auditLogInfo.TenantId,
auditLogInfo.TenantName, auditLogInfo.TenantName,
auditLogInfo.UserId, auditLogInfo.UserId,
auditLogInfo.UserName, auditLogInfo.UserName,
auditLogInfo.ExecutionTime, auditLogInfo.ExecutionTime,
auditLogInfo.ExecutionDuration, auditLogInfo.ExecutionDuration,
auditLogInfo.ClientIpAddress, auditLogInfo.ClientIpAddress,
auditLogInfo.ClientName, auditLogInfo.ClientName,
auditLogInfo.ClientId, auditLogInfo.ClientId,
auditLogInfo.CorrelationId, auditLogInfo.CorrelationId,
auditLogInfo.BrowserInfo, auditLogInfo.BrowserInfo,
auditLogInfo.HttpMethod, auditLogInfo.HttpMethod,
auditLogInfo.Url, auditLogInfo.Url,
auditLogInfo.HttpStatusCode, auditLogInfo.HttpStatusCode,
auditLogInfo.ImpersonatorUserId, auditLogInfo.ImpersonatorUserId,
auditLogInfo.ImpersonatorTenantId, auditLogInfo.ImpersonatorTenantId,
extraProperties, extraProperties,
entityChanges, entityChanges,
actions, actions,
exceptions, exceptions,
comments comments
); );
return Task.FromResult(auditLog); return Task.FromResult(auditLog);
}
} }
} }

79
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/AuditingStore.cs

@ -7,55 +7,54 @@ using Volo.Abp.Auditing;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Uow; using Volo.Abp.Uow;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
public class AuditingStore : IAuditingStore, ITransientDependency
{ {
public class AuditingStore : IAuditingStore, ITransientDependency public ILogger<AuditingStore> Logger { get; set; }
protected IAuditLogRepository AuditLogRepository { get; }
protected IUnitOfWorkManager UnitOfWorkManager { get; }
protected AbpAuditingOptions Options { get; }
protected IAuditLogInfoToAuditLogConverter Converter { get; }
public AuditingStore(
IAuditLogRepository auditLogRepository,
IUnitOfWorkManager unitOfWorkManager,
IOptions<AbpAuditingOptions> options,
IAuditLogInfoToAuditLogConverter converter)
{ {
public ILogger<AuditingStore> Logger { get; set; } AuditLogRepository = auditLogRepository;
protected IAuditLogRepository AuditLogRepository { get; } UnitOfWorkManager = unitOfWorkManager;
protected IUnitOfWorkManager UnitOfWorkManager { get; } Converter = converter;
protected AbpAuditingOptions Options { get; } Options = options.Value;
protected IAuditLogInfoToAuditLogConverter Converter { get; }
public AuditingStore(
IAuditLogRepository auditLogRepository,
IUnitOfWorkManager unitOfWorkManager,
IOptions<AbpAuditingOptions> options,
IAuditLogInfoToAuditLogConverter converter)
{
AuditLogRepository = auditLogRepository;
UnitOfWorkManager = unitOfWorkManager;
Converter = converter;
Options = options.Value;
Logger = NullLogger<AuditingStore>.Instance; Logger = NullLogger<AuditingStore>.Instance;
} }
public virtual async Task SaveAsync(AuditLogInfo auditInfo) public virtual async Task SaveAsync(AuditLogInfo auditInfo)
{
if (!Options.HideErrors)
{ {
if (!Options.HideErrors) await SaveLogAsync(auditInfo);
{ return;
await SaveLogAsync(auditInfo); }
return;
}
try try
{ {
await SaveLogAsync(auditInfo); await SaveLogAsync(auditInfo);
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.LogWarning("Could not save the audit log object: " + Environment.NewLine + auditInfo.ToString()); Logger.LogWarning("Could not save the audit log object: " + Environment.NewLine + auditInfo.ToString());
Logger.LogException(ex, LogLevel.Error); Logger.LogException(ex, LogLevel.Error);
}
} }
}
protected virtual async Task SaveLogAsync(AuditLogInfo auditInfo) protected virtual async Task SaveLogAsync(AuditLogInfo auditInfo)
{
using (var uow = UnitOfWorkManager.Begin(true))
{ {
using (var uow = UnitOfWorkManager.Begin(true)) await AuditLogRepository.InsertAsync(await Converter.ConvertAsync(auditInfo));
{ await uow.CompleteAsync();
await AuditLogRepository.InsertAsync(await Converter.ConvertAsync(auditInfo));
await uow.CompleteAsync();
}
} }
} }
} }

81
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/EntityChange.cs

@ -7,61 +7,60 @@ using Volo.Abp.Domain.Entities;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
[DisableAuditing]
public class EntityChange : Entity<Guid>, IMultiTenant, IHasExtraProperties
{ {
[DisableAuditing] public virtual Guid AuditLogId { get; protected set; }
public class EntityChange : Entity<Guid>, IMultiTenant, IHasExtraProperties
{
public virtual Guid AuditLogId { get; protected set; }
public virtual Guid? TenantId { get; protected set; } public virtual Guid? TenantId { get; protected set; }
public virtual DateTime ChangeTime { get; protected set; } public virtual DateTime ChangeTime { get; protected set; }
public virtual EntityChangeType ChangeType { get; protected set; } public virtual EntityChangeType ChangeType { get; protected set; }
public virtual Guid? EntityTenantId { get; protected set; } public virtual Guid? EntityTenantId { get; protected set; }
public virtual string EntityId { get; protected set; } public virtual string EntityId { get; protected set; }
public virtual string EntityTypeFullName { get; protected set; } public virtual string EntityTypeFullName { get; protected set; }
public virtual ICollection<EntityPropertyChange> PropertyChanges { get; protected set; } public virtual ICollection<EntityPropertyChange> PropertyChanges { get; protected set; }
public virtual ExtraPropertyDictionary ExtraProperties { get; protected set; } public virtual ExtraPropertyDictionary ExtraProperties { get; protected set; }
protected EntityChange() protected EntityChange()
{ {
ExtraProperties = new ExtraPropertyDictionary(); ExtraProperties = new ExtraPropertyDictionary();
} }
public EntityChange( public EntityChange(
IGuidGenerator guidGenerator, IGuidGenerator guidGenerator,
Guid auditLogId, Guid auditLogId,
EntityChangeInfo entityChangeInfo, EntityChangeInfo entityChangeInfo,
Guid? tenantId = null) Guid? tenantId = null)
{ {
Id = guidGenerator.Create(); Id = guidGenerator.Create();
AuditLogId = auditLogId; AuditLogId = auditLogId;
TenantId = tenantId; TenantId = tenantId;
ChangeTime = entityChangeInfo.ChangeTime; ChangeTime = entityChangeInfo.ChangeTime;
ChangeType = entityChangeInfo.ChangeType; ChangeType = entityChangeInfo.ChangeType;
EntityId = entityChangeInfo.EntityId.Truncate(EntityChangeConsts.MaxEntityTypeFullNameLength); EntityId = entityChangeInfo.EntityId.Truncate(EntityChangeConsts.MaxEntityTypeFullNameLength);
EntityTypeFullName = entityChangeInfo.EntityTypeFullName.TruncateFromBeginning(EntityChangeConsts.MaxEntityTypeFullNameLength); EntityTypeFullName = entityChangeInfo.EntityTypeFullName.TruncateFromBeginning(EntityChangeConsts.MaxEntityTypeFullNameLength);
PropertyChanges = entityChangeInfo PropertyChanges = entityChangeInfo
.PropertyChanges? .PropertyChanges?
.Select(p => new EntityPropertyChange(guidGenerator, Id, p, tenantId)) .Select(p => new EntityPropertyChange(guidGenerator, Id, p, tenantId))
.ToList() .ToList()
?? new List<EntityPropertyChange>(); ?? new List<EntityPropertyChange>();
ExtraProperties = new ExtraPropertyDictionary(); ExtraProperties = new ExtraPropertyDictionary();
if (entityChangeInfo.ExtraProperties != null) if (entityChangeInfo.ExtraProperties != null)
{
foreach (var pair in entityChangeInfo.ExtraProperties)
{ {
foreach (var pair in entityChangeInfo.ExtraProperties) ExtraProperties.Add(pair.Key, pair.Value);
{
ExtraProperties.Add(pair.Key, pair.Value);
}
} }
} }
} }

15
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/EntityChangeWithUsername.cs

@ -1,9 +1,8 @@
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
public class EntityChangeWithUsername
{ {
public class EntityChangeWithUsername public EntityChange EntityChange { get; set; }
{
public EntityChange EntityChange { get; set; } public string UserName { get; set; }
}
public string UserName { get; set; }
}
}

55
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/EntityPropertyChange.cs

@ -4,41 +4,40 @@ using Volo.Abp.Domain.Entities;
using Volo.Abp.Guids; using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
[DisableAuditing]
public class EntityPropertyChange : Entity<Guid>, IMultiTenant
{ {
[DisableAuditing] public virtual Guid? TenantId { get; protected set; }
public class EntityPropertyChange : Entity<Guid>, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
public virtual Guid EntityChangeId { get; protected set; } public virtual Guid EntityChangeId { get; protected set; }
public virtual string NewValue { get; protected set; } public virtual string NewValue { get; protected set; }
public virtual string OriginalValue { get; protected set; } public virtual string OriginalValue { get; protected set; }
public virtual string PropertyName { get; protected set; } public virtual string PropertyName { get; protected set; }
public virtual string PropertyTypeFullName { get; protected set; } public virtual string PropertyTypeFullName { get; protected set; }
protected EntityPropertyChange() protected EntityPropertyChange()
{ {
} }
public EntityPropertyChange( public EntityPropertyChange(
IGuidGenerator guidGenerator, IGuidGenerator guidGenerator,
Guid entityChangeId, Guid entityChangeId,
EntityPropertyChangeInfo entityChangeInfo, EntityPropertyChangeInfo entityChangeInfo,
Guid? tenantId = null) Guid? tenantId = null)
{ {
Id = guidGenerator.Create(); Id = guidGenerator.Create();
TenantId = tenantId; TenantId = tenantId;
EntityChangeId = entityChangeId; EntityChangeId = entityChangeId;
NewValue = entityChangeInfo.NewValue.Truncate(EntityPropertyChangeConsts.MaxNewValueLength); NewValue = entityChangeInfo.NewValue.Truncate(EntityPropertyChangeConsts.MaxNewValueLength);
OriginalValue = entityChangeInfo.OriginalValue.Truncate(EntityPropertyChangeConsts.MaxOriginalValueLength); OriginalValue = entityChangeInfo.OriginalValue.Truncate(EntityPropertyChangeConsts.MaxOriginalValueLength);
PropertyName = entityChangeInfo.PropertyName.TruncateFromBeginning(EntityPropertyChangeConsts.MaxPropertyNameLength); PropertyName = entityChangeInfo.PropertyName.TruncateFromBeginning(EntityPropertyChangeConsts.MaxPropertyNameLength);
PropertyTypeFullName = entityChangeInfo.PropertyTypeFullName.TruncateFromBeginning(EntityPropertyChangeConsts.MaxPropertyTypeFullNameLength); PropertyTypeFullName = entityChangeInfo.PropertyTypeFullName.TruncateFromBeginning(EntityPropertyChangeConsts.MaxPropertyTypeFullNameLength);
}
} }
} }

9
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/IAuditLogInfoToAuditLogConverter.cs

@ -1,10 +1,9 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.Auditing; using Volo.Abp.Auditing;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
public interface IAuditLogInfoToAuditLogConverter
{ {
public interface IAuditLogInfoToAuditLogConverter Task<AuditLog> ConvertAsync(AuditLogInfo auditLogInfo);
{
Task<AuditLog> ConvertAsync(AuditLogInfo auditLogInfo);
}
} }

129
modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/IAuditLogRepository.cs

@ -6,77 +6,76 @@ using System.Threading.Tasks;
using Volo.Abp.Auditing; using Volo.Abp.Auditing;
using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Repositories;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
public interface IAuditLogRepository : IRepository<AuditLog, Guid>
{ {
public interface IAuditLogRepository : IRepository<AuditLog, Guid> Task<List<AuditLog>> GetListAsync(
{ string sorting = null,
Task<List<AuditLog>> GetListAsync( int maxResultCount = 50,
string sorting = null, int skipCount = 0,
int maxResultCount = 50, DateTime? startTime = null,
int skipCount = 0, DateTime? endTime = null,
DateTime? startTime = null, string httpMethod = null,
DateTime? endTime = null, string url = null,
string httpMethod = null, Guid? userId = null,
string url = null, string userName = null,
Guid? userId = null, string applicationName = null,
string userName = null, string clientIpAddress = null,
string applicationName = null, string correlationId = null,
string clientIpAddress = null, int? maxExecutionDuration = null,
string correlationId = null, int? minExecutionDuration = null,
int? maxExecutionDuration = null, bool? hasException = null,
int? minExecutionDuration = null, HttpStatusCode? httpStatusCode = null,
bool? hasException = null, bool includeDetails = false,
HttpStatusCode? httpStatusCode = null, CancellationToken cancellationToken = default);
bool includeDetails = false,
CancellationToken cancellationToken = default);
Task<long> GetCountAsync( Task<long> GetCountAsync(
DateTime? startTime = null, DateTime? startTime = null,
DateTime? endTime = null, DateTime? endTime = null,
string httpMethod = null, string httpMethod = null,
string url = null, string url = null,
Guid? userId = null, Guid? userId = null,
string userName = null, string userName = null,
string applicationName = null, string applicationName = null,
string clientIpAddress = null, string clientIpAddress = null,
string correlationId = null, string correlationId = null,
int? maxExecutionDuration = null, int? maxExecutionDuration = null,
int? minExecutionDuration = null, int? minExecutionDuration = null,
bool? hasException = null, bool? hasException = null,
HttpStatusCode? httpStatusCode = null, HttpStatusCode? httpStatusCode = null,
CancellationToken cancellationToken = default); CancellationToken cancellationToken = default);
Task<Dictionary<DateTime, double>> GetAverageExecutionDurationPerDayAsync( Task<Dictionary<DateTime, double>> GetAverageExecutionDurationPerDayAsync(
DateTime startDate, DateTime startDate,
DateTime endDate, DateTime endDate,
CancellationToken cancellationToken = default); CancellationToken cancellationToken = default);
Task<EntityChange> GetEntityChange(Guid entityChangeId, CancellationToken cancellationToken = default); Task<EntityChange> GetEntityChange(Guid entityChangeId, CancellationToken cancellationToken = default);
Task<List<EntityChange>> GetEntityChangeListAsync( Task<List<EntityChange>> GetEntityChangeListAsync(
string sorting = null, string sorting = null,
int maxResultCount = 50, int maxResultCount = 50,
int skipCount = 0, int skipCount = 0,
Guid? auditLogId = null, Guid? auditLogId = null,
DateTime? startTime = null, DateTime? startTime = null,
DateTime? endTime = null, DateTime? endTime = null,
EntityChangeType? changeType = null, EntityChangeType? changeType = null,
string entityId = null, string entityId = null,
string entityTypeFullName = null, string entityTypeFullName = null,
bool includeDetails = false, bool includeDetails = false,
CancellationToken cancellationToken = default); CancellationToken cancellationToken = default);
Task<long> GetEntityChangeCountAsync( Task<long> GetEntityChangeCountAsync(
Guid? auditLogId = null, Guid? auditLogId = null,
DateTime? startTime = null, DateTime? startTime = null,
DateTime? endTime = null, DateTime? endTime = null,
EntityChangeType? changeType = null, EntityChangeType? changeType = null,
string entityId = null, string entityId = null,
string entityTypeFullName = null, string entityTypeFullName = null,
CancellationToken cancellationToken = default); CancellationToken cancellationToken = default);
Task<EntityChangeWithUsername> GetEntityChangeWithUsernameAsync(Guid entityChangeId, CancellationToken cancellationToken = default); Task<EntityChangeWithUsername> GetEntityChangeWithUsernameAsync(Guid entityChangeId, CancellationToken cancellationToken = default);
Task<List<EntityChangeWithUsername>> GetEntityChangesWithUsernameAsync(string entityId, string entityTypeFullName, CancellationToken cancellationToken = default); Task<List<EntityChangeWithUsername>> GetEntityChangesWithUsernameAsync(string entityId, string entityTypeFullName, CancellationToken cancellationToken = default);
}
} }

43
modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/AbpAuditLoggingEfCoreQueryableExtensions.cs

@ -1,34 +1,33 @@
using System.Linq; using System.Linq;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
public static class AbpAuditLoggingEfCoreQueryableExtensions
{ {
public static class AbpAuditLoggingEfCoreQueryableExtensions public static IQueryable<AuditLog> IncludeDetails(
this IQueryable<AuditLog> queryable,
bool include = true)
{ {
public static IQueryable<AuditLog> IncludeDetails( if (!include)
this IQueryable<AuditLog> queryable,
bool include = true)
{ {
if (!include) return queryable;
{
return queryable;
}
return queryable
.Include(x => x.Actions)
.Include(x => x.EntityChanges).ThenInclude(ec=>ec.PropertyChanges);
} }
public static IQueryable<EntityChange> IncludeDetails( return queryable
this IQueryable<EntityChange> queryable, .Include(x => x.Actions)
bool include = true) .Include(x => x.EntityChanges).ThenInclude(ec => ec.PropertyChanges);
{ }
if (!include)
{
return queryable;
}
return queryable.Include(x => x.PropertyChanges); public static IQueryable<EntityChange> IncludeDetails(
this IQueryable<EntityChange> queryable,
bool include = true)
{
if (!include)
{
return queryable;
} }
return queryable.Include(x => x.PropertyChanges);
} }
} }

27
modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingDbContext.cs

@ -2,24 +2,23 @@
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
namespace Volo.Abp.AuditLogging.EntityFrameworkCore namespace Volo.Abp.AuditLogging.EntityFrameworkCore;
[ConnectionStringName(AbpAuditLoggingDbProperties.ConnectionStringName)]
public class AbpAuditLoggingDbContext : AbpDbContext<AbpAuditLoggingDbContext>, IAuditLoggingDbContext
{ {
[ConnectionStringName(AbpAuditLoggingDbProperties.ConnectionStringName)] public DbSet<AuditLog> AuditLogs { get; set; }
public class AbpAuditLoggingDbContext : AbpDbContext<AbpAuditLoggingDbContext>, IAuditLoggingDbContext
{
public DbSet<AuditLog> AuditLogs { get; set; }
public AbpAuditLoggingDbContext(DbContextOptions<AbpAuditLoggingDbContext> options) public AbpAuditLoggingDbContext(DbContextOptions<AbpAuditLoggingDbContext> options)
: base(options) : base(options)
{ {
} }
protected override void OnModelCreating(ModelBuilder builder) protected override void OnModelCreating(ModelBuilder builder)
{ {
base.OnModelCreating(builder); base.OnModelCreating(builder);
builder.ConfigureAuditLogging(); builder.ConfigureAuditLogging();
}
} }
} }

161
modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingDbContextModelBuilderExtensions.cs

@ -2,105 +2,104 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Modeling; using Volo.Abp.EntityFrameworkCore.Modeling;
namespace Volo.Abp.AuditLogging.EntityFrameworkCore namespace Volo.Abp.AuditLogging.EntityFrameworkCore;
public static class AbpAuditLoggingDbContextModelBuilderExtensions
{ {
public static class AbpAuditLoggingDbContextModelBuilderExtensions public static void ConfigureAuditLogging(
[NotNull] this ModelBuilder builder)
{ {
public static void ConfigureAuditLogging( Check.NotNull(builder, nameof(builder));
[NotNull] this ModelBuilder builder)
{
Check.NotNull(builder, nameof(builder));
builder.Entity<AuditLog>(b =>
{
b.ToTable(AbpAuditLoggingDbProperties.DbTablePrefix + "AuditLogs", AbpAuditLoggingDbProperties.DbSchema);
b.ConfigureByConvention();
b.Property(x => x.ApplicationName).HasMaxLength(AuditLogConsts.MaxApplicationNameLength).HasColumnName(nameof(AuditLog.ApplicationName));
b.Property(x => x.ClientIpAddress).HasMaxLength(AuditLogConsts.MaxClientIpAddressLength).HasColumnName(nameof(AuditLog.ClientIpAddress));
b.Property(x => x.ClientName).HasMaxLength(AuditLogConsts.MaxClientNameLength).HasColumnName(nameof(AuditLog.ClientName));
b.Property(x => x.ClientId).HasMaxLength(AuditLogConsts.MaxClientIdLength).HasColumnName(nameof(AuditLog.ClientId));
b.Property(x => x.CorrelationId).HasMaxLength(AuditLogConsts.MaxCorrelationIdLength).HasColumnName(nameof(AuditLog.CorrelationId));
b.Property(x => x.BrowserInfo).HasMaxLength(AuditLogConsts.MaxBrowserInfoLength).HasColumnName(nameof(AuditLog.BrowserInfo));
b.Property(x => x.HttpMethod).HasMaxLength(AuditLogConsts.MaxHttpMethodLength).HasColumnName(nameof(AuditLog.HttpMethod));
b.Property(x => x.Url).HasMaxLength(AuditLogConsts.MaxUrlLength).HasColumnName(nameof(AuditLog.Url));
b.Property(x => x.HttpStatusCode).HasColumnName(nameof(AuditLog.HttpStatusCode));
b.Property(x => x.Comments).HasMaxLength(AuditLogConsts.MaxCommentsLength).HasColumnName(nameof(AuditLog.Comments));
b.Property(x => x.ExecutionDuration).HasColumnName(nameof(AuditLog.ExecutionDuration));
b.Property(x => x.ImpersonatorTenantId).HasColumnName(nameof(AuditLog.ImpersonatorTenantId));
b.Property(x => x.ImpersonatorUserId).HasColumnName(nameof(AuditLog.ImpersonatorUserId));
b.Property(x => x.UserId).HasColumnName(nameof(AuditLog.UserId));
b.Property(x => x.UserName).HasMaxLength(AuditLogConsts.MaxUserNameLength).HasColumnName(nameof(AuditLog.UserName));
b.Property(x => x.TenantId).HasColumnName(nameof(AuditLog.TenantId));
b.HasMany(a => a.Actions).WithOne().HasForeignKey(x => x.AuditLogId).IsRequired();
b.HasMany(a => a.EntityChanges).WithOne().HasForeignKey(x => x.AuditLogId).IsRequired();
b.HasIndex(x => new { x.TenantId, x.ExecutionTime }); builder.Entity<AuditLog>(b =>
b.HasIndex(x => new { x.TenantId, x.UserId, x.ExecutionTime }); {
b.ToTable(AbpAuditLoggingDbProperties.DbTablePrefix + "AuditLogs", AbpAuditLoggingDbProperties.DbSchema);
b.ApplyObjectExtensionMappings();
}); b.ConfigureByConvention();
builder.Entity<AuditLogAction>(b => b.Property(x => x.ApplicationName).HasMaxLength(AuditLogConsts.MaxApplicationNameLength).HasColumnName(nameof(AuditLog.ApplicationName));
{ b.Property(x => x.ClientIpAddress).HasMaxLength(AuditLogConsts.MaxClientIpAddressLength).HasColumnName(nameof(AuditLog.ClientIpAddress));
b.ToTable(AbpAuditLoggingDbProperties.DbTablePrefix + "AuditLogActions", AbpAuditLoggingDbProperties.DbSchema); b.Property(x => x.ClientName).HasMaxLength(AuditLogConsts.MaxClientNameLength).HasColumnName(nameof(AuditLog.ClientName));
b.Property(x => x.ClientId).HasMaxLength(AuditLogConsts.MaxClientIdLength).HasColumnName(nameof(AuditLog.ClientId));
b.Property(x => x.CorrelationId).HasMaxLength(AuditLogConsts.MaxCorrelationIdLength).HasColumnName(nameof(AuditLog.CorrelationId));
b.Property(x => x.BrowserInfo).HasMaxLength(AuditLogConsts.MaxBrowserInfoLength).HasColumnName(nameof(AuditLog.BrowserInfo));
b.Property(x => x.HttpMethod).HasMaxLength(AuditLogConsts.MaxHttpMethodLength).HasColumnName(nameof(AuditLog.HttpMethod));
b.Property(x => x.Url).HasMaxLength(AuditLogConsts.MaxUrlLength).HasColumnName(nameof(AuditLog.Url));
b.Property(x => x.HttpStatusCode).HasColumnName(nameof(AuditLog.HttpStatusCode));
b.Property(x => x.Comments).HasMaxLength(AuditLogConsts.MaxCommentsLength).HasColumnName(nameof(AuditLog.Comments));
b.Property(x => x.ExecutionDuration).HasColumnName(nameof(AuditLog.ExecutionDuration));
b.Property(x => x.ImpersonatorTenantId).HasColumnName(nameof(AuditLog.ImpersonatorTenantId));
b.Property(x => x.ImpersonatorUserId).HasColumnName(nameof(AuditLog.ImpersonatorUserId));
b.Property(x => x.UserId).HasColumnName(nameof(AuditLog.UserId));
b.Property(x => x.UserName).HasMaxLength(AuditLogConsts.MaxUserNameLength).HasColumnName(nameof(AuditLog.UserName));
b.Property(x => x.TenantId).HasColumnName(nameof(AuditLog.TenantId));
b.HasMany(a => a.Actions).WithOne().HasForeignKey(x => x.AuditLogId).IsRequired();
b.HasMany(a => a.EntityChanges).WithOne().HasForeignKey(x => x.AuditLogId).IsRequired();
b.HasIndex(x => new { x.TenantId, x.ExecutionTime });
b.HasIndex(x => new { x.TenantId, x.UserId, x.ExecutionTime });
b.ApplyObjectExtensionMappings();
});
builder.Entity<AuditLogAction>(b =>
{
b.ToTable(AbpAuditLoggingDbProperties.DbTablePrefix + "AuditLogActions", AbpAuditLoggingDbProperties.DbSchema);
b.ConfigureByConvention(); b.ConfigureByConvention();
b.Property(x => x.AuditLogId).HasColumnName(nameof(AuditLogAction.AuditLogId)); b.Property(x => x.AuditLogId).HasColumnName(nameof(AuditLogAction.AuditLogId));
b.Property(x => x.ServiceName).HasMaxLength(AuditLogActionConsts.MaxServiceNameLength).HasColumnName(nameof(AuditLogAction.ServiceName)); b.Property(x => x.ServiceName).HasMaxLength(AuditLogActionConsts.MaxServiceNameLength).HasColumnName(nameof(AuditLogAction.ServiceName));
b.Property(x => x.MethodName).HasMaxLength(AuditLogActionConsts.MaxMethodNameLength).HasColumnName(nameof(AuditLogAction.MethodName)); b.Property(x => x.MethodName).HasMaxLength(AuditLogActionConsts.MaxMethodNameLength).HasColumnName(nameof(AuditLogAction.MethodName));
b.Property(x => x.Parameters).HasMaxLength(AuditLogActionConsts.MaxParametersLength).HasColumnName(nameof(AuditLogAction.Parameters)); b.Property(x => x.Parameters).HasMaxLength(AuditLogActionConsts.MaxParametersLength).HasColumnName(nameof(AuditLogAction.Parameters));
b.Property(x => x.ExecutionTime).HasColumnName(nameof(AuditLogAction.ExecutionTime)); b.Property(x => x.ExecutionTime).HasColumnName(nameof(AuditLogAction.ExecutionTime));
b.Property(x => x.ExecutionDuration).HasColumnName(nameof(AuditLogAction.ExecutionDuration)); b.Property(x => x.ExecutionDuration).HasColumnName(nameof(AuditLogAction.ExecutionDuration));
b.HasIndex(x => new { x.AuditLogId }); b.HasIndex(x => new { x.AuditLogId });
b.HasIndex(x => new { x.TenantId, x.ServiceName, x.MethodName, x.ExecutionTime }); b.HasIndex(x => new { x.TenantId, x.ServiceName, x.MethodName, x.ExecutionTime });
b.ApplyObjectExtensionMappings(); b.ApplyObjectExtensionMappings();
}); });
builder.Entity<EntityChange>(b => builder.Entity<EntityChange>(b =>
{ {
b.ToTable(AbpAuditLoggingDbProperties.DbTablePrefix + "EntityChanges", AbpAuditLoggingDbProperties.DbSchema); b.ToTable(AbpAuditLoggingDbProperties.DbTablePrefix + "EntityChanges", AbpAuditLoggingDbProperties.DbSchema);
b.ConfigureByConvention(); b.ConfigureByConvention();
b.Property(x => x.EntityTypeFullName).HasMaxLength(EntityChangeConsts.MaxEntityTypeFullNameLength).IsRequired().HasColumnName(nameof(EntityChange.EntityTypeFullName)); b.Property(x => x.EntityTypeFullName).HasMaxLength(EntityChangeConsts.MaxEntityTypeFullNameLength).IsRequired().HasColumnName(nameof(EntityChange.EntityTypeFullName));
b.Property(x => x.EntityId).HasMaxLength(EntityChangeConsts.MaxEntityIdLength).IsRequired().HasColumnName(nameof(EntityChange.EntityId)); b.Property(x => x.EntityId).HasMaxLength(EntityChangeConsts.MaxEntityIdLength).IsRequired().HasColumnName(nameof(EntityChange.EntityId));
b.Property(x => x.AuditLogId).IsRequired().HasColumnName(nameof(EntityChange.AuditLogId)); b.Property(x => x.AuditLogId).IsRequired().HasColumnName(nameof(EntityChange.AuditLogId));
b.Property(x => x.ChangeTime).IsRequired().HasColumnName(nameof(EntityChange.ChangeTime)); b.Property(x => x.ChangeTime).IsRequired().HasColumnName(nameof(EntityChange.ChangeTime));
b.Property(x => x.ChangeType).IsRequired().HasColumnName(nameof(EntityChange.ChangeType)); b.Property(x => x.ChangeType).IsRequired().HasColumnName(nameof(EntityChange.ChangeType));
b.Property(x => x.TenantId).HasColumnName(nameof(EntityChange.TenantId)); b.Property(x => x.TenantId).HasColumnName(nameof(EntityChange.TenantId));
b.HasMany(a => a.PropertyChanges).WithOne().HasForeignKey(x => x.EntityChangeId); b.HasMany(a => a.PropertyChanges).WithOne().HasForeignKey(x => x.EntityChangeId);
b.HasIndex(x => new { x.AuditLogId }); b.HasIndex(x => new { x.AuditLogId });
b.HasIndex(x => new { x.TenantId, x.EntityTypeFullName, x.EntityId }); b.HasIndex(x => new { x.TenantId, x.EntityTypeFullName, x.EntityId });
b.ApplyObjectExtensionMappings(); b.ApplyObjectExtensionMappings();
}); });
builder.Entity<EntityPropertyChange>(b => builder.Entity<EntityPropertyChange>(b =>
{ {
b.ToTable(AbpAuditLoggingDbProperties.DbTablePrefix + "EntityPropertyChanges", AbpAuditLoggingDbProperties.DbSchema); b.ToTable(AbpAuditLoggingDbProperties.DbTablePrefix + "EntityPropertyChanges", AbpAuditLoggingDbProperties.DbSchema);
b.ConfigureByConvention(); b.ConfigureByConvention();
b.Property(x => x.NewValue).HasMaxLength(EntityPropertyChangeConsts.MaxNewValueLength).HasColumnName(nameof(EntityPropertyChange.NewValue)); b.Property(x => x.NewValue).HasMaxLength(EntityPropertyChangeConsts.MaxNewValueLength).HasColumnName(nameof(EntityPropertyChange.NewValue));
b.Property(x => x.PropertyName).HasMaxLength(EntityPropertyChangeConsts.MaxPropertyNameLength).IsRequired().HasColumnName(nameof(EntityPropertyChange.PropertyName)); b.Property(x => x.PropertyName).HasMaxLength(EntityPropertyChangeConsts.MaxPropertyNameLength).IsRequired().HasColumnName(nameof(EntityPropertyChange.PropertyName));
b.Property(x => x.PropertyTypeFullName).HasMaxLength(EntityPropertyChangeConsts.MaxPropertyTypeFullNameLength).IsRequired().HasColumnName(nameof(EntityPropertyChange.PropertyTypeFullName)); b.Property(x => x.PropertyTypeFullName).HasMaxLength(EntityPropertyChangeConsts.MaxPropertyTypeFullNameLength).IsRequired().HasColumnName(nameof(EntityPropertyChange.PropertyTypeFullName));
b.Property(x => x.OriginalValue).HasMaxLength(EntityPropertyChangeConsts.MaxOriginalValueLength).HasColumnName(nameof(EntityPropertyChange.OriginalValue)); b.Property(x => x.OriginalValue).HasMaxLength(EntityPropertyChangeConsts.MaxOriginalValueLength).HasColumnName(nameof(EntityPropertyChange.OriginalValue));
b.HasIndex(x => new { x.EntityChangeId }); b.HasIndex(x => new { x.EntityChangeId });
b.ApplyObjectExtensionMappings(); b.ApplyObjectExtensionMappings();
}); });
builder.TryConfigureObjectExtensions<AbpAuditLoggingDbContext>(); builder.TryConfigureObjectExtensions<AbpAuditLoggingDbContext>();
}
} }
} }

19
modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingEntityFrameworkCoreModule.cs

@ -2,18 +2,17 @@
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace Volo.Abp.AuditLogging.EntityFrameworkCore namespace Volo.Abp.AuditLogging.EntityFrameworkCore;
[DependsOn(typeof(AbpAuditLoggingDomainModule))]
[DependsOn(typeof(AbpEntityFrameworkCoreModule))]
public class AbpAuditLoggingEntityFrameworkCoreModule : AbpModule
{ {
[DependsOn(typeof(AbpAuditLoggingDomainModule))] public override void ConfigureServices(ServiceConfigurationContext context)
[DependsOn(typeof(AbpEntityFrameworkCoreModule))]
public class AbpAuditLoggingEntityFrameworkCoreModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) context.Services.AddAbpDbContext<AbpAuditLoggingDbContext>(options =>
{ {
context.Services.AddAbpDbContext<AbpAuditLoggingDbContext>(options => options.AddRepository<AuditLog, EfCoreAuditLogRepository>();
{ });
options.AddRepository<AuditLog, EfCoreAuditLogRepository>();
});
}
} }
} }

461
modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs

@ -11,265 +11,264 @@ using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
namespace Volo.Abp.AuditLogging.EntityFrameworkCore namespace Volo.Abp.AuditLogging.EntityFrameworkCore;
public class EfCoreAuditLogRepository : EfCoreRepository<IAuditLoggingDbContext, AuditLog, Guid>, IAuditLogRepository
{ {
public class EfCoreAuditLogRepository : EfCoreRepository<IAuditLoggingDbContext, AuditLog, Guid>, IAuditLogRepository public EfCoreAuditLogRepository(IDbContextProvider<IAuditLoggingDbContext> dbContextProvider)
: base(dbContextProvider)
{ {
public EfCoreAuditLogRepository(IDbContextProvider<IAuditLoggingDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public virtual async Task<List<AuditLog>> GetListAsync( }
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string clientIpAddress = null,
string correlationId = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = await GetListQueryAsync(
startTime,
endTime,
httpMethod,
url,
userId,
userName,
applicationName,
clientIpAddress,
correlationId,
maxExecutionDuration,
minExecutionDuration,
hasException,
httpStatusCode,
includeDetails
);
var auditLogs = await query public virtual async Task<List<AuditLog>> GetListAsync(
.OrderBy(sorting.IsNullOrWhiteSpace() ? (nameof(AuditLog.ExecutionTime) + " DESC") : sorting) string sorting = null,
.PageBy(skipCount, maxResultCount) int maxResultCount = 50,
.ToListAsync(GetCancellationToken(cancellationToken)); int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string clientIpAddress = null,
string correlationId = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = await GetListQueryAsync(
startTime,
endTime,
httpMethod,
url,
userId,
userName,
applicationName,
clientIpAddress,
correlationId,
maxExecutionDuration,
minExecutionDuration,
hasException,
httpStatusCode,
includeDetails
);
return auditLogs; var auditLogs = await query
} .OrderBy(sorting.IsNullOrWhiteSpace() ? (nameof(AuditLog.ExecutionTime) + " DESC") : sorting)
.PageBy(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
public virtual async Task<long> GetCountAsync( return auditLogs;
DateTime? startTime = null, }
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string clientIpAddress = null,
string correlationId = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
CancellationToken cancellationToken = default)
{
var query = await GetListQueryAsync(
startTime,
endTime,
httpMethod,
url,
userId,
userName,
applicationName,
clientIpAddress,
correlationId,
maxExecutionDuration,
minExecutionDuration,
hasException,
httpStatusCode
);
var totalCount = await query.LongCountAsync(GetCancellationToken(cancellationToken)); public virtual async Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string clientIpAddress = null,
string correlationId = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
CancellationToken cancellationToken = default)
{
var query = await GetListQueryAsync(
startTime,
endTime,
httpMethod,
url,
userId,
userName,
applicationName,
clientIpAddress,
correlationId,
maxExecutionDuration,
minExecutionDuration,
hasException,
httpStatusCode
);
return totalCount; var totalCount = await query.LongCountAsync(GetCancellationToken(cancellationToken));
}
protected virtual async Task<IQueryable<AuditLog>> GetListQueryAsync( return totalCount;
DateTime? startTime = null, }
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string clientIpAddress = null,
string correlationId = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false)
{
var nHttpStatusCode = (int?) httpStatusCode;
return (await GetDbSetAsync()).AsNoTracking()
.IncludeDetails(includeDetails)
.WhereIf(startTime.HasValue, auditLog => auditLog.ExecutionTime >= startTime)
.WhereIf(endTime.HasValue, auditLog => auditLog.ExecutionTime <= endTime)
.WhereIf(hasException.HasValue && hasException.Value, auditLog => auditLog.Exceptions != null && auditLog.Exceptions != "")
.WhereIf(hasException.HasValue && !hasException.Value, auditLog => auditLog.Exceptions == null || auditLog.Exceptions == "")
.WhereIf(httpMethod != null, auditLog => auditLog.HttpMethod == httpMethod)
.WhereIf(url != null, auditLog => auditLog.Url != null && auditLog.Url.Contains(url))
.WhereIf(userId != null, auditLog => auditLog.UserId == userId)
.WhereIf(userName != null, auditLog => auditLog.UserName == userName)
.WhereIf(applicationName != null, auditLog => auditLog.ApplicationName == applicationName)
.WhereIf(clientIpAddress != null, auditLog => auditLog.ClientIpAddress != null && auditLog.ClientIpAddress == clientIpAddress)
.WhereIf(correlationId != null, auditLog => auditLog.CorrelationId == correlationId)
.WhereIf(httpStatusCode != null && httpStatusCode > 0, auditLog => auditLog.HttpStatusCode == nHttpStatusCode)
.WhereIf(maxExecutionDuration != null && maxExecutionDuration.Value > 0, auditLog => auditLog.ExecutionDuration <= maxExecutionDuration)
.WhereIf(minExecutionDuration != null && minExecutionDuration.Value > 0, auditLog => auditLog.ExecutionDuration >= minExecutionDuration);
}
public virtual async Task<Dictionary<DateTime, double>> GetAverageExecutionDurationPerDayAsync( protected virtual async Task<IQueryable<AuditLog>> GetListQueryAsync(
DateTime startDate, DateTime? startTime = null,
DateTime endDate, DateTime? endTime = null,
CancellationToken cancellationToken = default) string httpMethod = null,
{ string url = null,
var result = await (await GetDbSetAsync()).AsNoTracking() Guid? userId = null,
.Where(a => a.ExecutionTime < endDate.AddDays(1) && a.ExecutionTime > startDate) string userName = null,
.OrderBy(t => t.ExecutionTime) string applicationName = null,
.GroupBy(t => new { t.ExecutionTime.Date }) string clientIpAddress = null,
.Select(g => new { Day = g.Min(t => t.ExecutionTime), avgExecutionTime = g.Average(t => t.ExecutionDuration) }) string correlationId = null,
.ToListAsync(GetCancellationToken(cancellationToken)); int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false)
{
var nHttpStatusCode = (int?)httpStatusCode;
return (await GetDbSetAsync()).AsNoTracking()
.IncludeDetails(includeDetails)
.WhereIf(startTime.HasValue, auditLog => auditLog.ExecutionTime >= startTime)
.WhereIf(endTime.HasValue, auditLog => auditLog.ExecutionTime <= endTime)
.WhereIf(hasException.HasValue && hasException.Value, auditLog => auditLog.Exceptions != null && auditLog.Exceptions != "")
.WhereIf(hasException.HasValue && !hasException.Value, auditLog => auditLog.Exceptions == null || auditLog.Exceptions == "")
.WhereIf(httpMethod != null, auditLog => auditLog.HttpMethod == httpMethod)
.WhereIf(url != null, auditLog => auditLog.Url != null && auditLog.Url.Contains(url))
.WhereIf(userId != null, auditLog => auditLog.UserId == userId)
.WhereIf(userName != null, auditLog => auditLog.UserName == userName)
.WhereIf(applicationName != null, auditLog => auditLog.ApplicationName == applicationName)
.WhereIf(clientIpAddress != null, auditLog => auditLog.ClientIpAddress != null && auditLog.ClientIpAddress == clientIpAddress)
.WhereIf(correlationId != null, auditLog => auditLog.CorrelationId == correlationId)
.WhereIf(httpStatusCode != null && httpStatusCode > 0, auditLog => auditLog.HttpStatusCode == nHttpStatusCode)
.WhereIf(maxExecutionDuration != null && maxExecutionDuration.Value > 0, auditLog => auditLog.ExecutionDuration <= maxExecutionDuration)
.WhereIf(minExecutionDuration != null && minExecutionDuration.Value > 0, auditLog => auditLog.ExecutionDuration >= minExecutionDuration);
}
return result.ToDictionary(element => element.Day.ClearTime(), element => element.avgExecutionTime); public virtual async Task<Dictionary<DateTime, double>> GetAverageExecutionDurationPerDayAsync(
} DateTime startDate,
DateTime endDate,
CancellationToken cancellationToken = default)
{
var result = await (await GetDbSetAsync()).AsNoTracking()
.Where(a => a.ExecutionTime < endDate.AddDays(1) && a.ExecutionTime > startDate)
.OrderBy(t => t.ExecutionTime)
.GroupBy(t => new { t.ExecutionTime.Date })
.Select(g => new { Day = g.Min(t => t.ExecutionTime), avgExecutionTime = g.Average(t => t.ExecutionDuration) })
.ToListAsync(GetCancellationToken(cancellationToken));
[Obsolete("Use WithDetailsAsync method.")] return result.ToDictionary(element => element.Day.ClearTime(), element => element.avgExecutionTime);
public override IQueryable<AuditLog> WithDetails() }
{
return GetQueryable().IncludeDetails();
}
public override async Task<IQueryable<AuditLog>> WithDetailsAsync() [Obsolete("Use WithDetailsAsync method.")]
{ public override IQueryable<AuditLog> WithDetails()
return (await GetQueryableAsync()).IncludeDetails(); {
} return GetQueryable().IncludeDetails();
}
public virtual async Task<EntityChange> GetEntityChange( public override async Task<IQueryable<AuditLog>> WithDetailsAsync()
Guid entityChangeId, {
CancellationToken cancellationToken = default) return (await GetQueryableAsync()).IncludeDetails();
{ }
var entityChange = await (await GetDbContextAsync()).Set<EntityChange>()
.AsNoTracking()
.IncludeDetails()
.Where(x => x.Id == entityChangeId)
.OrderBy(x => x.Id)
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
if (entityChange == null) public virtual async Task<EntityChange> GetEntityChange(
{ Guid entityChangeId,
throw new EntityNotFoundException(typeof(EntityChange)); CancellationToken cancellationToken = default)
} {
var entityChange = await (await GetDbContextAsync()).Set<EntityChange>()
.AsNoTracking()
.IncludeDetails()
.Where(x => x.Id == entityChangeId)
.OrderBy(x => x.Id)
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
return entityChange; if (entityChange == null)
{
throw new EntityNotFoundException(typeof(EntityChange));
} }
public virtual async Task<List<EntityChange>> GetEntityChangeListAsync( return entityChange;
string sorting = null, }
int maxResultCount = 50,
int skipCount = 0,
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string entityId = null,
string entityTypeFullName = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, includeDetails);
return await query.OrderBy(sorting.IsNullOrWhiteSpace() ? (nameof(EntityChange.ChangeTime) + " DESC") : sorting) public virtual async Task<List<EntityChange>> GetEntityChangeListAsync(
.PageBy(skipCount, maxResultCount) string sorting = null,
.ToListAsync(GetCancellationToken(cancellationToken)); int maxResultCount = 50,
} int skipCount = 0,
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string entityId = null,
string entityTypeFullName = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, includeDetails);
public virtual async Task<long> GetEntityChangeCountAsync( return await query.OrderBy(sorting.IsNullOrWhiteSpace() ? (nameof(EntityChange.ChangeTime) + " DESC") : sorting)
Guid? auditLogId = null, .PageBy(skipCount, maxResultCount)
DateTime? startTime = null, .ToListAsync(GetCancellationToken(cancellationToken));
DateTime? endTime = null, }
EntityChangeType? changeType = null,
string entityId = null,
string entityTypeFullName = null,
CancellationToken cancellationToken = default)
{
var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName);
var totalCount = await query.LongCountAsync(GetCancellationToken(cancellationToken)); public virtual async Task<long> GetEntityChangeCountAsync(
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string entityId = null,
string entityTypeFullName = null,
CancellationToken cancellationToken = default)
{
var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName);
return totalCount; var totalCount = await query.LongCountAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<EntityChangeWithUsername> GetEntityChangeWithUsernameAsync( return totalCount;
Guid entityChangeId, }
CancellationToken cancellationToken = default)
{
var auditLog = await (await GetDbSetAsync()).AsNoTracking().IncludeDetails()
.Where(x => x.EntityChanges.Any(y => y.Id == entityChangeId)).FirstAsync(GetCancellationToken(cancellationToken));
return new EntityChangeWithUsername() public virtual async Task<EntityChangeWithUsername> GetEntityChangeWithUsernameAsync(
{ Guid entityChangeId,
EntityChange = auditLog.EntityChanges.First(x => x.Id == entityChangeId), CancellationToken cancellationToken = default)
UserName = auditLog.UserName {
}; var auditLog = await (await GetDbSetAsync()).AsNoTracking().IncludeDetails()
} .Where(x => x.EntityChanges.Any(y => y.Id == entityChangeId)).FirstAsync(GetCancellationToken(cancellationToken));
public virtual async Task<List<EntityChangeWithUsername>> GetEntityChangesWithUsernameAsync( return new EntityChangeWithUsername()
string entityId,
string entityTypeFullName,
CancellationToken cancellationToken = default)
{ {
var dbContext = await GetDbContextAsync(); EntityChange = auditLog.EntityChanges.First(x => x.Id == entityChangeId),
UserName = auditLog.UserName
};
}
var query = dbContext.Set<EntityChange>() public virtual async Task<List<EntityChangeWithUsername>> GetEntityChangesWithUsernameAsync(
.AsNoTracking() string entityId,
.IncludeDetails() string entityTypeFullName,
.Where(x => x.EntityId == entityId && x.EntityTypeFullName == entityTypeFullName); CancellationToken cancellationToken = default)
{
var dbContext = await GetDbContextAsync();
return await (from e in query var query = dbContext.Set<EntityChange>()
join auditLog in dbContext.AuditLogs on e.AuditLogId equals auditLog.Id .AsNoTracking()
select new EntityChangeWithUsername {EntityChange = e, UserName = auditLog.UserName}) .IncludeDetails()
.OrderByDescending(x => x.EntityChange.ChangeTime).ToListAsync(GetCancellationToken(cancellationToken)); .Where(x => x.EntityId == entityId && x.EntityTypeFullName == entityTypeFullName);
}
protected virtual async Task<IQueryable<EntityChange>> GetEntityChangeListQueryAsync( return await (from e in query
Guid? auditLogId = null, join auditLog in dbContext.AuditLogs on e.AuditLogId equals auditLog.Id
DateTime? startTime = null, select new EntityChangeWithUsername { EntityChange = e, UserName = auditLog.UserName })
DateTime? endTime = null, .OrderByDescending(x => x.EntityChange.ChangeTime).ToListAsync(GetCancellationToken(cancellationToken));
EntityChangeType? changeType = null, }
string entityId = null,
string entityTypeFullName = null, protected virtual async Task<IQueryable<EntityChange>> GetEntityChangeListQueryAsync(
bool includeDetails = false) Guid? auditLogId = null,
{ DateTime? startTime = null,
return (await GetDbContextAsync()) DateTime? endTime = null,
.Set<EntityChange>() EntityChangeType? changeType = null,
.AsNoTracking() string entityId = null,
.IncludeDetails(includeDetails) string entityTypeFullName = null,
.WhereIf(auditLogId.HasValue, e => e.AuditLogId == auditLogId) bool includeDetails = false)
.WhereIf(startTime.HasValue, e => e.ChangeTime >= startTime) {
.WhereIf(endTime.HasValue, e => e.ChangeTime <= endTime) return (await GetDbContextAsync())
.WhereIf(changeType.HasValue, e => e.ChangeType == changeType) .Set<EntityChange>()
.WhereIf(!string.IsNullOrWhiteSpace(entityId), e => e.EntityId == entityId) .AsNoTracking()
.WhereIf(!string.IsNullOrWhiteSpace(entityTypeFullName), e => e.EntityTypeFullName.Contains(entityTypeFullName)); .IncludeDetails(includeDetails)
} .WhereIf(auditLogId.HasValue, e => e.AuditLogId == auditLogId)
.WhereIf(startTime.HasValue, e => e.ChangeTime >= startTime)
.WhereIf(endTime.HasValue, e => e.ChangeTime <= endTime)
.WhereIf(changeType.HasValue, e => e.ChangeType == changeType)
.WhereIf(!string.IsNullOrWhiteSpace(entityId), e => e.EntityId == entityId)
.WhereIf(!string.IsNullOrWhiteSpace(entityTypeFullName), e => e.EntityTypeFullName.Contains(entityTypeFullName));
} }
} }

13
modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/IAuditLoggingDbContext.cs

@ -2,11 +2,10 @@
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;
namespace Volo.Abp.AuditLogging.EntityFrameworkCore namespace Volo.Abp.AuditLogging.EntityFrameworkCore;
[ConnectionStringName(AbpAuditLoggingDbProperties.ConnectionStringName)]
public interface IAuditLoggingDbContext : IEfCoreDbContext
{ {
[ConnectionStringName(AbpAuditLoggingDbProperties.ConnectionStringName)] DbSet<AuditLog> AuditLogs { get; }
public interface IAuditLoggingDbContext : IEfCoreDbContext }
{
DbSet<AuditLog> AuditLogs { get; }
}
}

23
modules/audit-logging/src/Volo.Abp.AuditLogging.Installer/Volo/Abp/AuditLogging/AbpAuditLoggingInstallerModule.cs

@ -2,20 +2,19 @@
using Volo.Abp.Studio; using Volo.Abp.Studio;
using Volo.Abp.VirtualFileSystem; using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
[DependsOn(
typeof(AbpStudioModuleInstallerModule),
typeof(AbpVirtualFileSystemModule)
)]
public class AbpAuditLoggingInstallerModule : AbpModule
{ {
[DependsOn( public override void ConfigureServices(ServiceConfigurationContext context)
typeof(AbpStudioModuleInstallerModule),
typeof(AbpVirtualFileSystemModule)
)]
public class AbpAuditLoggingInstallerModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) Configure<AbpVirtualFileSystemOptions>(options =>
{ {
Configure<AbpVirtualFileSystemOptions>(options => options.FileSets.AddEmbedded<AbpAuditLoggingInstallerModule>();
{ });
options.FileSets.AddEmbedded<AbpAuditLoggingInstallerModule>();
});
}
} }
} }

29
modules/audit-logging/src/Volo.Abp.AuditLogging.Installer/Volo/Abp/AuditLogging/AuditLoggingInstallerPipelineBuilder.cs

@ -3,22 +3,21 @@ using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Studio.ModuleInstalling; using Volo.Abp.Studio.ModuleInstalling;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
[ExposeServices(typeof(IModuleInstallingPipelineBuilder))]
public class AuditLoggingInstallerPipelineBuilder : ModuleInstallingPipelineBuilderBase, IModuleInstallingPipelineBuilder, ITransientDependency
{ {
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)] public async Task<ModuleInstallingPipeline> BuildAsync(ModuleInstallingContext context)
[ExposeServices(typeof(IModuleInstallingPipelineBuilder))]
public class AuditLoggingInstallerPipelineBuilder : ModuleInstallingPipelineBuilderBase, IModuleInstallingPipelineBuilder, ITransientDependency
{ {
public async Task<ModuleInstallingPipeline> BuildAsync(ModuleInstallingContext context) context.AddEfCoreConfigurationMethodDeclaration(
{ new EfCoreConfigurationMethodDeclaration(
context.AddEfCoreConfigurationMethodDeclaration( "Volo.Abp.AuditLogging.EntityFrameworkCore",
new EfCoreConfigurationMethodDeclaration( "ConfigureAuditLogging"
"Volo.Abp.AuditLogging.EntityFrameworkCore", )
"ConfigureAuditLogging" );
)
); return GetBasePipeline(context);
return GetBasePipeline(context);
}
} }
} }

21
modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbContextExtensions.cs

@ -1,18 +1,17 @@
using Volo.Abp.MongoDB; using Volo.Abp.MongoDB;
namespace Volo.Abp.AuditLogging.MongoDB namespace Volo.Abp.AuditLogging.MongoDB;
public static class AbpAuditLoggingMongoDbContextExtensions
{ {
public static class AbpAuditLoggingMongoDbContextExtensions public static void ConfigureAuditLogging(
this IMongoModelBuilder builder)
{ {
public static void ConfigureAuditLogging( Check.NotNull(builder, nameof(builder));
this IMongoModelBuilder builder)
{
Check.NotNull(builder, nameof(builder));
builder.Entity<AuditLog>(b => builder.Entity<AuditLog>(b =>
{ {
b.CollectionName = AbpAuditLoggingDbProperties.DbTablePrefix + "AuditLogs"; b.CollectionName = AbpAuditLoggingDbProperties.DbTablePrefix + "AuditLogs";
}); });
}
} }
} }

19
modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbModule.cs

@ -2,18 +2,17 @@
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.MongoDB; using Volo.Abp.MongoDB;
namespace Volo.Abp.AuditLogging.MongoDB namespace Volo.Abp.AuditLogging.MongoDB;
[DependsOn(typeof(AbpAuditLoggingDomainModule))]
[DependsOn(typeof(AbpMongoDbModule))]
public class AbpAuditLoggingMongoDbModule : AbpModule
{ {
[DependsOn(typeof(AbpAuditLoggingDomainModule))] public override void ConfigureServices(ServiceConfigurationContext context)
[DependsOn(typeof(AbpMongoDbModule))]
public class AbpAuditLoggingMongoDbModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) context.Services.AddMongoDbContext<AuditLoggingMongoDbContext>(options =>
{ {
context.Services.AddMongoDbContext<AuditLoggingMongoDbContext>(options => options.AddRepository<AuditLog, MongoAuditLogRepository>();
{ });
options.AddRepository<AuditLog, MongoAuditLogRepository>();
});
}
} }
} }

19
modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/AuditLoggingMongoDbContext.cs

@ -2,18 +2,17 @@
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.MongoDB; using Volo.Abp.MongoDB;
namespace Volo.Abp.AuditLogging.MongoDB namespace Volo.Abp.AuditLogging.MongoDB;
[ConnectionStringName(AbpAuditLoggingDbProperties.ConnectionStringName)]
public class AuditLoggingMongoDbContext : AbpMongoDbContext, IAuditLoggingMongoDbContext
{ {
[ConnectionStringName(AbpAuditLoggingDbProperties.ConnectionStringName)] public IMongoCollection<AuditLog> AuditLogs => Collection<AuditLog>();
public class AuditLoggingMongoDbContext : AbpMongoDbContext, IAuditLoggingMongoDbContext
{
public IMongoCollection<AuditLog> AuditLogs => Collection<AuditLog>();
protected override void CreateModel(IMongoModelBuilder modelBuilder) protected override void CreateModel(IMongoModelBuilder modelBuilder)
{ {
base.CreateModel(modelBuilder); base.CreateModel(modelBuilder);
modelBuilder.ConfigureAuditLogging(); modelBuilder.ConfigureAuditLogging();
}
} }
} }

11
modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/IAuditLoggingMongoDbContext.cs

@ -2,11 +2,10 @@
using Volo.Abp.Data; using Volo.Abp.Data;
using Volo.Abp.MongoDB; using Volo.Abp.MongoDB;
namespace Volo.Abp.AuditLogging.MongoDB namespace Volo.Abp.AuditLogging.MongoDB;
[ConnectionStringName(AbpAuditLoggingDbProperties.ConnectionStringName)]
public interface IAuditLoggingMongoDbContext : IAbpMongoDbContext
{ {
[ConnectionStringName(AbpAuditLoggingDbProperties.ConnectionStringName)] IMongoCollection<AuditLog> AuditLogs { get; }
public interface IAuditLoggingMongoDbContext : IAbpMongoDbContext
{
IMongoCollection<AuditLog> AuditLogs { get; }
}
} }

456
modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs

@ -12,261 +12,259 @@ using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.Domain.Repositories.MongoDB;
using Volo.Abp.MongoDB; using Volo.Abp.MongoDB;
namespace Volo.Abp.AuditLogging.MongoDB namespace Volo.Abp.AuditLogging.MongoDB;
public class MongoAuditLogRepository : MongoDbRepository<IAuditLoggingMongoDbContext, AuditLog, Guid>, IAuditLogRepository
{ {
public class MongoAuditLogRepository : MongoDbRepository<IAuditLoggingMongoDbContext, AuditLog, Guid>, IAuditLogRepository public MongoAuditLogRepository(IMongoDbContextProvider<IAuditLoggingMongoDbContext> dbContextProvider)
: base(dbContextProvider)
{ {
public MongoAuditLogRepository(IMongoDbContextProvider<IAuditLoggingMongoDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public virtual async Task<List<AuditLog>> GetListAsync( }
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string clientIpAddress = null,
string correlationId = null,
int? maxDuration = null,
int? minDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = await GetListQueryAsync(
startTime,
endTime,
httpMethod,
url,
userId,
userName,
applicationName,
clientIpAddress,
correlationId,
maxDuration,
minDuration,
hasException,
httpStatusCode,
includeDetails,
cancellationToken
);
return await query public virtual async Task<List<AuditLog>> GetListAsync(
.OrderBy(sorting.IsNullOrWhiteSpace() ? (nameof(AuditLog.ExecutionTime) + " DESC") : sorting) string sorting = null,
.As<IMongoQueryable<AuditLog>>() int maxResultCount = 50,
.PageBy<AuditLog, IMongoQueryable<AuditLog>>(skipCount, maxResultCount) int skipCount = 0,
.ToListAsync(GetCancellationToken(cancellationToken)); DateTime? startTime = null,
} DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string clientIpAddress = null,
string correlationId = null,
int? maxDuration = null,
int? minDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = await GetListQueryAsync(
startTime,
endTime,
httpMethod,
url,
userId,
userName,
applicationName,
clientIpAddress,
correlationId,
maxDuration,
minDuration,
hasException,
httpStatusCode,
includeDetails,
cancellationToken
);
public virtual async Task<long> GetCountAsync( return await query
DateTime? startTime = null, .OrderBy(sorting.IsNullOrWhiteSpace() ? (nameof(AuditLog.ExecutionTime) + " DESC") : sorting)
DateTime? endTime = null, .As<IMongoQueryable<AuditLog>>()
string httpMethod = null, .PageBy<AuditLog, IMongoQueryable<AuditLog>>(skipCount, maxResultCount)
string url = null, .ToListAsync(GetCancellationToken(cancellationToken));
Guid? userId = null, }
string userName = null,
string applicationName = null,
string clientIpAddress = null,
string correlationId = null,
int? maxDuration = null,
int? minDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
CancellationToken cancellationToken = default)
{
var query = await GetListQueryAsync(
startTime,
endTime,
httpMethod,
url,
userId,
userName,
applicationName,
clientIpAddress,
correlationId,
maxDuration,
minDuration,
hasException,
httpStatusCode,
cancellationToken: cancellationToken
);
var count = await query.As<IMongoQueryable<AuditLog>>() public virtual async Task<long> GetCountAsync(
.LongCountAsync(GetCancellationToken(cancellationToken)); DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string clientIpAddress = null,
string correlationId = null,
int? maxDuration = null,
int? minDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
CancellationToken cancellationToken = default)
{
var query = await GetListQueryAsync(
startTime,
endTime,
httpMethod,
url,
userId,
userName,
applicationName,
clientIpAddress,
correlationId,
maxDuration,
minDuration,
hasException,
httpStatusCode,
cancellationToken: cancellationToken
);
return count; var count = await query.As<IMongoQueryable<AuditLog>>()
} .LongCountAsync(GetCancellationToken(cancellationToken));
protected virtual async Task<IQueryable<AuditLog>> GetListQueryAsync( return count;
DateTime? startTime = null, }
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string clientIpAddress = null,
string correlationId = null,
int? maxDuration = null,
int? minDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return (await GetMongoQueryableAsync(cancellationToken))
.WhereIf(startTime.HasValue, auditLog => auditLog.ExecutionTime >= startTime)
.WhereIf(endTime.HasValue, auditLog => auditLog.ExecutionTime <= endTime)
.WhereIf(hasException.HasValue && hasException.Value, auditLog => auditLog.Exceptions != null && auditLog.Exceptions != "")
.WhereIf(hasException.HasValue && !hasException.Value, auditLog => auditLog.Exceptions == null || auditLog.Exceptions == "")
.WhereIf(httpMethod != null, auditLog => auditLog.HttpMethod == httpMethod)
.WhereIf(url != null, auditLog => auditLog.Url != null && auditLog.Url.Contains(url))
.WhereIf(userId != null, auditLog => auditLog.UserId == userId)
.WhereIf(userName != null, auditLog => auditLog.UserName == userName)
.WhereIf(applicationName != null, auditLog => auditLog.ApplicationName == applicationName)
.WhereIf(clientIpAddress != null, auditLog => auditLog.ClientIpAddress == clientIpAddress)
.WhereIf(correlationId != null, auditLog => auditLog.CorrelationId == correlationId)
.WhereIf(httpStatusCode != null && httpStatusCode > 0, auditLog => auditLog.HttpStatusCode == (int?)httpStatusCode)
.WhereIf(maxDuration != null && maxDuration > 0, auditLog => auditLog.ExecutionDuration <= maxDuration)
.WhereIf(minDuration != null && minDuration > 0, auditLog => auditLog.ExecutionDuration >= minDuration);
}
public virtual async Task<Dictionary<DateTime, double>> GetAverageExecutionDurationPerDayAsync( protected virtual async Task<IQueryable<AuditLog>> GetListQueryAsync(
DateTime startDate, DateTime? startTime = null,
DateTime endDate, DateTime? endTime = null,
CancellationToken cancellationToken = default) string httpMethod = null,
{ string url = null,
var result = await (await GetMongoQueryableAsync(cancellationToken)) Guid? userId = null,
.Where(a => a.ExecutionTime < endDate.AddDays(1) && a.ExecutionTime > startDate) string userName = null,
.OrderBy(t => t.ExecutionTime) string applicationName = null,
.GroupBy(t => new string clientIpAddress = null,
{ string correlationId = null,
t.ExecutionTime.Year, int? maxDuration = null,
t.ExecutionTime.Month, int? minDuration = null,
t.ExecutionTime.Day bool? hasException = null,
}) HttpStatusCode? httpStatusCode = null,
.Select(g => new { Day = g.Min(t => t.ExecutionTime), avgExecutionTime = g.Average(t => t.ExecutionDuration) }) bool includeDetails = false,
.ToListAsync(GetCancellationToken(cancellationToken)); CancellationToken cancellationToken = default)
{
return (await GetMongoQueryableAsync(cancellationToken))
.WhereIf(startTime.HasValue, auditLog => auditLog.ExecutionTime >= startTime)
.WhereIf(endTime.HasValue, auditLog => auditLog.ExecutionTime <= endTime)
.WhereIf(hasException.HasValue && hasException.Value, auditLog => auditLog.Exceptions != null && auditLog.Exceptions != "")
.WhereIf(hasException.HasValue && !hasException.Value, auditLog => auditLog.Exceptions == null || auditLog.Exceptions == "")
.WhereIf(httpMethod != null, auditLog => auditLog.HttpMethod == httpMethod)
.WhereIf(url != null, auditLog => auditLog.Url != null && auditLog.Url.Contains(url))
.WhereIf(userId != null, auditLog => auditLog.UserId == userId)
.WhereIf(userName != null, auditLog => auditLog.UserName == userName)
.WhereIf(applicationName != null, auditLog => auditLog.ApplicationName == applicationName)
.WhereIf(clientIpAddress != null, auditLog => auditLog.ClientIpAddress == clientIpAddress)
.WhereIf(correlationId != null, auditLog => auditLog.CorrelationId == correlationId)
.WhereIf(httpStatusCode != null && httpStatusCode > 0, auditLog => auditLog.HttpStatusCode == (int?)httpStatusCode)
.WhereIf(maxDuration != null && maxDuration > 0, auditLog => auditLog.ExecutionDuration <= maxDuration)
.WhereIf(minDuration != null && minDuration > 0, auditLog => auditLog.ExecutionDuration >= minDuration);
}
return result.ToDictionary(element => element.Day.ClearTime(), element => element.avgExecutionTime); public virtual async Task<Dictionary<DateTime, double>> GetAverageExecutionDurationPerDayAsync(
} DateTime startDate,
DateTime endDate,
CancellationToken cancellationToken = default)
{
var result = await (await GetMongoQueryableAsync(cancellationToken))
.Where(a => a.ExecutionTime < endDate.AddDays(1) && a.ExecutionTime > startDate)
.OrderBy(t => t.ExecutionTime)
.GroupBy(t => new {
t.ExecutionTime.Year,
t.ExecutionTime.Month,
t.ExecutionTime.Day
})
.Select(g => new { Day = g.Min(t => t.ExecutionTime), avgExecutionTime = g.Average(t => t.ExecutionDuration) })
.ToListAsync(GetCancellationToken(cancellationToken));
public virtual async Task<EntityChange> GetEntityChange( return result.ToDictionary(element => element.Day.ClearTime(), element => element.avgExecutionTime);
Guid entityChangeId, }
CancellationToken cancellationToken = default)
{
var entityChange = (await (await GetMongoQueryableAsync(cancellationToken))
.Where(x => x.EntityChanges.Any(y => y.Id == entityChangeId))
.OrderBy(x => x.Id)
.FirstAsync(GetCancellationToken(cancellationToken))).EntityChanges.FirstOrDefault(x => x.Id == entityChangeId);
if (entityChange == null) public virtual async Task<EntityChange> GetEntityChange(
{ Guid entityChangeId,
throw new EntityNotFoundException(typeof(EntityChange)); CancellationToken cancellationToken = default)
} {
var entityChange = (await (await GetMongoQueryableAsync(cancellationToken))
.Where(x => x.EntityChanges.Any(y => y.Id == entityChangeId))
.OrderBy(x => x.Id)
.FirstAsync(GetCancellationToken(cancellationToken))).EntityChanges.FirstOrDefault(x => x.Id == entityChangeId);
return entityChange; if (entityChange == null)
{
throw new EntityNotFoundException(typeof(EntityChange));
} }
public virtual async Task<List<EntityChange>> GetEntityChangeListAsync( return entityChange;
string sorting = null, }
int maxResultCount = 50,
int skipCount = 0,
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string entityId = null,
string entityTypeFullName = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, cancellationToken);
return await query public virtual async Task<List<EntityChange>> GetEntityChangeListAsync(
.OrderBy(sorting.IsNullOrWhiteSpace() ? (nameof(EntityChange.ChangeTime) + " DESC") : sorting) string sorting = null,
.As<IMongoQueryable<EntityChange>>() int maxResultCount = 50,
.PageBy<EntityChange, IMongoQueryable<EntityChange>>(skipCount, maxResultCount) int skipCount = 0,
.ToListAsync(GetCancellationToken(cancellationToken)); Guid? auditLogId = null,
} DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string entityId = null,
string entityTypeFullName = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, cancellationToken);
public virtual async Task<long> GetEntityChangeCountAsync( return await query
Guid? auditLogId = null, .OrderBy(sorting.IsNullOrWhiteSpace() ? (nameof(EntityChange.ChangeTime) + " DESC") : sorting)
DateTime? startTime = null, .As<IMongoQueryable<EntityChange>>()
DateTime? endTime = null, .PageBy<EntityChange, IMongoQueryable<EntityChange>>(skipCount, maxResultCount)
EntityChangeType? changeType = null, .ToListAsync(GetCancellationToken(cancellationToken));
string entityId = null, }
string entityTypeFullName = null,
CancellationToken cancellationToken = default)
{
var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, cancellationToken);
var count = await query.As<IMongoQueryable<EntityChange>>().LongCountAsync(GetCancellationToken(cancellationToken)); public virtual async Task<long> GetEntityChangeCountAsync(
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string entityId = null,
string entityTypeFullName = null,
CancellationToken cancellationToken = default)
{
var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, cancellationToken);
return count; var count = await query.As<IMongoQueryable<EntityChange>>().LongCountAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<EntityChangeWithUsername> GetEntityChangeWithUsernameAsync( return count;
Guid entityChangeId, }
CancellationToken cancellationToken = default)
{
var auditLog = await (await GetMongoQueryableAsync(cancellationToken))
.Where(x => x.EntityChanges.Any(y => y.Id == entityChangeId))
.FirstAsync(GetCancellationToken(cancellationToken));
return new EntityChangeWithUsername() public virtual async Task<EntityChangeWithUsername> GetEntityChangeWithUsernameAsync(
{ Guid entityChangeId,
EntityChange = auditLog.EntityChanges.First(x => x.Id == entityChangeId), CancellationToken cancellationToken = default)
UserName = auditLog.UserName {
}; var auditLog = await (await GetMongoQueryableAsync(cancellationToken))
} .Where(x => x.EntityChanges.Any(y => y.Id == entityChangeId))
.FirstAsync(GetCancellationToken(cancellationToken));
public virtual async Task<List<EntityChangeWithUsername>> GetEntityChangesWithUsernameAsync( return new EntityChangeWithUsername()
string entityId,
string entityTypeFullName,
CancellationToken cancellationToken = default)
{ {
var auditLogs = await (await GetMongoQueryableAsync(cancellationToken)) EntityChange = auditLog.EntityChanges.First(x => x.Id == entityChangeId),
.Where(x => x.EntityChanges.Any(y => y.EntityId == entityId && y.EntityTypeFullName == entityTypeFullName)) UserName = auditLog.UserName
.As<IMongoQueryable<AuditLog>>() };
.OrderByDescending(x => x.ExecutionTime) }
.ToListAsync(GetCancellationToken(cancellationToken));
var entityChanges = auditLogs.SelectMany(x => x.EntityChanges).ToList(); public virtual async Task<List<EntityChangeWithUsername>> GetEntityChangesWithUsernameAsync(
string entityId,
string entityTypeFullName,
CancellationToken cancellationToken = default)
{
var auditLogs = await (await GetMongoQueryableAsync(cancellationToken))
.Where(x => x.EntityChanges.Any(y => y.EntityId == entityId && y.EntityTypeFullName == entityTypeFullName))
.As<IMongoQueryable<AuditLog>>()
.OrderByDescending(x => x.ExecutionTime)
.ToListAsync(GetCancellationToken(cancellationToken));
entityChanges.RemoveAll(x => x.EntityId != entityId || x.EntityTypeFullName != entityTypeFullName); var entityChanges = auditLogs.SelectMany(x => x.EntityChanges).ToList();
return entityChanges.Select(x => new EntityChangeWithUsername() entityChanges.RemoveAll(x => x.EntityId != entityId || x.EntityTypeFullName != entityTypeFullName);
{EntityChange = x, UserName = auditLogs.First(y => y.Id == x.AuditLogId).UserName}).ToList();
}
protected virtual async Task<IQueryable<EntityChange>> GetEntityChangeListQueryAsync( return entityChanges.Select(x => new EntityChangeWithUsername()
Guid? auditLogId = null, { EntityChange = x, UserName = auditLogs.First(y => y.Id == x.AuditLogId).UserName }).ToList();
DateTime? startTime = null, }
DateTime? endTime = null,
EntityChangeType? changeType = null, protected virtual async Task<IQueryable<EntityChange>> GetEntityChangeListQueryAsync(
string entityId = null, Guid? auditLogId = null,
string entityTypeFullName = null, DateTime? startTime = null,
CancellationToken cancellationToken = default) DateTime? endTime = null,
{ EntityChangeType? changeType = null,
return (await GetMongoQueryableAsync(cancellationToken)) string entityId = null,
.SelectMany(x => x.EntityChanges) string entityTypeFullName = null,
.WhereIf(auditLogId.HasValue, e => e.Id == auditLogId) CancellationToken cancellationToken = default)
.WhereIf(startTime.HasValue, e => e.ChangeTime >= startTime) {
.WhereIf(endTime.HasValue, e => e.ChangeTime <= endTime) return (await GetMongoQueryableAsync(cancellationToken))
.WhereIf(changeType.HasValue, e => e.ChangeType == changeType) .SelectMany(x => x.EntityChanges)
.WhereIf(!string.IsNullOrWhiteSpace(entityId), e => e.EntityId == entityId) .WhereIf(auditLogId.HasValue, e => e.Id == auditLogId)
.WhereIf(!string.IsNullOrWhiteSpace(entityTypeFullName), .WhereIf(startTime.HasValue, e => e.ChangeTime >= startTime)
e => e.EntityTypeFullName.Contains(entityTypeFullName)); .WhereIf(endTime.HasValue, e => e.ChangeTime <= endTime)
} .WhereIf(changeType.HasValue, e => e.ChangeType == changeType)
.WhereIf(!string.IsNullOrWhiteSpace(entityId), e => e.EntityId == entityId)
.WhereIf(!string.IsNullOrWhiteSpace(entityTypeFullName),
e => e.EntityTypeFullName.Contains(entityTypeFullName));
} }
} }

51
modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingEntityFrameworkCoreTestModule.cs

@ -7,38 +7,37 @@ using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.Sqlite; using Volo.Abp.EntityFrameworkCore.Sqlite;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace Volo.Abp.AuditLogging.EntityFrameworkCore namespace Volo.Abp.AuditLogging.EntityFrameworkCore;
[DependsOn(
typeof(AbpAuditLoggingTestBaseModule),
typeof(AbpAuditLoggingEntityFrameworkCoreModule),
typeof(AbpEntityFrameworkCoreSqliteModule)
)]
public class AbpAuditLoggingEntityFrameworkCoreTestModule : AbpModule
{ {
[DependsOn( public override void ConfigureServices(ServiceConfigurationContext context)
typeof(AbpAuditLoggingTestBaseModule),
typeof(AbpAuditLoggingEntityFrameworkCoreModule),
typeof(AbpEntityFrameworkCoreSqliteModule)
)]
public class AbpAuditLoggingEntityFrameworkCoreTestModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) var sqliteConnection = CreateDatabaseAndGetConnection();
{
var sqliteConnection = CreateDatabaseAndGetConnection();
Configure<AbpDbContextOptions>(options => Configure<AbpDbContextOptions>(options =>
{
options.Configure(ctx =>
{ {
options.Configure(ctx => ctx.DbContextOptions.UseSqlite(sqliteConnection);
{
ctx.DbContextOptions.UseSqlite(sqliteConnection);
});
}); });
} });
}
private static SqliteConnection CreateDatabaseAndGetConnection() private static SqliteConnection CreateDatabaseAndGetConnection()
{ {
var connection = new SqliteConnection("Data Source=:memory:"); var connection = new SqliteConnection("Data Source=:memory:");
connection.Open(); connection.Open();
new AbpAuditLoggingDbContext( new AbpAuditLoggingDbContext(
new DbContextOptionsBuilder<AbpAuditLoggingDbContext>().UseSqlite(connection).Options new DbContextOptionsBuilder<AbpAuditLoggingDbContext>().UseSqlite(connection).Options
).GetService<IRelationalDatabaseCreator>().CreateTables(); ).GetService<IRelationalDatabaseCreator>().CreateTables();
return connection; return connection;
}
} }
} }

7
modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo/Abp/AuditLogging/EntityFrameworkCore/AuditLogRepository_Tests.cs

@ -1,7 +1,6 @@
namespace Volo.Abp.AuditLogging.EntityFrameworkCore namespace Volo.Abp.AuditLogging.EntityFrameworkCore;
public class AuditLogRepository_Tests : AuditLogRepository_Tests<AbpAuditLoggingEntityFrameworkCoreTestModule>
{ {
public class AuditLogRepository_Tests : AuditLogRepository_Tests<AbpAuditLoggingEntityFrameworkCoreTestModule>
{
}
} }

7
modules/audit-logging/test/Volo.Abp.AuditLogging.EntityFrameworkCore.Tests/Volo/Abp/AuditLogging/EntityFrameworkCore/AuditStore_Basic_Tests.cs

@ -1,7 +1,6 @@
namespace Volo.Abp.AuditLogging.EntityFrameworkCore namespace Volo.Abp.AuditLogging.EntityFrameworkCore;
public class AuditStore_Basic_Tests : AuditStore_Basic_Tests<AbpAuditLoggingEntityFrameworkCoreTestModule>
{ {
public class AuditStore_Basic_Tests : AuditStore_Basic_Tests<AbpAuditLoggingEntityFrameworkCoreTestModule>
{
}
} }

33
modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AbpAuditLoggingMongoDbTestModule.cs

@ -3,25 +3,24 @@ using Volo.Abp.Data;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.Uow; using Volo.Abp.Uow;
namespace Volo.Abp.AuditLogging.MongoDB namespace Volo.Abp.AuditLogging.MongoDB;
[DependsOn(
typeof(AbpAuditLoggingTestBaseModule),
typeof(AbpAuditLoggingMongoDbModule)
)]
public class AbpAuditLoggingMongoDbTestModule : AbpModule
{ {
[DependsOn( public override void ConfigureServices(ServiceConfigurationContext context)
typeof(AbpAuditLoggingTestBaseModule),
typeof(AbpAuditLoggingMongoDbModule)
)]
public class AbpAuditLoggingMongoDbTestModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) var stringArray = MongoDbFixture.ConnectionString.Split('?');
{ var connectionString = stringArray[0].EnsureEndsWith('/') +
var stringArray = MongoDbFixture.ConnectionString.Split('?'); "Db_" +
var connectionString = stringArray[0].EnsureEndsWith('/') + Guid.NewGuid().ToString("N") + "/?" + stringArray[1];
"Db_" +
Guid.NewGuid().ToString("N") + "/?" + stringArray[1];
Configure<AbpDbConnectionOptions>(options => Configure<AbpDbConnectionOptions>(options =>
{ {
options.ConnectionStrings.Default = connectionString; options.ConnectionStrings.Default = connectionString;
}); });
}
} }
} }

9
modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AuditLogRepository_Tests.cs

@ -3,11 +3,10 @@ using System.Collections.Generic;
using System.Text; using System.Text;
using Xunit; using Xunit;
namespace Volo.Abp.AuditLogging.MongoDB namespace Volo.Abp.AuditLogging.MongoDB;
[Collection(MongoTestCollection.Name)]
public class AuditLogRepository_Tests : AuditLogRepository_Tests<AbpAuditLoggingMongoDbTestModule>
{ {
[Collection(MongoTestCollection.Name)]
public class AuditLogRepository_Tests : AuditLogRepository_Tests<AbpAuditLoggingMongoDbTestModule>
{
}
} }

9
modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/AuditStore_Basic_Tests.cs

@ -1,10 +1,9 @@
using Xunit; using Xunit;
namespace Volo.Abp.AuditLogging.MongoDB namespace Volo.Abp.AuditLogging.MongoDB;
[Collection(MongoTestCollection.Name)]
public class AuditStore_Basic_Tests : AuditStore_Basic_Tests<AbpAuditLoggingMongoDbTestModule>
{ {
[Collection(MongoTestCollection.Name)]
public class AuditStore_Basic_Tests : AuditStore_Basic_Tests<AbpAuditLoggingMongoDbTestModule>
{
}
} }

27
modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoDbFixture.cs

@ -1,22 +1,21 @@
using System; using System;
using Mongo2Go; using Mongo2Go;
namespace Volo.Abp.AuditLogging.MongoDB namespace Volo.Abp.AuditLogging.MongoDB;
public class MongoDbFixture : IDisposable
{ {
public class MongoDbFixture : IDisposable private static readonly MongoDbRunner MongoDbRunner;
{ public static readonly string ConnectionString;
private static readonly MongoDbRunner MongoDbRunner;
public static readonly string ConnectionString;
static MongoDbFixture() static MongoDbFixture()
{ {
MongoDbRunner = MongoDbRunner.Start(singleNodeReplSet: true, singleNodeReplSetWaitTimeout: 20); MongoDbRunner = MongoDbRunner.Start(singleNodeReplSet: true, singleNodeReplSetWaitTimeout: 20);
ConnectionString = MongoDbRunner.ConnectionString; ConnectionString = MongoDbRunner.ConnectionString;
} }
public void Dispose() public void Dispose()
{ {
MongoDbRunner?.Dispose(); MongoDbRunner?.Dispose();
}
} }
} }

13
modules/audit-logging/test/Volo.Abp.AuditLogging.MongoDB.Tests/Volo/Abp/AuditLogging/MongoDB/MongoTestCollection.cs

@ -1,10 +1,9 @@
using Xunit; using Xunit;
namespace Volo.Abp.AuditLogging.MongoDB namespace Volo.Abp.AuditLogging.MongoDB;
[CollectionDefinition(Name)]
public class MongoTestCollection : ICollectionFixture<MongoDbFixture>
{ {
[CollectionDefinition(Name)] public const string Name = "MongoDB Collection";
public class MongoTestCollection : ICollectionFixture<MongoDbFixture> }
{
public const string Name = "MongoDB Collection";
}
}

33
modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AbpAuditLoggingTestBaseModule.cs

@ -2,27 +2,26 @@
using Volo.Abp.Autofac; using Volo.Abp.Autofac;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
[DependsOn(
typeof(AbpAutofacModule),
typeof(AbpTestBaseModule),
typeof(AbpAuditLoggingDomainModule))]
public class AbpAuditLoggingTestBaseModule : AbpModule
{ {
[DependsOn( public override void OnApplicationInitialization(ApplicationInitializationContext context)
typeof(AbpAutofacModule),
typeof(AbpTestBaseModule),
typeof(AbpAuditLoggingDomainModule))]
public class AbpAuditLoggingTestBaseModule : AbpModule
{ {
public override void OnApplicationInitialization(ApplicationInitializationContext context) SeedTestData(context);
{ }
SeedTestData(context);
}
private static void SeedTestData(ApplicationInitializationContext context) private static void SeedTestData(ApplicationInitializationContext context)
{
using (var scope = context.ServiceProvider.CreateScope())
{ {
using (var scope = context.ServiceProvider.CreateScope()) scope.ServiceProvider
{ .GetRequiredService<AuditingTestDataBuilder>()
scope.ServiceProvider .Build();
.GetRequiredService <AuditingTestDataBuilder>()
.Build();
}
} }
} }
} }

877
modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditLogRepository_Tests.cs

File diff suppressed because it is too large

13
modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditLoggingTestBase.cs

@ -1,14 +1,13 @@
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.Testing; using Volo.Abp.Testing;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
public class AuditLoggingTestBase<TStartupModule> : AbpIntegratedTest<TStartupModule>
where TStartupModule : IAbpModule
{ {
public class AuditLoggingTestBase<TStartupModule> : AbpIntegratedTest<TStartupModule> protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
where TStartupModule : IAbpModule
{ {
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) options.UseAutofac();
{
options.UseAutofac();
}
} }
} }

9
modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditLogging_Repository_Resolve_Tests.cs

@ -3,11 +3,10 @@ using System.Collections.Generic;
using System.Text; using System.Text;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
public class AuditLogging_Repository_Resolve_Tests<TStartupModule> : AuditLoggingTestBase<TStartupModule>
where TStartupModule : IAbpModule
{ {
public class AuditLogging_Repository_Resolve_Tests<TStartupModule> : AuditLoggingTestBase<TStartupModule>
where TStartupModule : IAbpModule
{
}
} }

177
modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditStore_Basic_Tests.cs

@ -8,40 +8,40 @@ using Volo.Abp.Auditing;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Xunit; using Xunit;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
public abstract class AuditStore_Basic_Tests<TStartupModule> : AuditLoggingTestBase<TStartupModule>
where TStartupModule : IAbpModule
{ {
public abstract class AuditStore_Basic_Tests<TStartupModule> : AuditLoggingTestBase<TStartupModule> private readonly IAuditingStore _auditingStore;
where TStartupModule : IAbpModule private readonly IAuditLogRepository _auditLogRepository;
protected AuditStore_Basic_Tests()
{ {
private readonly IAuditingStore _auditingStore; _auditingStore = GetRequiredService<IAuditingStore>();
private readonly IAuditLogRepository _auditLogRepository; _auditLogRepository = GetRequiredService<IAuditLogRepository>();
}
protected AuditStore_Basic_Tests() [Fact]
{ public async Task Should_Save_An_Audit_Log()
_auditingStore = GetRequiredService<IAuditingStore>(); {
_auditLogRepository = GetRequiredService<IAuditLogRepository>(); //Arrange
} var userId = new Guid("4456fb0d-74cc-4807-9eee-23e551e6cb06");
var ipAddress = "153.1.7.61";
var firstComment = "first Comment";
[Fact] var auditLog = new AuditLogInfo
public async Task Should_Save_An_Audit_Log()
{ {
//Arrange UserId = userId,
var userId = new Guid("4456fb0d-74cc-4807-9eee-23e551e6cb06"); ImpersonatorUserId = Guid.NewGuid(),
var ipAddress = "153.1.7.61"; ImpersonatorTenantId = Guid.NewGuid(),
var firstComment = "first Comment"; ExecutionTime = DateTime.Today,
ExecutionDuration = 42,
var auditLog = new AuditLogInfo ClientIpAddress = ipAddress,
{ ClientName = "MyDesktop",
UserId = userId, BrowserInfo = "Chrome",
ImpersonatorUserId = Guid.NewGuid(), Comments = new List<string> { firstComment, "Second Comment" },
ImpersonatorTenantId = Guid.NewGuid(), EntityChanges =
ExecutionTime = DateTime.Today,
ExecutionDuration = 42,
ClientIpAddress = ipAddress,
ClientName = "MyDesktop",
BrowserInfo = "Chrome",
Comments = new List<string> { firstComment, "Second Comment" },
EntityChanges =
{ {
new EntityChangeInfo new EntityChangeInfo
{ {
@ -61,43 +61,43 @@ namespace Volo.Abp.AuditLogging
} }
} }
} }
}; };
//Act //Act
await _auditingStore.SaveAsync(auditLog); await _auditingStore.SaveAsync(auditLog);
//Assert //Assert
var insertedLog = (await _auditLogRepository.GetListAsync(true)) var insertedLog = (await _auditLogRepository.GetListAsync(true))
.FirstOrDefault(al => al.UserId == userId); .FirstOrDefault(al => al.UserId == userId);
insertedLog.ShouldNotBeNull(); insertedLog.ShouldNotBeNull();
insertedLog.ClientIpAddress.ShouldBe(ipAddress); insertedLog.ClientIpAddress.ShouldBe(ipAddress);
insertedLog.Comments.ShouldStartWith(firstComment); insertedLog.Comments.ShouldStartWith(firstComment);
insertedLog.EntityChanges.Count.ShouldBeGreaterThan(0); insertedLog.EntityChanges.Count.ShouldBeGreaterThan(0);
insertedLog.EntityChanges.First().PropertyChanges.Count.ShouldBeGreaterThan(0); insertedLog.EntityChanges.First().PropertyChanges.Count.ShouldBeGreaterThan(0);
} }
[Fact]
public async Task Should_Get_List_Of_Audit_Logs()
{
var userId = new Guid("4456fb0d-74cc-4807-9eee-23e551e6cb06");
var ipAddress = "153.1.7.61";
var firstComment = "first Comment";
[Fact] var log1 = new AuditLogInfo
public async Task Should_Get_List_Of_Audit_Logs()
{ {
var userId = new Guid("4456fb0d-74cc-4807-9eee-23e551e6cb06"); UserId = userId,
var ipAddress = "153.1.7.61"; ImpersonatorUserId = Guid.NewGuid(),
var firstComment = "first Comment"; ImpersonatorTenantId = Guid.NewGuid(),
ExecutionTime = DateTime.Today,
var log1 = new AuditLogInfo ExecutionDuration = 42,
{ ClientIpAddress = ipAddress,
UserId = userId, ClientName = "MyDesktop",
ImpersonatorUserId = Guid.NewGuid(), BrowserInfo = "Chrome",
ImpersonatorTenantId = Guid.NewGuid(), Comments = new List<string> { firstComment, "Second Comment" },
ExecutionTime = DateTime.Today, UserName = "Douglas",
ExecutionDuration = 42, EntityChanges = {
ClientIpAddress = ipAddress,
ClientName = "MyDesktop",
BrowserInfo = "Chrome",
Comments = new List<string> { firstComment, "Second Comment" },
UserName = "Douglas",
EntityChanges = {
new EntityChangeInfo new EntityChangeInfo
{ {
EntityId = Guid.NewGuid().ToString(), EntityId = Guid.NewGuid().ToString(),
@ -134,21 +134,21 @@ namespace Volo.Abp.AuditLogging
} }
} }
}; };
var log2 = new AuditLogInfo var log2 = new AuditLogInfo
{ {
UserId = userId, UserId = userId,
ImpersonatorUserId = Guid.NewGuid(), ImpersonatorUserId = Guid.NewGuid(),
ImpersonatorTenantId = Guid.NewGuid(), ImpersonatorTenantId = Guid.NewGuid(),
ExecutionTime = DateTime.Today, ExecutionTime = DateTime.Today,
ExecutionDuration = 42, ExecutionDuration = 42,
ClientIpAddress = ipAddress, ClientIpAddress = ipAddress,
ClientName = "MyDesktop", ClientName = "MyDesktop",
BrowserInfo = "Chrome", BrowserInfo = "Chrome",
Comments = new List<string> { firstComment, "Second Comment" }, Comments = new List<string> { firstComment, "Second Comment" },
HttpStatusCode = (int?)HttpStatusCode.BadGateway, HttpStatusCode = (int?)HttpStatusCode.BadGateway,
EntityChanges = { EntityChanges = {
new EntityChangeInfo new EntityChangeInfo
{ {
EntityId = Guid.NewGuid().ToString(), EntityId = Guid.NewGuid().ToString(),
@ -168,27 +168,26 @@ namespace Volo.Abp.AuditLogging
} }
} }
}; };
await _auditingStore.SaveAsync(log1); await _auditingStore.SaveAsync(log1);
await _auditingStore.SaveAsync(log2); await _auditingStore.SaveAsync(log2);
var allLogsCount = await _auditLogRepository.GetCountAsync(); var allLogsCount = await _auditLogRepository.GetCountAsync();
var onlyLog1QueryResult = await _auditLogRepository.GetListAsync(includeDetails: true, userName: "Douglas"); var onlyLog1QueryResult = await _auditLogRepository.GetListAsync(includeDetails: true, userName: "Douglas");
var onlyLog2QueryResult = await _auditLogRepository.GetListAsync(includeDetails: true, httpStatusCode: HttpStatusCode.BadGateway); var onlyLog2QueryResult = await _auditLogRepository.GetListAsync(includeDetails: true, httpStatusCode: HttpStatusCode.BadGateway);
allLogsCount.ShouldBe(2); allLogsCount.ShouldBe(2);
onlyLog1QueryResult.Count.ShouldBe(1); onlyLog1QueryResult.Count.ShouldBe(1);
onlyLog1QueryResult.FirstOrDefault().UserName.ShouldBe("Douglas"); onlyLog1QueryResult.FirstOrDefault().UserName.ShouldBe("Douglas");
onlyLog1QueryResult.FirstOrDefault().EntityChanges.Count.ShouldBe(2); onlyLog1QueryResult.FirstOrDefault().EntityChanges.Count.ShouldBe(2);
onlyLog2QueryResult.Count.ShouldBe(1); onlyLog2QueryResult.Count.ShouldBe(1);
onlyLog2QueryResult.FirstOrDefault().HttpStatusCode.ShouldBe((int?)HttpStatusCode.BadGateway); onlyLog2QueryResult.FirstOrDefault().HttpStatusCode.ShouldBe((int?)HttpStatusCode.BadGateway);
onlyLog2QueryResult.FirstOrDefault().EntityChanges.Count.ShouldBe(1); onlyLog2QueryResult.FirstOrDefault().EntityChanges.Count.ShouldBe(1);
}
} }
} }

23
modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditingTestDataBuilder.cs

@ -1,19 +1,18 @@
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
public class AuditingTestDataBuilder : ITransientDependency
{ {
public class AuditingTestDataBuilder : ITransientDependency private readonly IAuditLogRepository _auditLogRepository;
public AuditingTestDataBuilder(IAuditLogRepository auditLogRepository)
{ {
private readonly IAuditLogRepository _auditLogRepository; _auditLogRepository = auditLogRepository;
}
public AuditingTestDataBuilder(IAuditLogRepository auditLogRepository ) public void Build()
{ {
_auditLogRepository = auditLogRepository;
}
public void Build()
{
}
} }
} }

13
modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo/Abp/AuditLogging/AbpAuditLoggingTestModule.cs

@ -1,13 +1,12 @@
using Volo.Abp.AuditLogging.EntityFrameworkCore; using Volo.Abp.AuditLogging.EntityFrameworkCore;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
[DependsOn(
typeof(AbpAuditLoggingEntityFrameworkCoreTestModule)
)]
public class AbpAuditLoggingTestModule : AbpModule
{ {
[DependsOn(
typeof(AbpAuditLoggingEntityFrameworkCoreTestModule)
)]
public class AbpAuditLoggingTestModule : AbpModule
{
}
} }

37
modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo/Abp/AuditLogging/AuditLogsTestBase.cs

@ -3,31 +3,30 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Volo.Abp.AuditLogging.EntityFrameworkCore; using Volo.Abp.AuditLogging.EntityFrameworkCore;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
public class AuditLogsTestBase : AuditLoggingTestBase<AbpAuditLoggingTestModule>
{ {
public class AuditLogsTestBase : AuditLoggingTestBase<AbpAuditLoggingTestModule> protected virtual void UsingDbContext(Action<IAuditLoggingDbContext> action)
{ {
protected virtual void UsingDbContext(Action<IAuditLoggingDbContext> action) using (var dbContext = GetRequiredService<IAuditLoggingDbContext>())
{ {
using (var dbContext = GetRequiredService<IAuditLoggingDbContext>()) action.Invoke(dbContext);
{
action.Invoke(dbContext);
}
} }
}
protected virtual T UsingDbContext<T>(Func<IAuditLoggingDbContext, T> action) protected virtual T UsingDbContext<T>(Func<IAuditLoggingDbContext, T> action)
{
using (var dbContext = GetRequiredService<IAuditLoggingDbContext>())
{ {
using (var dbContext = GetRequiredService<IAuditLoggingDbContext>()) return action.Invoke(dbContext);
{
return action.Invoke(dbContext);
}
} }
}
protected List<AuditLog> GetAuditLogsFromDbContext() protected List<AuditLog> GetAuditLogsFromDbContext()
{ {
return UsingDbContext(context => return UsingDbContext(context =>
context.AuditLogs.IncludeDetails().ToList() context.AuditLogs.IncludeDetails().ToList()
); );
}
} }
} }

111
modules/audit-logging/test/Volo.Abp.AuditLogging.Tests/Volo/Abp/AuditLogging/MultiTenantAuditLog_Tests.cs

@ -5,72 +5,71 @@ using Shouldly;
using Volo.Abp.Auditing; using Volo.Abp.Auditing;
using Xunit; using Xunit;
namespace Volo.Abp.AuditLogging namespace Volo.Abp.AuditLogging;
public class MultiTenantAuditLog_Tests : AuditLogsTestBase
{ {
public class MultiTenantAuditLog_Tests : AuditLogsTestBase private readonly IAuditingManager _auditingManager;
{ private readonly IAuditLogRepository _auditLogRepository;
private readonly IAuditingManager _auditingManager;
private readonly IAuditLogRepository _auditLogRepository;
public MultiTenantAuditLog_Tests() public MultiTenantAuditLog_Tests()
{ {
_auditingManager = GetRequiredService<IAuditingManager>(); _auditingManager = GetRequiredService<IAuditingManager>();
_auditLogRepository = GetRequiredService<IAuditLogRepository>(); _auditLogRepository = GetRequiredService<IAuditLogRepository>();
} }
[Fact] [Fact]
public async Task Should_Save_Audit_Logs_To_The_Tenant_Begins_The_Scope() public async Task Should_Save_Audit_Logs_To_The_Tenant_Begins_The_Scope()
{ {
//Arrange //Arrange
var applicationName = Guid.NewGuid().ToString(); var applicationName = Guid.NewGuid().ToString();
var tenantId = Guid.NewGuid(); var tenantId = Guid.NewGuid();
var entityId1 = Guid.NewGuid(); var entityId1 = Guid.NewGuid();
var entityId2 = Guid.NewGuid(); var entityId2 = Guid.NewGuid();
//Act //Act
using (var scope = _auditingManager.BeginScope()) using (var scope = _auditingManager.BeginScope())
{ {
_auditingManager.Current.Log.ApplicationName = applicationName; _auditingManager.Current.Log.ApplicationName = applicationName;
//Creating a host entity //Creating a host entity
_auditingManager.Current.Log.EntityChanges.Add( _auditingManager.Current.Log.EntityChanges.Add(
new EntityChangeInfo new EntityChangeInfo
{ {
ChangeTime = DateTime.Now, ChangeTime = DateTime.Now,
ChangeType = EntityChangeType.Created, ChangeType = EntityChangeType.Created,
EntityEntry = new object(), EntityEntry = new object(),
EntityId = entityId1.ToString(), EntityId = entityId1.ToString(),
EntityTypeFullName = "TestEntity" EntityTypeFullName = "TestEntity"
} }
); );
//Creating a tenant entity //Creating a tenant entity
_auditingManager.Current.Log.EntityChanges.Add( _auditingManager.Current.Log.EntityChanges.Add(
new EntityChangeInfo new EntityChangeInfo
{ {
ChangeTime = DateTime.Now, ChangeTime = DateTime.Now,
ChangeType = EntityChangeType.Created, ChangeType = EntityChangeType.Created,
EntityEntry = new object(), EntityEntry = new object(),
EntityId = entityId2.ToString(), EntityId = entityId2.ToString(),
EntityTypeFullName = "TestEntity", EntityTypeFullName = "TestEntity",
EntityTenantId = tenantId EntityTenantId = tenantId
} }
); );
await scope.SaveAsync(); await scope.SaveAsync();
} }
//Assert //Assert
var auditLogs = await _auditLogRepository.GetListAsync(applicationName: applicationName, includeDetails: true); var auditLogs = await _auditLogRepository.GetListAsync(applicationName: applicationName, includeDetails: true);
auditLogs.Count.ShouldBe(1); auditLogs.Count.ShouldBe(1);
var auditLog = auditLogs.First(); var auditLog = auditLogs.First();
auditLog.EntityChanges.ShouldNotBeNull(); auditLog.EntityChanges.ShouldNotBeNull();
auditLog.EntityChanges.Count.ShouldBe(2); auditLog.EntityChanges.Count.ShouldBe(2);
auditLog.EntityChanges.ShouldContain(e => e.EntityId == entityId1.ToString()); auditLog.EntityChanges.ShouldContain(e => e.EntityId == entityId1.ToString());
auditLog.EntityChanges.ShouldContain(e => e.EntityId == entityId2.ToString()); auditLog.EntityChanges.ShouldContain(e => e.EntityId == entityId2.ToString());
}
} }
} }

Loading…
Cancel
Save