using Marco.Pms.Model.MongoDBModels; using Marco.Pms.Model.MongoDBModels.Utility; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using MongoDB.Bson; using MongoDB.Driver; using System.Collections; namespace Marco.Pms.Helpers.Utility { public class UtilityMongoDBHelper { private readonly IMongoDatabase _mongoDatabase; private readonly IConfiguration _configuration; private readonly ILogger _logger; public UtilityMongoDBHelper(IConfiguration configuration, ILogger logger) { _configuration = configuration; _logger = logger; var connectionString = configuration["MongoDB:ModificationConnectionString"]; var mongoUrl = new MongoUrl(connectionString); var client = new MongoClient(mongoUrl); // Your MongoDB connection string _mongoDatabase = client.GetDatabase(mongoUrl.DatabaseName); // Your MongoDB Database name } #region =================================================================== Update Log Helper Functions =================================================================== public async Task PushToUpdateLogsAsync(UpdateLogsObject oldObject, string collectionName) { try { var collection = _mongoDatabase.GetCollection(collectionName); await collection.InsertOneAsync(oldObject); } catch (Exception ex) { _logger.LogError(ex, "Exception occured while saving object of update logs in collection: {Collection}", collectionName); } } public async Task PushListToUpdateLogsAsync(List oldObjects, string collectionName) { try { var collection = _mongoDatabase.GetCollection(collectionName); if (oldObjects.Any()) { await collection.InsertManyAsync(oldObjects); } } catch (Exception ex) { _logger.LogError(ex, "Exception occured while saving list of update logs in collection: {Collection}", collectionName); } } public async Task> GetFromUpdateLogsByEntityIdAsync(Guid entityId, string collectionName) { var collection = _mongoDatabase.GetCollection(collectionName); var filter = Builders.Filter.Eq(p => p.EntityId, entityId.ToString()); List result = await collection .Find(filter) .ToListAsync(); return result; } public async Task> GetFromUpdateLogsByUpdetedByIdAsync(Guid updatedById, string collectionName) { var collection = _mongoDatabase.GetCollection(collectionName); var filter = Builders.Filter.Eq(p => p.UpdatedById, updatedById.ToString()); List result = await collection .Find(filter) .ToListAsync(); return result; } public BsonDocument EntityToBsonDocument(object entity) { var bson = new BsonDocument(); var props = entity.GetType().GetProperties(); foreach (var prop in props) { var value = prop.GetValue(entity); if (value == null) { bson[prop.Name] = BsonNull.Value; continue; } if (value is Guid guidValue) { bson[prop.Name] = guidValue.ToString(); // store Guid as string } else if (value is string || value.GetType().IsPrimitive || value is DateTime) { bson[prop.Name] = BsonValue.Create(value); // simple types } else if (value is IEnumerable list && !(value is string)) { var array = new BsonArray(); foreach (var item in list) { array.Add(EntityToBsonDocument(item)); // recursive } bson[prop.Name] = array; } else { // nested object continue; } } return bson; } #endregion #region =================================================================== S3 deletion Helper Functions =================================================================== public async Task PushToS3DeletionAsync(List deletionObject) { var bucketName = _configuration["AWS:BucketName"]; if (bucketName != null) { deletionObject = deletionObject.Select(d => new S3DeletionObject { BucketName = bucketName, Key = d.Key, Deleted = false }).ToList(); } _logger.LogInformation("Delection object for bucket {BucketName} added to mongoDB", bucketName); try { var collection = _mongoDatabase.GetCollection("S3Delection"); await collection.InsertManyAsync(deletionObject); } catch (Exception ex) { _logger.LogError(ex, "Error occured while saving delection object for S3 to MogoDB"); } _logger.LogInformation("Delection Objects added to MongoDB Successfully"); } #endregion #region =================================================================== NotificatioBody Helper Functions =================================================================== public async Task AddNotificationAsync(NotificationMongoDB notification) { try { var collection = _mongoDatabase.GetCollection("NotificatioBody"); var indexKeys = Builders.IndexKeys .Ascending(doc => doc.TenantId) .Ascending(doc => doc.Name); // Define index options with unique constraint var indexOptions = new CreateIndexOptions { Unique = true }; // Create the index model var indexModel = new CreateIndexModel(indexKeys, indexOptions); // Create the index on the collection (this operation is idempotent) collection.Indexes.CreateOne(indexModel); await collection.InsertOneAsync(notification); } catch (Exception ex) { _logger.LogError(ex, "Exception occured while adding the Notification body {NotificationName} for tenant {TenantId}", notification.Name, notification.TenantId); } } public async Task GetNotificationBodyAsync(string name, Guid tenantId) { var rootTenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26"); NotificationMongoDB? result = null; NotificationMongoDB? defaultNotification = new NotificationMongoDB { Name = "default", Title = "Error: Something Went Wrong", Body = " An unexpected error occurred. Please try again. If the problem persists, contact support", Parameters = "", TenantId = rootTenantId }; var collection = _mongoDatabase.GetCollection("NotificatioBody"); try { var filter = Builders.Filter.And( Builders.Filter.Eq(n => n.Name, name), Builders.Filter.Eq(n => n.TenantId, tenantId) ); result = await collection .Find(filter) .FirstOrDefaultAsync(); } catch (Exception ex) { _logger.LogError(ex, "Exception occured while fetching the Notification body {NotificationName} for tenant {TenantId}", name, tenantId); } if (result == null) { try { var filter = Builders.Filter.And( Builders.Filter.Eq(n => n.Name, name), Builders.Filter.Eq(n => n.TenantId, rootTenantId) ); result = await collection.Find(filter).FirstOrDefaultAsync(); } catch (Exception ex) { _logger.LogError(ex, "Exception occured while fetching the Notification body {NotificationName} for tenant {TenantId}", name, rootTenantId); return defaultNotification; } } return result; } #endregion } }