From 4c17ed4180c33d457436426ab557fd0ccfb30c8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20=C3=87otur?= Date: Fri, 27 Mar 2020 16:07:00 +0300 Subject: [PATCH 1/8] entitychanges ef core implemented --- .../Abp/AuditLogging/IAuditLogRepository.cs | 23 ++++++++ ...bpAuditLoggingEfCoreQueryableExtensions.cs | 12 ++++ .../EfCoreAuditLogRepository.cs | 56 ++++++++++++++++++ .../IAuditLoggingDbContext.cs | 2 + .../MongoDB/MongoAuditLogRepository.cs | 58 +++++++++++++++++++ 5 files changed, 151 insertions(+) diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/IAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/IAuditLogRepository.cs index fb676fe288..dbf3692b29 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/IAuditLogRepository.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/IAuditLogRepository.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Net; using System.Threading; using System.Threading.Tasks; +using Volo.Abp.Auditing; using Volo.Abp.Domain.Repositories; namespace Volo.Abp.AuditLogging @@ -44,5 +45,27 @@ namespace Volo.Abp.AuditLogging Task> GetAverageExecutionDurationPerDayAsync( DateTime startDate, DateTime endDate); + + Task> GetEntityChangeListAsync( + 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); + + Task GetEntityChangeCountAsync( + Guid? auditLogId = null, + DateTime? startTime = null, + DateTime? endTime = null, + EntityChangeType? changeType = null, + string entityId = null, + string entityTypeFullName = null, + CancellationToken cancellationToken = default); } } diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/AbpAuditLoggingEfCoreQueryableExtensions.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/AbpAuditLoggingEfCoreQueryableExtensions.cs index 27445045e7..6dc4bfadb8 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/AbpAuditLoggingEfCoreQueryableExtensions.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/AbpAuditLoggingEfCoreQueryableExtensions.cs @@ -18,5 +18,17 @@ namespace Volo.Abp.AuditLogging .Include(x => x.Actions) .Include(x => x.EntityChanges).ThenInclude(ec=>ec.PropertyChanges); } + + public static IQueryable IncludeDetails( + this IQueryable queryable, + bool include = true) + { + if (!include) + { + return queryable; + } + + return queryable.Include(x => x.PropertyChanges); + } } } diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs index 1fabbcbe7c..ece526d869 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs @@ -6,6 +6,7 @@ using System.Net; using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; +using Volo.Abp.Auditing; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; @@ -139,5 +140,60 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore { return GetQueryable().IncludeDetails(); } + + public virtual async Task> GetEntityChangeListAsync( + 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 = GetEntityChangeListQuery(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, includeDetails); + + return await query.OrderBy(sorting ?? "changeTime desc") + .PageBy(skipCount, maxResultCount) + .ToListAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task GetEntityChangeCountAsync( + Guid? auditLogId = null, + DateTime? startTime = null, + DateTime? endTime = null, + EntityChangeType? changeType = null, + string entityId = null, + string entityTypeFullName = null, + CancellationToken cancellationToken = default) + { + var query = GetEntityChangeListQuery(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, false); + + var totalCount = await query.LongCountAsync(GetCancellationToken(cancellationToken)); + + return totalCount; + } + + protected virtual IQueryable GetEntityChangeListQuery( + Guid? auditLogId = null, + DateTime? startTime = null, + DateTime? endTime = null, + EntityChangeType? changeType = null, + string entityId = null, + string entityTypeFullName = null, + bool includeDetails = false) + { + return DbContext.EntityChanges.AsNoTracking().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 == entityTypeFullName); + } } } diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/IAuditLoggingDbContext.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/IAuditLoggingDbContext.cs index 684c5fc55f..a74c20bd68 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/IAuditLoggingDbContext.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/IAuditLoggingDbContext.cs @@ -8,5 +8,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore public interface IAuditLoggingDbContext : IEfCoreDbContext { DbSet AuditLogs { get; set; } + + DbSet EntityChanges { get; set; } } } \ No newline at end of file diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs index fdb9bca387..a813ada669 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs @@ -7,6 +7,7 @@ using System.Threading; using System.Threading.Tasks; using MongoDB.Driver; using MongoDB.Driver.Linq; +using Volo.Abp.Auditing; using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.MongoDB; @@ -138,5 +139,62 @@ namespace Volo.Abp.AuditLogging.MongoDB return result.ToDictionary(element => element.Day.ClearTime(), element => element.avgExecutionTime); } + + public virtual async Task> GetEntityChangeListAsync( + 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 = GetEntityChangeListQuery(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, includeDetails); + + return await query.OrderBy(sorting ?? "changeTime desc").As>() + .PageBy>(skipCount, maxResultCount) + .ToListAsync(GetCancellationToken(cancellationToken)); + } + + public virtual async Task GetEntityChangeCountAsync( + Guid? auditLogId = null, + DateTime? startTime = null, + DateTime? endTime = null, + EntityChangeType? changeType = null, + string entityId = null, + string entityTypeFullName = null, + CancellationToken cancellationToken = default) + { + var query = GetEntityChangeListQuery(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName); + var count = await query.As>() + .LongCountAsync(GetCancellationToken(cancellationToken)); + + return count; + } + + protected virtual IQueryable GetEntityChangeListQuery( + Guid? auditLogId = null, + DateTime? startTime = null, + DateTime? endTime = null, + EntityChangeType? changeType = null, + string entityId = null, + string entityTypeFullName = null, + bool includeDetails = false) + { + return null; + // TODO: Learn How to? + return GetMongoQueryable() + .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 == entityTypeFullName); + } } } From 122e157555186e95948cb5389df1cd1c2a90b25e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20=C3=87otur?= Date: Fri, 27 Mar 2020 18:58:45 +0300 Subject: [PATCH 2/8] update --- .../EntityFrameworkCore/EfCoreAuditLogRepository.cs | 2 +- .../AuditLogging/EntityFrameworkCore/IAuditLoggingDbContext.cs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs index ece526d869..b59186c923 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs @@ -186,7 +186,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore string entityTypeFullName = null, bool includeDetails = false) { - return DbContext.EntityChanges.AsNoTracking().IncludeDetails(includeDetails) + return DbContext.Set().AsNoTracking().IncludeDetails(includeDetails) .WhereIf(auditLogId.HasValue, e => e.AuditLogId == auditLogId) .WhereIf(startTime.HasValue, e => e.ChangeTime >= startTime) .WhereIf(endTime.HasValue, e => e.ChangeTime <= endTime) diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/IAuditLoggingDbContext.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/IAuditLoggingDbContext.cs index a74c20bd68..684c5fc55f 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/IAuditLoggingDbContext.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/IAuditLoggingDbContext.cs @@ -8,7 +8,5 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore public interface IAuditLoggingDbContext : IEfCoreDbContext { DbSet AuditLogs { get; set; } - - DbSet EntityChanges { get; set; } } } \ No newline at end of file From 4e6fe6c61f86f5272b40e72309fad9fe68c6c76e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20=C3=87otur?= Date: Fri, 27 Mar 2020 22:49:45 +0300 Subject: [PATCH 3/8] Update MongoAuditLogRepository.cs --- .../MongoDB/MongoAuditLogRepository.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs index a813ada669..d2e002fbbe 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs @@ -155,9 +155,11 @@ namespace Volo.Abp.AuditLogging.MongoDB { var query = GetEntityChangeListQuery(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, includeDetails); - return await query.OrderBy(sorting ?? "changeTime desc").As>() - .PageBy>(skipCount, maxResultCount) + var auditLogs = await query.OrderBy(sorting ?? "changeTime desc").As>() + .PageBy>(skipCount, maxResultCount) .ToListAsync(GetCancellationToken(cancellationToken)); + + return auditLogs.SelectMany(x => x.EntityChanges).ToList(); } public virtual async Task GetEntityChangeCountAsync( @@ -170,13 +172,13 @@ namespace Volo.Abp.AuditLogging.MongoDB CancellationToken cancellationToken = default) { var query = GetEntityChangeListQuery(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName); - var count = await query.As>() + var count = await query.As>() .LongCountAsync(GetCancellationToken(cancellationToken)); return count; } - protected virtual IQueryable GetEntityChangeListQuery( + protected virtual IQueryable GetEntityChangeListQuery( Guid? auditLogId = null, DateTime? startTime = null, DateTime? endTime = null, @@ -185,16 +187,14 @@ namespace Volo.Abp.AuditLogging.MongoDB string entityTypeFullName = null, bool includeDetails = false) { - return null; - // TODO: Learn How to? return GetMongoQueryable() - .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 == entityTypeFullName); + .WhereIf(auditLogId.HasValue, e => e.Id == auditLogId) + .WhereIf(startTime.HasValue, e => e.EntityChanges.Any(ec => ec.ChangeTime >= startTime)) + .WhereIf(endTime.HasValue, e => e.EntityChanges.Any(ec => ec.ChangeTime >= endTime)) + .WhereIf(changeType.HasValue, e => e.EntityChanges.Any(ec => ec.ChangeType >= changeType)) + .WhereIf(!string.IsNullOrWhiteSpace(entityId), e => e.EntityChanges.Any(ec => ec.EntityId == entityId)) + .WhereIf(!string.IsNullOrWhiteSpace(entityTypeFullName), + e => e.EntityChanges.Any(ec => ec.EntityTypeFullName == entityTypeFullName)); } } } From b8d0c34869404a51eae14502f5932dac4f67dbf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20=C3=87otur?= Date: Sat, 28 Mar 2020 00:04:17 +0300 Subject: [PATCH 4/8] implemented --- .../MongoDB/MongoAuditLogRepository.cs | 58 +++- .../AuditLogging/AuditLogRepository_Tests.cs | 325 ++++++++++++++++++ 2 files changed, 377 insertions(+), 6 deletions(-) diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs index d2e002fbbe..8aeb23fa51 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs @@ -153,13 +153,18 @@ namespace Volo.Abp.AuditLogging.MongoDB bool includeDetails = false, CancellationToken cancellationToken = default) { - var query = GetEntityChangeListQuery(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, includeDetails); + var query = GetEntityChangeListQuery(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName); - var auditLogs = await query.OrderBy(sorting ?? "changeTime desc").As>() + var auditLogs = await query.As>() .PageBy>(skipCount, maxResultCount) .ToListAsync(GetCancellationToken(cancellationToken)); + + // TODO: Improve this specification - return auditLogs.SelectMany(x => x.EntityChanges).ToList(); + return auditLogs + .SelectMany(x => x.EntityChanges.Where(y => + IsSatisfiedBySpecification(y, auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName))) + .AsQueryable().OrderBy(sorting ?? "changeTime desc").ToList(); } public virtual async Task GetEntityChangeCountAsync( @@ -184,17 +189,58 @@ namespace Volo.Abp.AuditLogging.MongoDB DateTime? endTime = null, EntityChangeType? changeType = null, string entityId = null, - string entityTypeFullName = null, - bool includeDetails = false) + string entityTypeFullName = null) { return GetMongoQueryable() .WhereIf(auditLogId.HasValue, e => e.Id == auditLogId) .WhereIf(startTime.HasValue, e => e.EntityChanges.Any(ec => ec.ChangeTime >= startTime)) .WhereIf(endTime.HasValue, e => e.EntityChanges.Any(ec => ec.ChangeTime >= endTime)) - .WhereIf(changeType.HasValue, e => e.EntityChanges.Any(ec => ec.ChangeType >= changeType)) + .WhereIf(changeType.HasValue, e => e.EntityChanges.Any(ec => ec.ChangeType == changeType)) .WhereIf(!string.IsNullOrWhiteSpace(entityId), e => e.EntityChanges.Any(ec => ec.EntityId == entityId)) .WhereIf(!string.IsNullOrWhiteSpace(entityTypeFullName), e => e.EntityChanges.Any(ec => ec.EntityTypeFullName == entityTypeFullName)); } + + protected virtual bool IsSatisfiedBySpecification( + EntityChange entityChange, + Guid? auditLogId = null, + DateTime? startTime = null, + DateTime? endTime = null, + EntityChangeType? changeType = null, + string entityId = null, + string entityTypeFullName = null) + { + if (auditLogId != null && auditLogId != entityChange.AuditLogId) + { + return false; + } + + if (startTime != null && startTime.Value >= entityChange.ChangeTime) + { + return false; + } + + if (endTime != null && endTime.Value <= entityChange.ChangeTime) + { + return false; + } + + if (changeType != null && changeType != entityChange.ChangeType) + { + return false; + } + + if (entityId != null && entityId != entityChange.EntityId) + { + return false; + } + + if (entityTypeFullName != null && entityTypeFullName != entityChange.EntityTypeFullName) + { + return false; + } + + return true; + } } } diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditLogRepository_Tests.cs b/modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditLogRepository_Tests.cs index f88c10c079..3b04b78234 100644 --- a/modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditLogRepository_Tests.cs +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditLogRepository_Tests.cs @@ -333,5 +333,330 @@ namespace Volo.Abp.AuditLogging results.Count.ShouldBe(1); results.Values.First().ShouldBe(50); // (45 + 55) / 2 } + + [Fact] + public async Task GetEntityChangeListAsync() + { + // Arrange + var userId = new Guid("4456fb0d-74cc-4807-9eee-23e551e6cb06"); + var userId2 = new Guid("4456fb0d-74cc-4807-9eee-23e551e6cb06"); + var ipAddress = "153.1.7.61"; + var firstComment = "first Comment"; + + var log1 = new AuditLogInfo + { + UserId = userId, + ImpersonatorUserId = Guid.NewGuid(), + ImpersonatorTenantId = Guid.NewGuid(), + ExecutionTime = DateTime.Today, + ExecutionDuration = 42, + ClientIpAddress = ipAddress, + ClientName = "MyDesktop", + BrowserInfo = "Chrome", + Comments = new List { firstComment, "Second Comment" }, + UserName = "Douglas", + EntityChanges = { + new EntityChangeInfo + { + EntityId = Guid.NewGuid().ToString(), + EntityTypeFullName = "Volo.Abp.AuditLogging.TestEntity_Deleted", + ChangeType = EntityChangeType.Deleted, + ChangeTime = DateTime.Now, + PropertyChanges = new List + { + new EntityPropertyChangeInfo + { + PropertyTypeFullName = typeof(string).FullName, + PropertyName = "Name", + NewValue = "New value", + OriginalValue = null + } + } + }, + new EntityChangeInfo + { + EntityId = Guid.NewGuid().ToString(), + EntityTypeFullName = "Volo.Abp.AuditLogging.TestEntity_Created", + ChangeType = EntityChangeType.Created, + ChangeTime = DateTime.Now, + PropertyChanges = new List + { + new EntityPropertyChangeInfo + { + PropertyTypeFullName = typeof(string).FullName, + PropertyName = "Name", + NewValue = "New value", + OriginalValue = null + } + } + } + + } + }; + + var log2 = new AuditLogInfo + { + UserId = userId2, + ImpersonatorUserId = Guid.NewGuid(), + ImpersonatorTenantId = Guid.NewGuid(), + ExecutionTime = DateTime.Today, + ExecutionDuration = 42, + ClientIpAddress = ipAddress, + ClientName = "MyDesktop", + BrowserInfo = "Chrome", + Comments = new List { firstComment, "Second Comment" }, + HttpStatusCode = (int?)HttpStatusCode.BadGateway, + EntityChanges = { + new EntityChangeInfo + { + EntityId = Guid.NewGuid().ToString(), + EntityTypeFullName = "Volo.Abp.AuditLogging.TestEntity_Updated", + ChangeType = EntityChangeType.Updated, + ChangeTime = DateTime.Now, + PropertyChanges = new List + { + new EntityPropertyChangeInfo + { + PropertyTypeFullName = typeof(string).FullName, + PropertyName = "Name", + NewValue = "New value", + OriginalValue = null + } + } + } + } + }; + + await AuditLogRepository.InsertAsync(new AuditLog(GuidGenerator, log1)); + await AuditLogRepository.InsertAsync(new AuditLog(GuidGenerator, log2)); + + //Assert + var logs = await AuditLogRepository.GetEntityChangeListAsync(); + logs.ShouldNotBeNull(); + logs.Count.ShouldBe(3); + + logs.Single(x => x.ChangeType == EntityChangeType.Created).ShouldNotBeNull(); + logs.Single(x => x.ChangeType == EntityChangeType.Deleted).ShouldNotBeNull(); + logs.Single(x => x.ChangeType == EntityChangeType.Updated).ShouldNotBeNull(); + } + + [Fact] + public async Task GetOrderedEntityChangeListAsync() + { + // Arrange + var userId = new Guid("4456fb0d-74cc-4807-9eee-23e551e6cb06"); + var userId2 = new Guid("4456fb0d-74cc-4807-9eee-23e551e6cb06"); + var ipAddress = "153.1.7.61"; + var firstComment = "first Comment"; + + var deletedEntityChangeTime = new DateTime(2000, 05, 05, 05, 05, 05); + var createdEntityChangeTime = new DateTime(2005, 05, 05, 05, 05, 05); + var updatedEntityChangeTime = new DateTime(2010, 05, 05, 05, 05, 05); + + var log1 = new AuditLogInfo + { + UserId = userId, + ImpersonatorUserId = Guid.NewGuid(), + ImpersonatorTenantId = Guid.NewGuid(), + ExecutionTime = DateTime.Today, + ExecutionDuration = 42, + ClientIpAddress = ipAddress, + ClientName = "MyDesktop", + BrowserInfo = "Chrome", + Comments = new List { firstComment, "Second Comment" }, + UserName = "Douglas", + EntityChanges = { + new EntityChangeInfo + { + EntityId = Guid.NewGuid().ToString(), + EntityTypeFullName = "Volo.Abp.AuditLogging.TestEntity_Deleted", + ChangeType = EntityChangeType.Deleted, + ChangeTime = deletedEntityChangeTime, + PropertyChanges = new List + { + new EntityPropertyChangeInfo + { + PropertyTypeFullName = typeof(string).FullName, + PropertyName = "Name", + NewValue = "New value", + OriginalValue = null + } + } + }, + new EntityChangeInfo + { + EntityId = Guid.NewGuid().ToString(), + EntityTypeFullName = "Volo.Abp.AuditLogging.TestEntity_Created", + ChangeType = EntityChangeType.Created, + ChangeTime = createdEntityChangeTime, + PropertyChanges = new List + { + new EntityPropertyChangeInfo + { + PropertyTypeFullName = typeof(string).FullName, + PropertyName = "Name", + NewValue = "New value", + OriginalValue = null + } + } + } + + } + }; + + var log2 = new AuditLogInfo + { + UserId = userId2, + ImpersonatorUserId = Guid.NewGuid(), + ImpersonatorTenantId = Guid.NewGuid(), + ExecutionTime = DateTime.Today, + ExecutionDuration = 42, + ClientIpAddress = ipAddress, + ClientName = "MyDesktop", + BrowserInfo = "Chrome", + Comments = new List { firstComment, "Second Comment" }, + HttpStatusCode = (int?)HttpStatusCode.BadGateway, + EntityChanges = { + new EntityChangeInfo + { + EntityId = Guid.NewGuid().ToString(), + EntityTypeFullName = "Volo.Abp.AuditLogging.TestEntity_Updated", + ChangeType = EntityChangeType.Updated, + ChangeTime = updatedEntityChangeTime, + PropertyChanges = new List + { + new EntityPropertyChangeInfo + { + PropertyTypeFullName = typeof(string).FullName, + PropertyName = "Name", + NewValue = "New value", + OriginalValue = null + } + } + } + } + }; + + await AuditLogRepository.InsertAsync(new AuditLog(GuidGenerator, log1)); + await AuditLogRepository.InsertAsync(new AuditLog(GuidGenerator, log2)); + + //Assert + var logs = await AuditLogRepository.GetEntityChangeListAsync(); + logs.ShouldNotBeNull(); + logs.Count.ShouldBe(3); + + logs.First().EntityTypeFullName.ShouldBe("Volo.Abp.AuditLogging.TestEntity_Updated"); + logs.Last().EntityTypeFullName.ShouldBe("Volo.Abp.AuditLogging.TestEntity_Deleted"); + + var logsReversed = await AuditLogRepository.GetEntityChangeListAsync("changeTime asc"); + + logsReversed.First().EntityTypeFullName.ShouldBe("Volo.Abp.AuditLogging.TestEntity_Deleted"); + logsReversed.Last().EntityTypeFullName.ShouldBe("Volo.Abp.AuditLogging.TestEntity_Updated"); + } + + [Fact] + public async Task GetSpecifiedEntityChangeListAsync() + { + // Arrange + var userId = new Guid("4456fb0d-74cc-4807-9eee-23e551e6cb06"); + var userId2 = new Guid("4456fb0d-74cc-4807-9eee-23e551e6cb06"); + var ipAddress = "153.1.7.61"; + var firstComment = "first Comment"; + + var deletedEntityChangeTime = new DateTime(2000, 05, 05, 05, 05, 05); + var createdEntityChangeTime = new DateTime(2005, 05, 05, 05, 05, 05); + var updatedEntityChangeTime = new DateTime(2010, 05, 05, 05, 05, 05); + + var log1 = new AuditLogInfo + { + UserId = userId, + ImpersonatorUserId = Guid.NewGuid(), + ImpersonatorTenantId = Guid.NewGuid(), + ExecutionTime = DateTime.Today, + ExecutionDuration = 42, + ClientIpAddress = ipAddress, + ClientName = "MyDesktop", + BrowserInfo = "Chrome", + Comments = new List { firstComment, "Second Comment" }, + UserName = "Douglas", + EntityChanges = { + new EntityChangeInfo + { + EntityId = Guid.NewGuid().ToString(), + EntityTypeFullName = "Volo.Abp.AuditLogging.TestEntity_Deleted", + ChangeType = EntityChangeType.Deleted, + ChangeTime = deletedEntityChangeTime, + PropertyChanges = new List + { + new EntityPropertyChangeInfo + { + PropertyTypeFullName = typeof(string).FullName, + PropertyName = "Name", + NewValue = "New value", + OriginalValue = null + } + } + }, + new EntityChangeInfo + { + EntityId = Guid.NewGuid().ToString(), + EntityTypeFullName = "Volo.Abp.AuditLogging.TestEntity_Created", + ChangeType = EntityChangeType.Created, + ChangeTime = createdEntityChangeTime, + PropertyChanges = new List + { + new EntityPropertyChangeInfo + { + PropertyTypeFullName = typeof(string).FullName, + PropertyName = "Name", + NewValue = "New value", + OriginalValue = null + } + } + } + } + }; + + var log2 = new AuditLogInfo + { + UserId = userId2, + ImpersonatorUserId = Guid.NewGuid(), + ImpersonatorTenantId = Guid.NewGuid(), + ExecutionTime = DateTime.Today, + ExecutionDuration = 42, + ClientIpAddress = ipAddress, + ClientName = "MyDesktop", + BrowserInfo = "Chrome", + Comments = new List { firstComment, "Second Comment" }, + HttpStatusCode = (int?)HttpStatusCode.BadGateway, + EntityChanges = { + new EntityChangeInfo + { + EntityId = Guid.NewGuid().ToString(), + EntityTypeFullName = "Volo.Abp.AuditLogging.TestEntity_Updated", + ChangeType = EntityChangeType.Updated, + ChangeTime = updatedEntityChangeTime, + PropertyChanges = new List + { + new EntityPropertyChangeInfo + { + PropertyTypeFullName = typeof(string).FullName, + PropertyName = "Name", + NewValue = "New value", + OriginalValue = null + } + } + } + } + }; + + await AuditLogRepository.InsertAsync(new AuditLog(GuidGenerator, log1)); + await AuditLogRepository.InsertAsync(new AuditLog(GuidGenerator, log2)); + + //Assert + var logs = await AuditLogRepository.GetEntityChangeListAsync(changeType: EntityChangeType.Created); + logs.ShouldNotBeNull(); + logs.Count.ShouldBe(1); + } } } From 5255a61986f73699cf39c7786fb87c410d45f847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20=C3=87otur?= Date: Sat, 28 Mar 2020 22:22:37 +0300 Subject: [PATCH 5/8] Update MongoAuditLogRepository.cs --- .../Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs index 8aeb23fa51..9ab6064484 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs @@ -192,6 +192,7 @@ namespace Volo.Abp.AuditLogging.MongoDB string entityTypeFullName = null) { return GetMongoQueryable() + .Where(x => x.EntityChanges != null) .WhereIf(auditLogId.HasValue, e => e.Id == auditLogId) .WhereIf(startTime.HasValue, e => e.EntityChanges.Any(ec => ec.ChangeTime >= startTime)) .WhereIf(endTime.HasValue, e => e.EntityChanges.Any(ec => ec.ChangeTime >= endTime)) From 21e82b9e8468c385a7b6058efbf2af0215d66bfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20=C3=87otur?= Date: Mon, 30 Mar 2020 00:09:54 +0300 Subject: [PATCH 6/8] Update MongoAuditLogRepository.cs --- .../Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs index 9ab6064484..8705e398dd 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs @@ -163,7 +163,7 @@ namespace Volo.Abp.AuditLogging.MongoDB return auditLogs .SelectMany(x => x.EntityChanges.Where(y => - IsSatisfiedBySpecification(y, auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName))) + IsSatisfiedEntityChange(y, auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName))) .AsQueryable().OrderBy(sorting ?? "changeTime desc").ToList(); } @@ -202,7 +202,7 @@ namespace Volo.Abp.AuditLogging.MongoDB e => e.EntityChanges.Any(ec => ec.EntityTypeFullName == entityTypeFullName)); } - protected virtual bool IsSatisfiedBySpecification( + protected virtual bool IsSatisfiedEntityChange( EntityChange entityChange, Guid? auditLogId = null, DateTime? startTime = null, From 237290a301a91daac7f89a637b60d09f3572e4bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20=C3=87otur?= Date: Mon, 30 Mar 2020 00:12:48 +0300 Subject: [PATCH 7/8] Update AuditLogRepository_Tests.cs --- .../AuditLogging/AuditLogRepository_Tests.cs | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditLogRepository_Tests.cs b/modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditLogRepository_Tests.cs index 3b04b78234..7acf357e3b 100644 --- a/modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditLogRepository_Tests.cs +++ b/modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditLogRepository_Tests.cs @@ -431,13 +431,13 @@ namespace Volo.Abp.AuditLogging await AuditLogRepository.InsertAsync(new AuditLog(GuidGenerator, log2)); //Assert - var logs = await AuditLogRepository.GetEntityChangeListAsync(); - logs.ShouldNotBeNull(); - logs.Count.ShouldBe(3); + var entityChanges = await AuditLogRepository.GetEntityChangeListAsync(); + entityChanges.ShouldNotBeNull(); + entityChanges.Count.ShouldBe(3); - logs.Single(x => x.ChangeType == EntityChangeType.Created).ShouldNotBeNull(); - logs.Single(x => x.ChangeType == EntityChangeType.Deleted).ShouldNotBeNull(); - logs.Single(x => x.ChangeType == EntityChangeType.Updated).ShouldNotBeNull(); + entityChanges.Single(x => x.ChangeType == EntityChangeType.Created).ShouldNotBeNull(); + entityChanges.Single(x => x.ChangeType == EntityChangeType.Deleted).ShouldNotBeNull(); + entityChanges.Single(x => x.ChangeType == EntityChangeType.Updated).ShouldNotBeNull(); } [Fact] @@ -541,17 +541,17 @@ namespace Volo.Abp.AuditLogging await AuditLogRepository.InsertAsync(new AuditLog(GuidGenerator, log2)); //Assert - var logs = await AuditLogRepository.GetEntityChangeListAsync(); - logs.ShouldNotBeNull(); - logs.Count.ShouldBe(3); + var entityChangesDesc = await AuditLogRepository.GetEntityChangeListAsync(); + entityChangesDesc.ShouldNotBeNull(); + entityChangesDesc.Count.ShouldBe(3); - logs.First().EntityTypeFullName.ShouldBe("Volo.Abp.AuditLogging.TestEntity_Updated"); - logs.Last().EntityTypeFullName.ShouldBe("Volo.Abp.AuditLogging.TestEntity_Deleted"); + entityChangesDesc.First().EntityTypeFullName.ShouldBe("Volo.Abp.AuditLogging.TestEntity_Updated"); + entityChangesDesc.Last().EntityTypeFullName.ShouldBe("Volo.Abp.AuditLogging.TestEntity_Deleted"); - var logsReversed = await AuditLogRepository.GetEntityChangeListAsync("changeTime asc"); + var entityChangesAsc = await AuditLogRepository.GetEntityChangeListAsync("changeTime asc"); - logsReversed.First().EntityTypeFullName.ShouldBe("Volo.Abp.AuditLogging.TestEntity_Deleted"); - logsReversed.Last().EntityTypeFullName.ShouldBe("Volo.Abp.AuditLogging.TestEntity_Updated"); + entityChangesAsc.First().EntityTypeFullName.ShouldBe("Volo.Abp.AuditLogging.TestEntity_Deleted"); + entityChangesAsc.Last().EntityTypeFullName.ShouldBe("Volo.Abp.AuditLogging.TestEntity_Updated"); } [Fact] @@ -654,9 +654,9 @@ namespace Volo.Abp.AuditLogging await AuditLogRepository.InsertAsync(new AuditLog(GuidGenerator, log2)); //Assert - var logs = await AuditLogRepository.GetEntityChangeListAsync(changeType: EntityChangeType.Created); - logs.ShouldNotBeNull(); - logs.Count.ShouldBe(1); + var entityChanges = await AuditLogRepository.GetEntityChangeListAsync(changeType: EntityChangeType.Created); + entityChanges.ShouldNotBeNull(); + entityChanges.Count.ShouldBe(1); } } } From 479a79ced4b990ddecf687b272f1ed11316dfc77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20=C3=87otur?= Date: Mon, 30 Mar 2020 00:16:17 +0300 Subject: [PATCH 8/8] Update EfCoreAuditLogRepository.cs --- .../EntityFrameworkCore/EfCoreAuditLogRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs index b59186c923..2a80767cd6 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs @@ -170,7 +170,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore string entityTypeFullName = null, CancellationToken cancellationToken = default) { - var query = GetEntityChangeListQuery(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, false); + var query = GetEntityChangeListQuery(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName); var totalCount = await query.LongCountAsync(GetCancellationToken(cancellationToken));