dbMango/Rms.Risk.Mango/Services/MongoDbServiceFactory.cs
Alexander Shabarshov 2a7a24c9e7 Initial contribution
2025-11-03 14:43:26 +00:00

143 lines
6.1 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* dbMango
*
* Copyright 2025 Deutsche Bank AG
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using Rms.Risk.Mango.Interfaces;
using Rms.Risk.Mango.Pivot.Core;
using Rms.Risk.Mango.Pivot.Core.Models;
using Rms.Risk.Mango.Pivot.Core.MongoDb;
using Rms.Risk.Mango.Services.Audit;
using Rms.Risk.Mango.Services.Context;
namespace Rms.Risk.Mango.Services;
public class MongoDbServiceFactory : IMongoDbServiceFactory
{
private const int SessionExpirationMinutes = 30;
private const int SessionExpirationCheckMinutes = 5;
private record AuditServiceKey(string AuditDatabase, string DatabaseInstance);
private record PivotServiceKey(string Database, string DatabaseInstance);
private record AdminServiceKey (string Database, string DatabaseInstance, IUserSession Session);
private readonly IDatabaseConfigurationService _databases;
private readonly IOptions<DbMangoSettings> _settings;
private IAuditService? _inOracle;
private readonly ExpiringConcurrentDictionary<AuditServiceKey, IAuditService> _auditServices;
private readonly ExpiringConcurrentDictionary<PivotServiceKey, IPivotTableDataSource> _pivotServices;
private readonly ExpiringConcurrentDictionary<AdminServiceKey, IMongoDbDatabaseAdminService> _adminServices;
private readonly IDbMangoPlugin? _dbMangoPlugin;
public MongoDbServiceFactory(IDatabaseConfigurationService databases, IOptions<DbMangoSettings> settings, IDbMangoPlugin? dbMangoPlugin = null)
{
_databases = databases;
_settings = settings;
_dbMangoPlugin = dbMangoPlugin;
_auditServices = new (
InternalCreateAudit,
TimeSpan.FromMinutes(SessionExpirationMinutes),
TimeSpan.FromMinutes(SessionExpirationCheckMinutes),
false
);
_adminServices = new (
InternalCreateAdmin,
TimeSpan.FromMinutes(SessionExpirationMinutes),
TimeSpan.FromMinutes(SessionExpirationCheckMinutes),
false
);
_pivotServices = new (
InternalCreatePivot,
TimeSpan.FromMinutes(SessionExpirationMinutes),
TimeSpan.FromMinutes(SessionExpirationCheckMinutes),
false
);
}
public static MongoDbConfigRecord GetConfig(MongoDbConfigRecord config, string databaseInstance)
{
if (string.IsNullOrWhiteSpace(config.MongoDbDatabase) && string.IsNullOrWhiteSpace(databaseInstance))
throw new ApplicationException("MongoDB database name is not provided and it's not set in the configuration either.");
if (!string.IsNullOrWhiteSpace(databaseInstance))
{
var copy = config.Clone();
copy.MongoDbDatabase = databaseInstance;
return copy;
}
return config;
}
public IPivotTableDataSource CreatePivot(string database, string databaseInstance)
=> _pivotServices.GetOrAdd(new(database,databaseInstance));
public IMongoDbDatabaseAdminService CreateAdmin(string database, IUserSession session, string databaseInstance)
=> _adminServices.GetOrAdd(new(database, databaseInstance, session));
public IMongoDbService<BsonDocument> Create(string database, string collection, string databaseInstance)
=> new BsonMongoDbService(GetConfig(_databases.Databases[database].Config, databaseInstance), _settings.Value.Settings, collection, databaseInstance);
public IMongoDbDatabaseAdminService CreateAdmin(MongoDbConfigRecord config, string auditDatabase, IUserSession session, string databaseInstance)
=> new AuditedMongoDbDatabaseAdminService(
config,
_settings.Value.Settings,
session,
CreateAudit(auditDatabase, string.IsNullOrWhiteSpace(config.MongoDbDatabase) ? databaseInstance : config.MongoDbDatabase), databaseInstance);
public IAuditService CreateAudit(string auditDatabase, string databaseInstance)
=> _auditServices.GetOrAdd(new(auditDatabase,databaseInstance));
#region Internal Methods
private IPivotTableDataSource InternalCreatePivot(PivotServiceKey key) =>
new MongoDbOnlyProxyDataSource(new MongoDbDataSource(
GetConfig(_databases.Databases[key.Database].Config, key.DatabaseInstance),
_settings.Value.Settings,
key.DatabaseInstance
));
private IMongoDbDatabaseAdminService InternalCreateAdmin(AdminServiceKey key)
=> new AuditedMongoDbDatabaseAdminService(
GetConfig(_databases.Databases[key.Database].Config, key.DatabaseInstance),
_settings.Value.Settings,
key.Session,
CreateAudit(key.Database, key.DatabaseInstance), key.DatabaseInstance);
private IAuditService InternalCreateAudit(AuditServiceKey key)
{
var inMongo = new AuditService(
GetConfig(_databases.Databases[key.AuditDatabase].Config, key.DatabaseInstance),
_settings.Value.Settings,
_settings.Value.AuditExpireDays
);
_inOracle ??= _settings.Value.AuditLogsInOracle && _dbMangoPlugin != null
? _dbMangoPlugin.CreateSecureAuditService(_settings.Value.OracleConnectionSettings)
: null;
return _inOracle == null
? inMongo
: new ChainedAuditService([_inOracle, inMongo]);
}
#endregion
}