143 lines
6.1 KiB
C#
143 lines
6.1 KiB
C#
/*
|
||
* 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
|
||
} |