272 lines
11 KiB
C#
272 lines
11 KiB
C#
using Marco.Pms.Model.MongoDBModels.Employees;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.Logging;
|
|
using MongoDB.Driver;
|
|
|
|
namespace Marco.Pms.Helpers.CacheHelper
|
|
{
|
|
public class EmployeeCache
|
|
{
|
|
private readonly IMongoCollection<EmployeePermissionMongoDB> _collection;
|
|
private readonly ILogger<EmployeeCache> _logger;
|
|
|
|
public EmployeeCache(IConfiguration configuration, ILogger<EmployeeCache> logger)
|
|
{
|
|
_logger = logger;
|
|
var connectionString = configuration["MongoDB:ConnectionString"];
|
|
var mongoUrl = new MongoUrl(connectionString);
|
|
var client = new MongoClient(mongoUrl); // Your MongoDB connection string
|
|
var mongoDB = client.GetDatabase(mongoUrl.DatabaseName); // Your MongoDB Database name
|
|
_collection = mongoDB.GetCollection<EmployeePermissionMongoDB>("EmployeeProfile");
|
|
}
|
|
public async Task<bool> AddApplicationRoleToCache(Guid employeeId, List<string> newRoleIds, List<string> newPermissionIds, Guid tenantId)
|
|
{
|
|
|
|
// 2. Perform database queries concurrently for better performance.
|
|
var employeeIdString = employeeId.ToString();
|
|
var tenantIdString = tenantId.ToString();
|
|
|
|
// 5. Build a single, efficient update operation.
|
|
var filter = Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.Id, employeeIdString);
|
|
filter &= Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
|
|
|
var update = Builders<EmployeePermissionMongoDB>.Update
|
|
.AddToSetEach(e => e.ApplicationRoleIds, newRoleIds)
|
|
.Set(r => r.ExpireAt, DateTime.UtcNow.Date.AddDays(1))
|
|
.Set(r => r.TenantId, tenantIdString)
|
|
.AddToSetEach(e => e.PermissionIds, newPermissionIds);
|
|
|
|
var options = new UpdateOptions { IsUpsert = true };
|
|
|
|
var result = await _collection.UpdateOneAsync(filter, update, options);
|
|
|
|
await InitializeCollectionAsync();
|
|
|
|
// 6. Return a more accurate result indicating success for both updates and upserts.
|
|
// The operation is successful if an existing document was modified OR a new one was created.
|
|
return result.IsAcknowledged && (result.ModifiedCount > 0 || result.UpsertedId != null);
|
|
}
|
|
public async Task<bool> AddProjectsToCache(Guid employeeId, List<Guid> projectIds, Guid tenantId)
|
|
{
|
|
var newprojectIds = projectIds.Select(p => p.ToString()).ToList();
|
|
var tenantIdString = tenantId.ToString();
|
|
|
|
var filter = Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.Id, employeeId.ToString());
|
|
filter &= Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
|
|
|
var update = Builders<EmployeePermissionMongoDB>.Update
|
|
.Set(r => r.ExpireAt, DateTime.UtcNow.Date.AddDays(1))
|
|
.Set(r => r.TenantId, tenantIdString)
|
|
.AddToSetEach(e => e.ProjectIds, newprojectIds);
|
|
|
|
var result = await _collection.UpdateOneAsync(filter, update, new UpdateOptions { IsUpsert = true });
|
|
if (result.MatchedCount == 0)
|
|
{
|
|
return false;
|
|
}
|
|
await InitializeCollectionAsync();
|
|
return true;
|
|
}
|
|
public async Task<List<Guid>> GetProjectsFromCache(Guid employeeId, Guid tenantId)
|
|
{
|
|
var tenantIdString = tenantId.ToString();
|
|
|
|
var filter = Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.Id, employeeId.ToString());
|
|
filter &= Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
|
|
|
var result = await _collection
|
|
.Find(filter)
|
|
.FirstOrDefaultAsync();
|
|
|
|
var projectIds = new List<Guid>();
|
|
if (result != null)
|
|
{
|
|
projectIds = result.ProjectIds.Select(Guid.Parse).ToList();
|
|
}
|
|
|
|
return projectIds;
|
|
}
|
|
public async Task<List<Guid>> GetPermissionsFromCache(Guid employeeId, Guid tenantId)
|
|
{
|
|
var tenantIdString = tenantId.ToString();
|
|
|
|
var filter = Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.Id, employeeId.ToString());
|
|
filter &= Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
|
|
|
var result = await _collection
|
|
.Find(filter)
|
|
.FirstOrDefaultAsync();
|
|
|
|
var permissionIds = new List<Guid>();
|
|
if (result != null)
|
|
{
|
|
permissionIds = result.PermissionIds.Select(Guid.Parse).ToList();
|
|
}
|
|
|
|
return permissionIds;
|
|
}
|
|
public async Task<bool> ClearAllProjectIdsFromCache(Guid employeeId, Guid tenantId)
|
|
{
|
|
var tenantIdString = tenantId.ToString();
|
|
|
|
var filter = Builders<EmployeePermissionMongoDB>.Filter
|
|
.Eq(e => e.Id, employeeId.ToString());
|
|
filter &= Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
|
|
|
var update = Builders<EmployeePermissionMongoDB>.Update
|
|
.Set(e => e.ProjectIds, new List<string>());
|
|
|
|
var result = await _collection.UpdateOneAsync(filter, update);
|
|
|
|
if (result.ModifiedCount == 0)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
public async Task<bool> ClearAllProjectIdsByRoleIdFromCache(Guid roleId)
|
|
{
|
|
var filter = Builders<EmployeePermissionMongoDB>.Filter.AnyEq(e => e.ApplicationRoleIds, roleId.ToString());
|
|
|
|
var update = Builders<EmployeePermissionMongoDB>.Update
|
|
.Set(e => e.ProjectIds, new List<string>());
|
|
|
|
var result = await _collection.UpdateOneAsync(filter, update);
|
|
|
|
if (result.MatchedCount == 0)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
public async Task<bool> ClearAllProjectIdsByPermissionIdFromCache(Guid permissionId, Guid tenantId)
|
|
{
|
|
var tenantIdString = tenantId.ToString();
|
|
|
|
var filter = Builders<EmployeePermissionMongoDB>.Filter.AnyEq(e => e.PermissionIds, permissionId.ToString());
|
|
filter &= Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
|
|
|
var update = Builders<EmployeePermissionMongoDB>.Update.Set(e => e.ProjectIds, new List<string>());
|
|
|
|
var result = await _collection.UpdateManyAsync(filter, update).ConfigureAwait(false);
|
|
return result.IsAcknowledged && result.ModifiedCount > 0;
|
|
}
|
|
public async Task<bool> RemoveRoleIdFromCache(Guid employeeId, Guid roleId, Guid tenantId)
|
|
{
|
|
var tenantIdString = tenantId.ToString();
|
|
|
|
var filter = Builders<EmployeePermissionMongoDB>.Filter
|
|
.Eq(e => e.Id, employeeId.ToString());
|
|
filter &= Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
|
|
|
var update = Builders<EmployeePermissionMongoDB>.Update
|
|
.Pull(e => e.ApplicationRoleIds, roleId.ToString());
|
|
|
|
var result = await _collection.UpdateOneAsync(filter, update);
|
|
|
|
if (result.MatchedCount == 0)
|
|
return false;
|
|
|
|
if (result.ModifiedCount == 0)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
public async Task<bool> ClearAllPermissionIdsByEmployeeIDFromCache(Guid employeeId, Guid tenantId)
|
|
{
|
|
var tenantIdString = tenantId.ToString();
|
|
|
|
var filter = Builders<EmployeePermissionMongoDB>.Filter
|
|
.Eq(e => e.Id, employeeId.ToString());
|
|
filter &= Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
|
|
|
var update = Builders<EmployeePermissionMongoDB>.Update
|
|
.Set(e => e.PermissionIds, new List<string>());
|
|
|
|
var result = await _collection.UpdateOneAsync(filter, update);
|
|
|
|
if (result.MatchedCount == 0)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
public async Task<bool> ClearAllPermissionIdsByRoleIdFromCache(Guid roleId)
|
|
{
|
|
var filter = Builders<EmployeePermissionMongoDB>.Filter.AnyEq(e => e.ApplicationRoleIds, roleId.ToString());
|
|
|
|
var update = Builders<EmployeePermissionMongoDB>.Update
|
|
.Set(e => e.PermissionIds, new List<string>());
|
|
|
|
var result = await _collection.UpdateOneAsync(filter, update);
|
|
|
|
if (result.MatchedCount == 0)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
public async Task<bool> ClearAllEmployeesFromCache()
|
|
{
|
|
var result = await _collection.DeleteManyAsync(FilterDefinition<EmployeePermissionMongoDB>.Empty);
|
|
|
|
if (result.DeletedCount == 0)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
public async Task<bool> ClearAllEmployeesFromCacheByTenantId(Guid tenantId)
|
|
{
|
|
var tenantIdString = tenantId.ToString();
|
|
|
|
try
|
|
{
|
|
var filter = Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
|
|
|
var result = await _collection.DeleteManyAsync(filter);
|
|
|
|
if (result.DeletedCount == 0)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error occured while deleting employee profile");
|
|
return false;
|
|
}
|
|
}
|
|
public async Task<bool> ClearAllEmployeesFromCacheByEmployeeIds(List<string> employeeIds, Guid tenantId)
|
|
{
|
|
var tenantIdString = tenantId.ToString();
|
|
|
|
try
|
|
{
|
|
var filter = Builders<EmployeePermissionMongoDB>.Filter.In(x => x.Id, employeeIds);
|
|
filter &= Builders<EmployeePermissionMongoDB>.Filter.Eq(e => e.TenantId, tenantIdString);
|
|
|
|
var result = await _collection.DeleteManyAsync(filter);
|
|
|
|
if (result.DeletedCount == 0)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error occured while deleting employee profile");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// A private method to handle the one-time setup of the collection's indexes.
|
|
private async Task InitializeCollectionAsync()
|
|
{
|
|
var indexKeys = Builders<EmployeePermissionMongoDB>.IndexKeys.Ascending(x => x.ExpireAt);
|
|
var indexOptions = new CreateIndexOptions
|
|
{
|
|
ExpireAfter = TimeSpan.Zero // required for fixed expiration time
|
|
};
|
|
var indexModel = new CreateIndexModel<EmployeePermissionMongoDB>(indexKeys, indexOptions);
|
|
await _collection.Indexes.CreateOneAsync(indexModel);
|
|
}
|
|
}
|
|
}
|