Browse Source

Remove distributed event bus & refactor migrations

pull/93/head
Enis Necipoglu 4 years ago
parent
commit
67b343e978
  1. 2
      services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/AdministrationServiceHttpApiHostModule.cs
  2. 49
      services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/DbMigrations/AdministrationServiceDatabaseMigrationChecker.cs
  3. 94
      services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/DbMigrations/AdministrationServiceDatabaseMigrationEventHandler.cs
  4. 2
      services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/CatalogServiceHttpApiHostModule.cs
  5. 24
      services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/DbMigrations/CatalogServiceDatabaseMigrationChecker.cs
  6. 66
      services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/DbMigrations/CatalogServiceDatabaseMigrationEventHandler.cs
  7. 6
      services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/DbMigrations/ProductServiceDataSeeder.cs
  8. 9
      services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/DbMigrations/ApplyDatabaseSeedsEto.cs
  9. 21
      services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/DbMigrations/DataSeederEventHandler.cs
  10. 17
      services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/DbMigrations/IdentityServiceDatabaseMigrationChecker.cs
  11. 90
      services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/DbMigrations/IdentityServiceDatabaseMigrationEventHandler.cs
  12. 2
      services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/IdentityServiceHttpApiHostModule.cs
  13. 5
      services/ordering/src/EShopOnAbp.OrderingService.HttpApi.Host/DbMigrations/OrderingServiceDatabaseMigrationChecker.cs
  14. 70
      services/ordering/src/EShopOnAbp.OrderingService.HttpApi.Host/DbMigrations/OrderingServiceDatabaseMigrationEventHandler.cs
  15. 2
      services/ordering/src/EShopOnAbp.OrderingService.HttpApi.Host/OrderingServiceHttpApiHostModule.cs
  16. 5
      services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/DbMigrations/PaymentServiceDatabaseMigrationChecker.cs
  17. 64
      services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/DbMigrations/PaymentServiceDatabaseMigrationEventHandler.cs
  18. 2
      services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/PaymentServiceHttpApiHostModule.cs
  19. 48
      shared/EShopOnAbp.Shared.Hosting.Microservices/DbMigrations/EfCore/PendingEfCoreMigrationsChecker.cs
  20. 75
      shared/EShopOnAbp.Shared.Hosting.Microservices/DbMigrations/MongoDb/PendingMongoDbMigrationsChecker.cs

2
services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/AdministrationServiceHttpApiHostModule.cs

@ -103,6 +103,6 @@ public class AdministrationServiceHttpApiHostModule : AbpModule
{
await context.ServiceProvider
.GetRequiredService<AdministrationServiceDatabaseMigrationChecker>()
.CheckAsync();
.CheckAndApplyDatabaseMigrations();
}
}

49
services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/DbMigrations/AdministrationServiceDatabaseMigrationChecker.cs

@ -1,8 +1,13 @@
using EShopOnAbp.AdministrationService.EntityFrameworkCore;
using System;
using EShopOnAbp.Shared.Hosting.Microservices.DbMigrations.EfCore;
using System;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.DistributedLocking;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.PermissionManagement;
using Volo.Abp.Uow;
namespace EShopOnAbp.AdministrationService.DbMigrations;
@ -10,17 +15,57 @@ namespace EShopOnAbp.AdministrationService.DbMigrations;
public class AdministrationServiceDatabaseMigrationChecker
: PendingEfCoreMigrationsChecker<AdministrationServiceDbContext>
{
private readonly IPermissionDefinitionManager _permissionDefinitionManager;
private readonly IPermissionDataSeeder _permissionDataSeeder;
public AdministrationServiceDatabaseMigrationChecker(
IUnitOfWorkManager unitOfWorkManager,
IServiceProvider serviceProvider,
ICurrentTenant currentTenant,
IDistributedEventBus distributedEventBus)
IDistributedEventBus distributedEventBus,
IAbpDistributedLock abpDistributedLock,
IPermissionDefinitionManager permissionDefinitionManager,
IPermissionDataSeeder permissionDataSeeder)
: base(
unitOfWorkManager,
serviceProvider,
currentTenant,
distributedEventBus,
abpDistributedLock,
AdministrationServiceDbProperties.ConnectionStringName)
{
_permissionDefinitionManager = permissionDefinitionManager;
_permissionDataSeeder = permissionDataSeeder;
}
public override async Task CheckAndApplyDatabaseMigrations()
{
await base.CheckAndApplyDatabaseMigrations();
await SeedDataAsync();
}
private async Task SeedDataAsync()
{
using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: true))
{
var multiTenancySide = MultiTenancySides.Host;
var permissionNames = _permissionDefinitionManager
.GetPermissions()
.Where(p => p.MultiTenancySide.HasFlag(multiTenancySide))
.Where(p => !p.Providers.Any() ||
p.Providers.Contains(RolePermissionValueProvider.ProviderName))
.Select(p => p.Name)
.ToArray();
await _permissionDataSeeder.SeedAsync(
RolePermissionValueProvider.ProviderName,
"admin",
permissionNames
);
await uow.CompleteAsync();
}
}
}

