|
|
|
@ -37,7 +37,7 @@ public abstract class DatabaseMongoDbMigrationEventHandler<TDbContext> : Databas |
|
|
|
IUnitOfWorkManager unitOfWorkManager, |
|
|
|
ITenantStore tenantStore, |
|
|
|
IDistributedEventBus distributedEventBus, |
|
|
|
string databaseName, |
|
|
|
string databaseName, |
|
|
|
IServiceProvider serviceProvider, |
|
|
|
IAbpDistributedLock distributedLockProvider |
|
|
|
) |
|
|
|
@ -57,62 +57,46 @@ public abstract class DatabaseMongoDbMigrationEventHandler<TDbContext> : Databas |
|
|
|
/// Apply pending EF Core schema migrations to the database.
|
|
|
|
/// Returns true if any migration has applied.
|
|
|
|
/// </summary>
|
|
|
|
protected virtual async Task<bool> MigrateDatabaseSchemaAsync(Guid? tenantId) |
|
|
|
protected virtual async Task<bool> MigrateDatabaseSchemaAsync() |
|
|
|
{ |
|
|
|
var result = false; |
|
|
|
|
|
|
|
using (CurrentTenant.Change(tenantId)) |
|
|
|
using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false)) |
|
|
|
{ |
|
|
|
using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false)) |
|
|
|
async Task<bool> MigrateDatabaseSchemaWithDbContextAsync() |
|
|
|
{ |
|
|
|
async Task<bool> MigrateDatabaseSchemaWithDbContextAsync() |
|
|
|
{ |
|
|
|
var dbContexts = ServiceProvider.GetServices<IAbpMongoDbContext>(); |
|
|
|
var connectionStringResolver = ServiceProvider.GetRequiredService<IConnectionStringResolver>(); |
|
|
|
var dbContexts = ServiceProvider.GetServices<IAbpMongoDbContext>(); |
|
|
|
var connectionStringResolver = ServiceProvider.GetRequiredService<IConnectionStringResolver>(); |
|
|
|
|
|
|
|
foreach (var dbContext in dbContexts) |
|
|
|
foreach (var dbContext in dbContexts) |
|
|
|
{ |
|
|
|
var connectionString = |
|
|
|
await connectionStringResolver.ResolveAsync( |
|
|
|
ConnectionStringNameAttribute.GetConnStringName(dbContext.GetType())); |
|
|
|
if (connectionString.IsNullOrWhiteSpace()) |
|
|
|
{ |
|
|
|
var connectionString = |
|
|
|
await connectionStringResolver.ResolveAsync( |
|
|
|
ConnectionStringNameAttribute.GetConnStringName(dbContext.GetType())); |
|
|
|
if (connectionString.IsNullOrWhiteSpace()) |
|
|
|
{ |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
var mongoUrl = new MongoUrl(connectionString); |
|
|
|
var databaseName = mongoUrl.DatabaseName; |
|
|
|
var client = new MongoClient(mongoUrl); |
|
|
|
|
|
|
|
if (databaseName.IsNullOrWhiteSpace()) |
|
|
|
{ |
|
|
|
databaseName = ConnectionStringNameAttribute.GetConnStringName(dbContext.GetType()); |
|
|
|
} |
|
|
|
|
|
|
|
(dbContext as AbpMongoDbContext)?.InitializeCollections(client.GetDatabase(databaseName)); |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
var mongoUrl = new MongoUrl(connectionString); |
|
|
|
var databaseName = mongoUrl.DatabaseName; |
|
|
|
var client = new MongoClient(mongoUrl); |
|
|
|
|
|
|
|
if (tenantId == null) |
|
|
|
{ |
|
|
|
//Migrating the host database
|
|
|
|
result = await MigrateDatabaseSchemaWithDbContextAsync(); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
var tenantConfiguration = await TenantStore.FindAsync(tenantId.Value); |
|
|
|
if (!tenantConfiguration.ConnectionStrings.Default.IsNullOrWhiteSpace() || |
|
|
|
!tenantConfiguration.ConnectionStrings.GetOrDefault(DatabaseName).IsNullOrWhiteSpace()) |
|
|
|
if (databaseName.IsNullOrWhiteSpace()) |
|
|
|
{ |
|
|
|
//Migrating the tenant database (only if tenant has a separate database)
|
|
|
|
result = await MigrateDatabaseSchemaWithDbContextAsync(); |
|
|
|
databaseName = ConnectionStringNameAttribute.GetConnStringName(dbContext.GetType()); |
|
|
|
} |
|
|
|
|
|
|
|
(dbContext as AbpMongoDbContext)?.InitializeCollections(client.GetDatabase(databaseName)); |
|
|
|
} |
|
|
|
|
|
|
|
await uow.CompleteAsync(); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
//Migrating the host database
|
|
|
|
result = await MigrateDatabaseSchemaWithDbContextAsync(); |
|
|
|
|
|
|
|
await uow.CompleteAsync(); |
|
|
|
} |
|
|
|
|
|
|
|
return result; |
|
|
|
@ -140,50 +124,6 @@ public abstract class DatabaseMongoDbMigrationEventHandler<TDbContext> : Databas |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected virtual async Task HandleErrorTenantCreatedAsync( |
|
|
|
TenantCreatedEto eventData, |
|
|
|
Exception exception) |
|
|
|
{ |
|
|
|
var tryCount = IncrementEventTryCount(eventData); |
|
|
|
if (tryCount <= MaxEventTryCount) |
|
|
|
{ |
|
|
|
Logger.LogWarning( |
|
|
|
$"Could not perform tenant created event. Re-queueing the operation. TenantId = {eventData.Id}, TenantName = {eventData.Name}."); |
|
|
|
Logger.LogException(exception, LogLevel.Warning); |
|
|
|
|
|
|
|
await Task.Delay(RandomHelper.GetRandom(5000, 15000)); |
|
|
|
await DistributedEventBus.PublishAsync(eventData); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
Logger.LogError( |
|
|
|
$"Could not perform tenant created event. Canceling the operation. TenantId = {eventData.Id}, TenantName = {eventData.Name}."); |
|
|
|
Logger.LogException(exception); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected virtual async Task HandleErrorTenantConnectionStringUpdatedAsync( |
|
|
|
TenantConnectionStringUpdatedEto eventData, |
|
|
|
Exception exception) |
|
|
|
{ |
|
|
|
var tryCount = IncrementEventTryCount(eventData); |
|
|
|
if (tryCount <= MaxEventTryCount) |
|
|
|
{ |
|
|
|
Logger.LogWarning( |
|
|
|
$"Could not perform tenant connection string updated event. Re-queueing the operation. TenantId = {eventData.Id}, TenantName = {eventData.Name}."); |
|
|
|
Logger.LogException(exception, LogLevel.Warning); |
|
|
|
|
|
|
|
await Task.Delay(RandomHelper.GetRandom(5000, 15000)); |
|
|
|
await DistributedEventBus.PublishAsync(eventData); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
Logger.LogError( |
|
|
|
$"Could not perform tenant connection string updated event. Canceling the operation. TenantId = {eventData.Id}, TenantName = {eventData.Name}."); |
|
|
|
Logger.LogException(exception); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private static int GetEventTryCount(EtoBase eventData) |
|
|
|
{ |
|
|
|
var tryCountAsString = eventData.Properties.GetOrDefault(TryCountPropertyName); |
|
|
|
|