Browse Source

Merge branch 'dev' of https://github.com/abpframework/abp into feat/abp-utils

pull/3415/head
mehmet-erim 6 years ago
parent
commit
dc6b3be957
  1. 23
      modules/audit-logging/src/Volo.Abp.AuditLogging.Domain/Volo/Abp/AuditLogging/IAuditLogRepository.cs
  2. 12
      modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/AbpAuditLoggingEfCoreQueryableExtensions.cs
  3. 56
      modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs
  4. 105
      modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs
  5. 325
      modules/audit-logging/test/Volo.Abp.AuditLogging.TestBase/Volo/Abp/AuditLogging/AuditLogRepository_Tests.cs

23
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<Dictionary<DateTime, double>> GetAverageExecutionDurationPerDayAsync(
DateTime startDate,
DateTime endDate);
Task<List<EntityChange>> 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<long> GetEntityChangeCountAsync(
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string entityId = null,
string entityTypeFullName = null,
CancellationToken cancellationToken = default);
}
}

12
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<EntityChange> IncludeDetails(
this IQueryable<EntityChange> queryable,
bool include = true)
{
if (!include)
{
return queryable;
}
return queryable.Include(x => x.PropertyChanges);
}
}
}

56
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<List<EntityChange>> 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<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 = GetEntityChangeListQuery(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName);
var totalCount = await query.LongCountAsync(GetCancellationToken(cancellationToken));
return totalCount;
}
protected virtual IQueryable<EntityChange> GetEntityChangeListQuery(
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string entityId = null,
string entityTypeFullName = null,
bool includeDetails = false)
{
return DbContext.Set<EntityChange>().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);
}
}
}

105
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,109 @@ namespace Volo.Abp.AuditLogging.MongoDB
return result.ToDictionary(element => element.Day.ClearTime(), element => element.avgExecutionTime);
}
public virtual async Task<List<EntityChange>> 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);
var auditLogs = await query.As<IMongoQueryable<AuditLog>>()
.PageBy<AuditLog, IMongoQueryable<AuditLog>>(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
// TODO: Improve this specification
return auditLogs
.SelectMany(x => x.EntityChanges.Where(y =>
IsSatisfiedEntityChange(y, auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName)))
.AsQueryable().OrderBy(sorting ?? "changeTime desc").ToList();
}
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 = GetEntityChangeListQuery(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName);
var count = await query.As<IMongoQueryable<AuditLog>>()
.LongCountAsync(GetCancellationToken(cancellationToken));
return count;
}
protected virtual IQueryable<AuditLog> GetEntityChangeListQuery(
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string entityId = null,
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))
.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 IsSatisfiedEntityChange(
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;
}
}
}

325
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<string> { 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<EntityPropertyChangeInfo>
{
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<EntityPropertyChangeInfo>
{
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<string> { 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<EntityPropertyChangeInfo>
{
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 entityChanges = await AuditLogRepository.GetEntityChangeListAsync();
entityChanges.ShouldNotBeNull();
entityChanges.Count.ShouldBe(3);
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]
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<string> { 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<EntityPropertyChangeInfo>
{
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<EntityPropertyChangeInfo>
{
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<string> { 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<EntityPropertyChangeInfo>
{
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 entityChangesDesc = await AuditLogRepository.GetEntityChangeListAsync();
entityChangesDesc.ShouldNotBeNull();
entityChangesDesc.Count.ShouldBe(3);
entityChangesDesc.First().EntityTypeFullName.ShouldBe("Volo.Abp.AuditLogging.TestEntity_Updated");
entityChangesDesc.Last().EntityTypeFullName.ShouldBe("Volo.Abp.AuditLogging.TestEntity_Deleted");
var entityChangesAsc = await AuditLogRepository.GetEntityChangeListAsync("changeTime asc");
entityChangesAsc.First().EntityTypeFullName.ShouldBe("Volo.Abp.AuditLogging.TestEntity_Deleted");
entityChangesAsc.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<string> { 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<EntityPropertyChangeInfo>
{
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<EntityPropertyChangeInfo>
{
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<string> { 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<EntityPropertyChangeInfo>
{
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 entityChanges = await AuditLogRepository.GetEntityChangeListAsync(changeType: EntityChangeType.Created);
entityChanges.ShouldNotBeNull();
entityChanges.Count.ShouldBe(1);
}
}
}

Loading…
Cancel
Save