94
services/administration/src/EShopOnAbp.AdministrationService.HttpApi.Host/DbMigrations/AdministrationServiceDatabaseMigrationEventHandler.cs

@ -1,94 +0,0 @@
using EShopOnAbp.AdministrationService.EntityFrameworkCore;
using EShopOnAbp.Shared.Hosting.Microservices.DbMigrations.EfCore;
using Serilog;
using System;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Data;
using Volo.Abp.DistributedLocking;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.PermissionManagement;
using Volo.Abp.Uow;
namespace EShopOnAbp.AdministrationService.DbMigrations;
public class AdministrationServiceDatabaseMigrationEventHandler
: DatabaseEfCoreMigrationEventHandler<AdministrationServiceDbContext>,
IDistributedEventHandler<ApplyDatabaseMigrationsEto>
{
private readonly IPermissionDefinitionManager _permissionDefinitionManager;
private readonly IPermissionDataSeeder _permissionDataSeeder;
public AdministrationServiceDatabaseMigrationEventHandler(
ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager,
ITenantStore tenantStore,
IPermissionDefinitionManager permissionDefinitionManager,
IPermissionDataSeeder permissionDataSeeder,
IDistributedEventBus distributedEventBus,
IAbpDistributedLock distributedLockProvider
) : base(
currentTenant,
unitOfWorkManager,
tenantStore,
distributedEventBus,
AdministrationServiceDbProperties.ConnectionStringName,
distributedLockProvider
)
{
_permissionDefinitionManager = permissionDefinitionManager;
_permissionDataSeeder = permissionDataSeeder;
}
public async Task HandleEventAsync(ApplyDatabaseMigrationsEto eventData)
{
if (eventData.DatabaseName != DatabaseName)
{
return;
}
try
{
await using (var handle = await DistributedLockProvider.TryAcquireAsync(DatabaseName))
{
Log.Information("AdministrationService acquired lock for db migration and seeding...");
if (handle != null)
{
await MigrateDatabaseSchemaAsync();
await SeedDataAsync();
}
}
}
catch (Exception ex)
{
await HandleErrorOnApplyDatabaseMigrationAsync(eventData, ex);
}
}
private async Task SeedDataAsync()
{
using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: true))
{
var multiTenancySide = MultiTenancySides.Host;
var permissionNames = _permissionDefinitionManager
.GetPermissions()
.Where(p => p.MultiTenancySide.HasFlag(multiTenancySide))
.Where(p => !p.Providers.Any() ||
p.Providers.Contains(RolePermissionValueProvider.ProviderName))
.Select(p => p.Name)
.ToArray();
await _permissionDataSeeder.SeedAsync(
RolePermissionValueProvider.ProviderName,
"admin",
permissionNames
);
await uow.CompleteAsync();
}
}
}

2
services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/CatalogServiceHttpApiHostModule.cs

@ -125,6 +125,6 @@ public class CatalogServiceHttpApiHostModule : AbpModule
{
await context.ServiceProvider
.GetRequiredService<CatalogServiceDatabaseMigrationChecker>()
.CheckAsync();
.CheckAndApplyDatabaseMigrationsAsync();
}
}

24
services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/DbMigrations/CatalogServiceDatabaseMigrationChecker.cs

