-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #64 from marcwittke/develop
Develop
- Loading branch information
Showing
44 changed files
with
726 additions
and
910 deletions.
There are no files selected for viewing
87 changes: 87 additions & 0 deletions
87
src/abstractions/Backend.Fx/Environment/MultiTenancy/BackendFxApplicationTenantExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Reflection; | ||
using Backend.Fx.Environment.Authentication; | ||
using Backend.Fx.Logging; | ||
using Backend.Fx.Patterns.DataGeneration; | ||
using Backend.Fx.Patterns.DependencyInjection; | ||
using Backend.Fx.Patterns.EventAggregation.Integration; | ||
|
||
namespace Backend.Fx.Environment.MultiTenancy | ||
{ | ||
public static class BackendFxApplicationTenantExtensions | ||
{ | ||
private static readonly ILogger Logger = LogManager.Create(typeof(BackendFxApplicationTenantExtensions)); | ||
|
||
public static void RegisterSeedActionForNewlyCreatedTenants(this IBackendFxApplication application, ITenantService tenantService) | ||
{ | ||
application.CompositionRoot | ||
.GetInstance<IEventBus>() | ||
.Subscribe(new DelegateIntegrationEventHandler<TenantCreated>(tenantCreated => | ||
{ | ||
try | ||
{ | ||
var tenantId = new TenantId(tenantCreated.TenantId); | ||
application.SeedDataForTenant(tenantId, tenantCreated.IsDemoTenant); | ||
tenantService.ActivateTenant(tenantId); | ||
} | ||
catch (Exception ex) | ||
{ | ||
Logger.Error(ex, "Handling TenantCreated event failed"); | ||
} | ||
})); | ||
} | ||
|
||
public static void SeedDataForAllActiveTenants(this IBackendFxApplication application) | ||
{ | ||
using (Logger.InfoDuration("Seeding data")) | ||
{ | ||
var prodTenantIds = application.TenantIdService.GetActiveProductionTenantIds(); | ||
foreach (var prodTenantId in prodTenantIds) | ||
{ | ||
application.SeedDataForTenant(prodTenantId, false); | ||
} | ||
|
||
var demoTenantIds = application.TenantIdService.GetActiveDemonstrationTenantIds(); | ||
foreach (var demoTenantId in demoTenantIds) | ||
{ | ||
application.SeedDataForTenant(demoTenantId, true); | ||
} | ||
} | ||
} | ||
|
||
private static void SeedDataForTenant(this IBackendFxApplication application, TenantId tenantId, bool isDemoTenant) | ||
{ | ||
using (Logger.InfoDuration($"Seeding data for tenant {tenantId.Value}")) | ||
{ | ||
Type[] dataGeneratorTypesToRun; | ||
|
||
using (application.BeginScope()) | ||
{ | ||
var dataGenerators = application.CompositionRoot.GetInstances<IDataGenerator>() | ||
.OrderBy(dg => dg.Priority) | ||
.Select(dg => dg.GetType()); | ||
|
||
if (!isDemoTenant) | ||
{ | ||
dataGenerators = dataGenerators.Where(dg => !typeof(IDemoDataGenerator).IsAssignableFrom(dg)); | ||
} | ||
|
||
dataGeneratorTypesToRun = dataGenerators.ToArray(); | ||
} | ||
|
||
foreach (var dataGeneratorTypeToRun in dataGeneratorTypesToRun) | ||
{ | ||
application.Invoke(() => | ||
{ | ||
IDataGenerator dataGenerator = application | ||
.CompositionRoot | ||
.GetInstances<IDataGenerator>() | ||
.Single(dg => dg.GetType() == dataGeneratorTypeToRun); | ||
dataGenerator.Generate(); | ||
}, new SystemIdentity(), tenantId); | ||
} | ||
} | ||
} | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
src/abstractions/Backend.Fx/Environment/MultiTenancy/ITenantIdService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
using System.Linq; | ||
|
||
namespace Backend.Fx.Environment.MultiTenancy | ||
{ | ||
public interface ITenantIdService | ||
{ | ||
TenantId[] GetActiveTenantIds(); | ||
TenantId[] GetActiveDemonstrationTenantIds(); | ||
TenantId[] GetActiveProductionTenantIds(); | ||
} | ||
|
||
public class TenantIdService : ITenantIdService | ||
{ | ||
private readonly ITenantRepository _tenantRepository; | ||
|
||
public TenantIdService(ITenantRepository tenantRepository) | ||
{ | ||
_tenantRepository = tenantRepository; | ||
} | ||
|
||
|
||
public TenantId[] GetActiveTenantIds() | ||
{ | ||
return _tenantRepository | ||
.GetTenants() | ||
.Where(t => t.State == TenantState.Active) | ||
.Select(t => new TenantId(t.Id)) | ||
.ToArray(); | ||
} | ||
|
||
public TenantId[] GetActiveDemonstrationTenantIds() | ||
{ | ||
return _tenantRepository | ||
.GetTenants() | ||
.Where(t => t.State == TenantState.Active && t.IsDemoTenant) | ||
.Select(t => new TenantId(t.Id)) | ||
.ToArray(); | ||
} | ||
|
||
public TenantId[] GetActiveProductionTenantIds() | ||
{ | ||
return _tenantRepository | ||
.GetTenants() | ||
.Where(t => t.State == TenantState.Active && !t.IsDemoTenant) | ||
.Select(t => new TenantId(t.Id)) | ||
.ToArray(); | ||
} | ||
} | ||
|
||
} |
111 changes: 0 additions & 111 deletions
111
src/abstractions/Backend.Fx/Environment/MultiTenancy/ITenantManager.cs
This file was deleted.
Oops, something went wrong.
11 changes: 11 additions & 0 deletions
11
src/abstractions/Backend.Fx/Environment/MultiTenancy/ITenantRepository.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
namespace Backend.Fx.Environment.MultiTenancy | ||
{ | ||
public interface ITenantRepository | ||
{ | ||
void SaveTenant(Tenant tenant); | ||
|
||
Tenant[] GetTenants(); | ||
|
||
Tenant GetTenant(TenantId tenantId); | ||
} | ||
} |
80 changes: 80 additions & 0 deletions
80
src/abstractions/Backend.Fx/Environment/MultiTenancy/ITenantService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
using System; | ||
using System.Linq; | ||
using Backend.Fx.Logging; | ||
using Backend.Fx.Patterns.EventAggregation.Integration; | ||
using JetBrains.Annotations; | ||
|
||
namespace Backend.Fx.Environment.MultiTenancy | ||
{ | ||
/// <summary> | ||
/// Encapsulates the management of tenants | ||
/// Note that this should not use repositories and other building blocks, but access the persistence layer directly | ||
/// </summary> | ||
public interface ITenantService | ||
{ | ||
TenantId CreateDemonstrationTenant(string name, string description, string defaultCultureName); | ||
TenantId CreateProductionTenant(string name, string description, string defaultCultureName); | ||
void ActivateTenant(TenantId tenantId); | ||
void DeactivateTenant(TenantId tenantId); | ||
} | ||
|
||
public class TenantService : ITenantService | ||
{ | ||
private readonly IEventBus _eventBus; | ||
private readonly ITenantRepository _tenantRepository; | ||
private static readonly ILogger Logger = LogManager.Create<TenantService>(); | ||
|
||
public TenantService(IEventBus eventBus, ITenantRepository tenantRepository) | ||
{ | ||
_eventBus = eventBus; | ||
_tenantRepository = tenantRepository; | ||
} | ||
|
||
public TenantId CreateDemonstrationTenant(string name, string description, string defaultCultureName) | ||
{ | ||
Logger.Info($"Creating demonstration tenant: {name}"); | ||
return CreateTenant(name, description, true, defaultCultureName); | ||
} | ||
|
||
public TenantId CreateProductionTenant(string name, string description, string defaultCultureName) | ||
{ | ||
Logger.Info($"Creating production tenant: {name}"); | ||
return CreateTenant(name, description, false, defaultCultureName); | ||
} | ||
|
||
public void ActivateTenant(TenantId tenantId) | ||
{ | ||
var tenant = _tenantRepository.GetTenant(tenantId); | ||
tenant.State = TenantState.Active; | ||
_tenantRepository.SaveTenant(tenant); | ||
_eventBus.Publish(new TenantActivated(tenant.Id, tenant.Name, tenant.Description, tenant.IsDemoTenant, tenant.DefaultCultureName)); | ||
} | ||
|
||
public void DeactivateTenant(TenantId tenantId) | ||
{ | ||
var tenant = _tenantRepository.GetTenant(tenantId); | ||
tenant.State = TenantState.Inactive; | ||
_tenantRepository.SaveTenant(tenant); | ||
_eventBus.Publish(new TenantDeactivated(tenant.Id, tenant.Name, tenant.Description, tenant.IsDemoTenant, tenant.DefaultCultureName)); | ||
} | ||
|
||
protected virtual TenantId CreateTenant([NotNull] string name, string description, bool isDemo, string defaultCultureName) | ||
{ | ||
if (string.IsNullOrWhiteSpace(name)) | ||
{ | ||
throw new ArgumentException("Value cannot be null or whitespace.", nameof(name)); | ||
} | ||
|
||
if (_tenantRepository.GetTenants().Any(t => t.Name != null && t.Name.ToLowerInvariant() == name.ToLowerInvariant())) | ||
{ | ||
throw new ArgumentException($"There is already a tenant named {name}"); | ||
} | ||
|
||
Tenant tenant = new Tenant(name, description, isDemo, defaultCultureName); | ||
_tenantRepository.SaveTenant(tenant); | ||
var tenantId = new TenantId(tenant.Id); | ||
_eventBus.Publish(new TenantCreated(tenant.Id, tenant.Name, tenant.Description, tenant.IsDemoTenant, tenant.DefaultCultureName)); | ||
return tenantId; | ||
} | ||
} | ||
} |
Oops, something went wrong.