@ -1,8 +1,8 @@
using System;
using System.Threading.Tasks;
using EShopOnAbp.CatalogService.MongoDB;
using EShopOnAbp.CatalogService.MongoDB;
using EShopOnAbp.Shared.Hosting.Microservices.DbMigrations;
using Volo.Abp.EventBus.Distributed;
using System;
using Volo.Abp.Data;
using Volo.Abp.DistributedLocking;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
@ -10,27 +10,19 @@ namespace EShopOnAbp.CatalogService.DbMigrations;
public class CatalogServiceDatabaseMigrationChecker : PendingMongoDbMigrationsChecker<CatalogServiceMongoDbContext>
{
private readonly ProductServiceDataSeeder _productServiceDataSeeder;
public CatalogServiceDatabaseMigrationChecker(
IUnitOfWorkManager unitOfWorkManager,
IServiceProvider serviceProvider,
ICurrentTenant currentTenant,
IDistributedEventBus distributedEventBus,
ProductServiceDataSeeder productServiceDataSeeder)
IDataSeeder dataSeeder,
IAbpDistributedLock distributedLockProvider)
: base(
unitOfWorkManager,
serviceProvider,
currentTenant,
distributedEventBus,
dataSeeder,
distributedLockProvider,
CatalogServiceDbProperties.ConnectionStringName)
{
_productServiceDataSeeder = productServiceDataSeeder;
}
public override async Task CheckAsync()
{
await base.CheckAsync();
await _productServiceDataSeeder.SeedAsync();
}
}

66
services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/DbMigrations/CatalogServiceDatabaseMigrationEventHandler.cs

@ -1,66 +0,0 @@
using EShopOnAbp.CatalogService.MongoDB;
using EShopOnAbp.Shared.Hosting.Microservices.DbMigrations.MongoDb;
using System;
using System.Threading.Tasks;
using Serilog;
using Volo.Abp.Data;
using Volo.Abp.DistributedLocking;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
namespace EShopOnAbp.CatalogService.DbMigrations;
public class CatalogServiceDatabaseMigrationEventHandler
: DatabaseMongoDbMigrationEventHandler<CatalogServiceMongoDbContext>,
IDistributedEventHandler<ApplyDatabaseMigrationsEto>
{
public CatalogServiceDatabaseMigrationEventHandler(
ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager,
ITenantStore tenantStore,
IDistributedEventBus distributedEventBus,
IServiceProvider serviceProvider,
IAbpDistributedLock distributedLockProvider
) : base(
currentTenant,
unitOfWorkManager,
tenantStore,
distributedEventBus,
CatalogServiceDbProperties.ConnectionStringName,
serviceProvider,
distributedLockProvider)
{
}
public async Task HandleEventAsync(ApplyDatabaseMigrationsEto eventData)
{
if (eventData.DatabaseName != DatabaseName)
{
return;
}
if (eventData.TenantId != null)
{
return;
}
try
{
Log.Information("CatalogService has acquired lock for db migration...");
await using (var handle = await DistributedLockProvider.TryAcquireAsync(DatabaseName))
{
if (handle != null)
{
Log.Information("CatalogService is migrating database...");
await MigrateDatabaseSchemaAsync();
}
}
}
catch (Exception ex)
{
await HandleErrorOnApplyDatabaseMigrationAsync(eventData, ex);
}
}
}

6
services/catalog/src/EShopOnAbp.CatalogService.HttpApi.Host/DbMigrations/ProductServiceDataSeeder.cs

@ -1,13 +1,14 @@
using System;
using System.Threading.Tasks;
using EShopOnAbp.CatalogService.Products;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Uow;
namespace EShopOnAbp.CatalogService.DbMigrations;
public class ProductServiceDataSeeder : ITransientDependency
public class ProductServiceDataSeeder : IDataSeedContributor, ITransientDependency
{
private readonly ProductManager _productManager;
private readonly IRepository<Product, Guid> _productRepository;
@ -20,8 +21,7 @@ public class ProductServiceDataSeeder : ITransientDependency
_productManager = productManager;
}
[UnitOfWork]
public virtual async Task SeedAsync()
public async Task SeedAsync(DataSeedContext context)
{
await AddProductsAsync();
}

9
services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/DbMigrations/ApplyDatabaseSeedsEto.cs

@ -1,9 +0,0 @@
using Volo.Abp.Domain.Entities.Events.Distributed;
using Volo.Abp.EventBus;
namespace EShopOnAbp.IdentityService.DbMigrations;
[EventName("abp.identity.apply_database_seeds")]
public class ApplyDatabaseSeedsEto : EtoBase
{
}

21
services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/DbMigrations/DataSeederEventHandler.cs

@ -1,21 +0,0 @@
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus;
namespace EShopOnAbp.IdentityService.DbMigrations;
public class DataSeederEventHandler : ILocalEventHandler<ApplyDatabaseSeedsEto>, ITransientDependency
{
protected IDataSeeder DataSeeder { get; }
public DataSeederEventHandler(IDataSeeder dataSeeder)
{
DataSeeder = dataSeeder;
}
public async Task HandleEventAsync(ApplyDatabaseSeedsEto eventData)
{
await DataSeeder.SeedAsync();
}
}

17
services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/DbMigrations/IdentityServiceDatabaseMigrationChecker.cs

@ -6,6 +6,7 @@ using Volo.Abp.EventBus.Distributed;
using Volo.Abp.EventBus.Local;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
using Volo.Abp.DistributedLocking;
namespace EShopOnAbp.IdentityService.DbMigrations;
@ -18,26 +19,16 @@ public class IdentityServiceDatabaseMigrationChecker : PendingEfCoreMigrationsCh
IServiceProvider serviceProvider,
ICurrentTenant currentTenant,
IDistributedEventBus distributedEventBus,
ILocalEventBus localEventBus)
ILocalEventBus localEventBus,
IAbpDistributedLock abpDistributedLock)
: base(
unitOfWorkManager,
serviceProvider,
currentTenant,
distributedEventBus,
abpDistributedLock,
IdentityServiceDbProperties.ConnectionStringName)
{
LocalEventBus = localEventBus;
}
public override async Task<bool> CheckAsync()
{
var isMigrationRequired = await base.CheckAsync();
if (!isMigrationRequired)
{
await LocalEventBus.PublishAsync(new ApplyDatabaseSeedsEto());
}
return isMigrationRequired;
}
}

90
services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/DbMigrations/IdentityServiceDatabaseMigrationEventHandler.cs

@ -1,90 +0,0 @@
using EShopOnAbp.IdentityService.EntityFrameworkCore;
using EShopOnAbp.Shared.Hosting.Microservices.DbMigrations.EfCore;
using Serilog;
using System;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.DistributedLocking;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.EventBus.Local;
using Volo.Abp.Identity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
namespace EShopOnAbp.IdentityService.DbMigrations;
public class IdentityServiceDatabaseMigrationEventHandler
: DatabaseEfCoreMigrationEventHandler<IdentityServiceDbContext>,
IDistributedEventHandler<ApplyDatabaseMigrationsEto>
{
private readonly IIdentityDataSeeder _identityDataSeeder;
private readonly IdentityServerDataSeeder _identityServerDataSeeder;
private readonly ILocalEventBus _localEventBus;
public IdentityServiceDatabaseMigrationEventHandler(
ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager,
ITenantStore tenantStore,
IIdentityDataSeeder identityDataSeeder,
IdentityServerDataSeeder identityServerDataSeeder,
IDistributedEventBus distributedEventBus,
ILocalEventBus localEventBus,
IAbpDistributedLock distributedLockProvider
) : base(
currentTenant,
unitOfWorkManager,
tenantStore,
distributedEventBus,
IdentityServiceDbProperties.ConnectionStringName,
distributedLockProvider)
{
_identityDataSeeder = identityDataSeeder;
_identityServerDataSeeder = identityServerDataSeeder;
_localEventBus = localEventBus;
}
public async Task HandleEventAsync(ApplyDatabaseMigrationsEto eventData)
{
if (eventData.DatabaseName != DatabaseName)
{
return;
}
try
{
await using (var handle = await DistributedLockProvider.TryAcquireAsync(DatabaseName))
{
Log.Information("IdentityService has acquired lock for db migration...");
if (handle != null)
{
Log.Information("IdentityService is migrating database...");
await MigrateDatabaseSchemaAsync();
Log.Information("IdentityService is seeding data...");
await SeedDataAsync(
adminEmail: IdentityServiceDbProperties.DefaultAdminEmailAddress,
adminPassword: IdentityServiceDbProperties.DefaultAdminPassword
);
}
}
await _localEventBus.PublishAsync(new ApplyDatabaseSeedsEto());
}
catch (Exception ex)
{
await HandleErrorOnApplyDatabaseMigrationAsync(eventData, ex);
}
}
private async Task SeedDataAsync(string adminEmail, string adminPassword)
{
Log.Information($"Seeding IdentityServer data...");
await _identityServerDataSeeder.SeedAsync();
Log.Information($"Seeding user data...");
await _identityDataSeeder.SeedAsync(
adminEmail,
adminPassword
);
}
}

2
services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/IdentityServiceHttpApiHostModule.cs

@ -100,6 +100,6 @@ public class IdentityServiceHttpApiHostModule : AbpModule
{
await context.ServiceProvider
.GetRequiredService<IdentityServiceDatabaseMigrationChecker>()
.CheckAsync();
.CheckAndApplyDatabaseMigrations();
}
}

5
services/ordering/src/EShopOnAbp.OrderingService.HttpApi.Host/DbMigrations/OrderingServiceDatabaseMigrationChecker.cs

@ -4,6 +4,7 @@ using EShopOnAbp.Shared.Hosting.Microservices.DbMigrations.EfCore;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
using Volo.Abp.DistributedLocking;
namespace EShopOnAbp.OrderingService.DbMigrations;
@ -14,12 +15,14 @@ public class OrderingServiceDatabaseMigrationChecker
IUnitOfWorkManager unitOfWorkManager,
IServiceProvider serviceProvider,
ICurrentTenant currentTenant,
IDistributedEventBus distributedEventBus)
IDistributedEventBus distributedEventBus,
IAbpDistributedLock abpDistributedLock)
: base(
unitOfWorkManager,
serviceProvider,
currentTenant,
distributedEventBus,
abpDistributedLock,
OrderingServiceDbProperties.ConnectionStringName)
{
}

70
services/ordering/src/EShopOnAbp.OrderingService.HttpApi.Host/DbMigrations/OrderingServiceDatabaseMigrationEventHandler.cs

@ -1,70 +0,0 @@
using EShopOnAbp.OrderingService.EntityFrameworkCore;
using EShopOnAbp.Shared.Hosting.Microservices.DbMigrations.EfCore;
using System;
using System.Threading.Tasks;
using Serilog;
using Volo.Abp.Data;
using Volo.Abp.DistributedLocking;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
namespace EShopOnAbp.OrderingService.DbMigrations;
public class OrderingServiceDatabaseMigrationEventHandler
: DatabaseEfCoreMigrationEventHandler<OrderingServiceDbContext>,
IDistributedEventHandler<ApplyDatabaseMigrationsEto>
{
private readonly IDataSeeder _dataSeeder;
public OrderingServiceDatabaseMigrationEventHandler(
ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager,
ITenantStore tenantStore,
IDistributedEventBus distributedEventBus,
IDataSeeder dataSeeder,
IAbpDistributedLock distributedLockProvider)
: base(
currentTenant,
unitOfWorkManager,
tenantStore,
distributedEventBus,
OrderingServiceDbProperties.ConnectionStringName,
distributedLockProvider)
{
_dataSeeder = dataSeeder;
}
public async Task HandleEventAsync(ApplyDatabaseMigrationsEto eventData)
{
if (eventData.DatabaseName != DatabaseName)
{
return;
}
if (eventData.TenantId != null)
{
return;
}
try
{
await using (var handle = await DistributedLockProvider.TryAcquireAsync(DatabaseName))
{
Log.Information("OrderingService has acquired lock for db migration...");
if (handle != null)
{
Log.Information("OrderingService is migrating database...");
await MigrateDatabaseSchemaAsync();
Log.Information("OrderingService is seeding data...");
await _dataSeeder.SeedAsync();
}
}
}
catch (Exception ex)
{
await HandleErrorOnApplyDatabaseMigrationAsync(eventData, ex);
}
}
}

2
services/ordering/src/EShopOnAbp.OrderingService.HttpApi.Host/OrderingServiceHttpApiHostModule.cs

@ -109,6 +109,6 @@ public class OrderingServiceHttpApiHostModule : AbpModule
{
await context.ServiceProvider
.GetRequiredService<OrderingServiceDatabaseMigrationChecker>()
.CheckAsync();
.CheckAndApplyDatabaseMigrations();
}
}

5
services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/DbMigrations/PaymentServiceDatabaseMigrationChecker.cs

@ -4,6 +4,7 @@ using EShopOnAbp.Shared.Hosting.Microservices.DbMigrations.EfCore;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
using Volo.Abp.DistributedLocking;
namespace EShopOnAbp.PaymentService.DbMigrations;
@ -14,12 +15,14 @@ public class PaymentServiceDatabaseMigrationChecker
IUnitOfWorkManager unitOfWorkManager,
IServiceProvider serviceProvider,
ICurrentTenant currentTenant,
IDistributedEventBus distributedEventBus)
IDistributedEventBus distributedEventBus,
IAbpDistributedLock abpDistributedLock)
: base(
unitOfWorkManager,
serviceProvider,
currentTenant,
distributedEventBus,
abpDistributedLock,
PaymentServiceDbProperties.ConnectionStringName)
{
}

64
services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/DbMigrations/PaymentServiceDatabaseMigrationEventHandler.cs

@ -1,64 +0,0 @@
using EShopOnAbp.PaymentService.EntityFrameworkCore;
using EShopOnAbp.Shared.Hosting.Microservices.DbMigrations.EfCore;
using System;
using System.Threading.Tasks;
using Serilog;
using Volo.Abp.Data;
using Volo.Abp.DistributedLocking;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
namespace EShopOnAbp.PaymentService.DbMigrations;
public class PaymentServiceDatabaseMigrationEventHandler
: DatabaseEfCoreMigrationEventHandler<PaymentServiceDbContext>,
IDistributedEventHandler<ApplyDatabaseMigrationsEto>
{
public PaymentServiceDatabaseMigrationEventHandler(
ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager,
ITenantStore tenantStore,
IDistributedEventBus distributedEventBus,
IAbpDistributedLock distributedLockProvider)
: base(
currentTenant,
unitOfWorkManager,
tenantStore,
distributedEventBus,
PaymentServiceDbProperties.ConnectionStringName,
distributedLockProvider)
{
}
public async Task HandleEventAsync(ApplyDatabaseMigrationsEto eventData)
{
if (eventData.DatabaseName != DatabaseName)
{
return;
}
if (eventData.TenantId != null)
{
return;
}
try
{
Log.Information("PaymentService has acquired lock for db migration...");
await using (var handle = await DistributedLockProvider.TryAcquireAsync(DatabaseName))
{
if (handle != null)
{
Log.Information("PaymentService is migrating database...");
await MigrateDatabaseSchemaAsync();
}
}
}
catch (Exception ex)
{
await HandleErrorOnApplyDatabaseMigrationAsync(eventData, ex);
}
}
}

2
services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/PaymentServiceHttpApiHostModule.cs

@ -100,6 +100,6 @@ public class PaymentServiceHttpApiHostModule : AbpModule
{
await context.ServiceProvider
.GetRequiredService<PaymentServiceDatabaseMigrationChecker>()
.CheckAsync();
.CheckAndApplyDatabaseMigrations();
}
}

48
shared/EShopOnAbp.Shared.Hosting.Microservices/DbMigrations/EfCore/PendingEfCoreMigrationsChecker.cs

@ -3,7 +3,9 @@ using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using Volo.Abp.Data;
using Volo.Abp.DistributedLocking;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
@ -17,6 +19,7 @@ public abstract class PendingEfCoreMigrationsChecker<TDbContext> : PendingMigrat
protected IServiceProvider ServiceProvider { get; }
protected ICurrentTenant CurrentTenant { get; }
protected IDistributedEventBus DistributedEventBus { get; }
protected IAbpDistributedLock DistributedLockProvider { get; }
protected string DatabaseName { get; }
protected PendingEfCoreMigrationsChecker(
@ -24,44 +27,45 @@ public abstract class PendingEfCoreMigrationsChecker<TDbContext> : PendingMigrat
IServiceProvider serviceProvider,
ICurrentTenant currentTenant,
IDistributedEventBus distributedEventBus,
IAbpDistributedLock abpDistributedLock,
string databaseName)
{
UnitOfWorkManager = unitOfWorkManager;
ServiceProvider = serviceProvider;
CurrentTenant = currentTenant;
DistributedEventBus = distributedEventBus;
DistributedLockProvider = abpDistributedLock;
DatabaseName = databaseName;
}
public virtual async Task<bool> CheckAsync()
public virtual async Task CheckAndApplyDatabaseMigrations()
{
var isMigrationRequired = false;
using (CurrentTenant.Change(null))
await using (var handle = await DistributedLockProvider.TryAcquireAsync("Migration_" + DatabaseName))
{
// Create database tables if needed
using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
{
var pendingMigrations = await ServiceProvider
.GetRequiredService<TDbContext>()
.Database
.GetPendingMigrationsAsync();
Log.Information($"Lock is acquired for db migration and seeding on database named: {DatabaseName}...");
if (pendingMigrations.Any())
using (CurrentTenant.Change(null))
{
// Create database tables if needed
using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
{
await DistributedEventBus.PublishAsync(
new ApplyDatabaseMigrationsEto
{
DatabaseName = DatabaseName
}
);
isMigrationRequired = true;
var dbContext = ServiceProvider.GetRequiredService<TDbContext>();
var pendingMigrations = await dbContext
.Database
.GetPendingMigrationsAsync();
if (pendingMigrations.Any())
{
await dbContext.Database.MigrateAsync();
}
await uow.CompleteAsync();
}
await uow.CompleteAsync();
await ServiceProvider.GetRequiredService<IDataSeeder>()
.SeedAsync();
}
return isMigrationRequired;
}
}
}

75
shared/EShopOnAbp.Shared.Hosting.Microservices/DbMigrations/MongoDb/PendingMongoDbMigrationsChecker.cs

@ -1,7 +1,10 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using MongoDB.Driver;
using Serilog;
using System;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.DistributedLocking;
using Volo.Abp.MongoDB;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
@ -14,39 +17,91 @@ public class PendingMongoDbMigrationsChecker<TDbContext> : PendingMigrationsChec
protected IUnitOfWorkManager UnitOfWorkManager { get; }
protected IServiceProvider ServiceProvider { get; }
protected ICurrentTenant CurrentTenant { get; }
protected IDistributedEventBus DistributedEventBus { get; }
protected IDataSeeder DataSeeder { get; }
protected IAbpDistributedLock DistributedLockProvider { get; }
protected string DatabaseName { get; }
protected PendingMongoDbMigrationsChecker(
IUnitOfWorkManager unitOfWorkManager,
IServiceProvider serviceProvider,
ICurrentTenant currentTenant,
IDistributedEventBus distributedEventBus,
IDataSeeder dataSeeder,
IAbpDistributedLock distributedLockProvider,
string databaseName)
{
UnitOfWorkManager = unitOfWorkManager;
ServiceProvider = serviceProvider;
CurrentTenant = currentTenant;
DistributedEventBus = distributedEventBus;
DataSeeder = dataSeeder;
DistributedLockProvider = distributedLockProvider;
DatabaseName = databaseName;
}
public virtual async Task CheckAsync()
public virtual async Task CheckAndApplyDatabaseMigrationsAsync()
{
using (CurrentTenant.Change(null))
{
// Create database tables if needed
using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
{
await DistributedEventBus.PublishAsync(
new ApplyDatabaseMigrationsEto
await MigrateDatabaseSchemaAsync();
await DataSeeder.SeedAsync();
await uow.CompleteAsync();
}
}
}
/// <summary>
/// Apply scheme update for MongoDB Database.
/// </summary>
protected virtual async Task<bool> MigrateDatabaseSchemaAsync()
{
var result = false;
await using (var handle = await DistributedLockProvider.TryAcquireAsync("Migration_" + DatabaseName))
{
Log.Information($"Lock is acquired for db migration and seeding on database named: {DatabaseName}...");
using (var uow = UnitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
{
async Task<bool> MigrateDatabaseSchemaWithDbContextAsync()
{
var dbContexts = ServiceProvider.GetServices<IAbpMongoDbContext>();
var connectionStringResolver = ServiceProvider.GetRequiredService<IConnectionStringResolver>();
foreach (var dbContext in dbContexts)
{
DatabaseName = DatabaseName
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));
}
);
return true;
}
//Migrating the host database
result = await MigrateDatabaseSchemaWithDbContextAsync();
await uow.CompleteAsync();
}
return result;
}
}
}
Loading…
Cancel
Save