Skip to content

Commit

Permalink
TenantState INitializing
Browse files Browse the repository at this point in the history
  • Loading branch information
marcwittke committed Dec 25, 2017
1 parent 457139d commit 405f0ae
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 63 deletions.
14 changes: 4 additions & 10 deletions src/Backend.Fx.Bootstrapping/SimpleInjectorRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ namespace Backend.Fx.Bootstrapping
using Environment.Authentication;
using Environment.MultiTenancy;
using Environment.Persistence;
using Exceptions;
using Logging;
using Patterns.Authorization;
using Patterns.DataGeneration;
Expand Down Expand Up @@ -251,15 +250,10 @@ public object GetInstance(Type serviceType)
/// </summary>
public IRuntimeScope BeginScope(IIdentity identity, TenantId tenantId)
{
if (TenantManager.IsActive(tenantId))
{
var scope = new RuntimeScope(this, identity, tenantId);
scope.GetInstance<ICurrentTHolder<IIdentity>>().ReplaceCurrent(identity);
scope.GetInstance<ICurrentTHolder<TenantId>>().ReplaceCurrent(tenantId);
return scope;
}

throw new UnprocessableException($"Tenant {tenantId.Value} is deactivated. Contact the system adminstrator.");
var scope = new RuntimeScope(this, identity, tenantId);
scope.GetInstance<ICurrentTHolder<IIdentity>>().ReplaceCurrent(identity);
scope.GetInstance<ICurrentTHolder<TenantId>>().ReplaceCurrent(tenantId);
return scope;
}

/// <summary>
Expand Down
3 changes: 1 addition & 2 deletions src/Backend.Fx.EfCorePersistence/TenantManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,12 @@ protected override void SaveTenant(Tenant tenant)
}
else
{
existingTenant.IsActive = tenant.IsActive;
existingTenant.State = tenant.State;
if (existingTenant.IsDemoTenant && !tenant.IsDemoTenant)
{
throw new InvalidOperationException("It is not possible to convert a demonstration tenant to a productive tenant");
}
existingTenant.IsDemoTenant = tenant.IsDemoTenant;
existingTenant.IsInitialized = tenant.IsInitialized;
existingTenant.Name = tenant.Name;
existingTenant.Description = tenant.Description;
}
Expand Down
47 changes: 20 additions & 27 deletions src/Backend.Fx/Environment/MultiTenancy/ITenantManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Exceptions;
using JetBrains.Annotations;
using Logging;

Expand All @@ -11,7 +12,6 @@ public interface ITenantManager
TenantId[] GetTenantIds();
Tenant[] GetTenants();
Tenant GetTenant(TenantId id);
bool IsActive(TenantId tenantId);
TenantId CreateDemonstrationTenant(string name, string description, bool isDefault);
TenantId CreateProductionTenant(string name, string description, bool isDefault);
void EnsureTenantIsInitialized(TenantId tenantId);
Expand Down Expand Up @@ -49,16 +49,26 @@ public TenantId CreateProductionTenant(string name, string description, bool isD

protected void InitializeTenant(Tenant tenant)
{
if (tenant.IsInitialized) return;

Logger.Info($"Initializing {(tenant.IsDemoTenant ? "demonstration" : "production")} tenant[{tenant.Id}] ({tenant.Name})");
var tenantId = new TenantId(tenant.Id);
tenantInitializer.RunProductiveInitialDataGenerators(tenantId);
if (tenant.IsDemoTenant)
switch (tenant.State)
{
tenantInitializer.RunDemoInitialDataGenerators(tenantId);
case TenantState.Inactive: throw new UnprocessableException($"Cannot initialize inactive Tenant[{tenant.Id}]");
case TenantState.Created:
tenant.State = TenantState.Initializing;
SaveTenant(tenant);

Logger.Info($"Initializing {(tenant.IsDemoTenant ? "demonstration" : "production")} tenant[{tenant.Id}] ({tenant.Name})");
var tenantId = new TenantId(tenant.Id);
tenantInitializer.RunProductiveInitialDataGenerators(tenantId);
if (tenant.IsDemoTenant)
{
tenantInitializer.RunDemoInitialDataGenerators(tenantId);
}
tenant.State = TenantState.Active;
break;
default:
return;
}
tenant.IsInitialized = true;

}

public abstract TenantId[] GetTenantIds();
Expand All @@ -76,23 +86,6 @@ public Tenant GetTenant(TenantId tenantId)
return tenant;
}

public bool IsActive(TenantId tenantId)
{
if (tenantId.HasValue)
{
Tenant tenant = FindTenant(tenantId);

if (tenant == null)
{
throw new ArgumentException($"Invalid tenant Id [{tenantId.Value}]", nameof(tenantId));
}

return tenant.IsActive;
}

return true;
}

public void EnsureTenantIsInitialized(TenantId tenantId)
{
if (initializedTenants.Contains(tenantId.Value))
Expand Down Expand Up @@ -123,7 +116,7 @@ private TenantId CreateTenant([NotNull] string name, string description, bool is
throw new ArgumentException($"There is already a tenant named {name}");
}

Tenant tenant = new Tenant(name, description, isDemo) { IsActive = true, IsDefault = isDefault };
Tenant tenant = new Tenant(name, description, isDemo) { State = TenantState.Created, IsDefault = isDefault };
SaveTenant(tenant);
return new TenantId(tenant.Id);
}
Expand Down
11 changes: 9 additions & 2 deletions src/Backend.Fx/Environment/MultiTenancy/Tenant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,16 @@ public Tenant([NotNull] string name, string description, bool isDemoTenant)

public bool IsDemoTenant { get; set; }

public bool IsInitialized { get; set; }
public TenantState State { get; set; }

public bool IsActive { get; set; }
public bool IsDefault { get; set; }
}

public enum TenantState
{
Created = 0,
Initializing = 1,
Active = 2,
Inactive = int.MaxValue
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ public void ThrowsOnValidation()
IDatabaseManager databaseManager = A.Fake<IDatabaseManager>();

ITenantManager tenantManager = A.Fake<ITenantManager>();
A.CallTo(() => tenantManager.IsActive(A<TenantId>._)).Returns(true);


var sut = new TestRuntime(tenantManager, databaseManager);
Assert.Throws<InvalidOperationException>(() => sut.Boot(container => container.Register<UnresolvableService>()));
}
Expand Down
10 changes: 0 additions & 10 deletions tests/Backend.Fx.Bootstrapping.Tests/TheSimpleInjectorRuntime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace Backend.Fx.Bootstrapping.Tests
using Environment.DateAndTime;
using Environment.MultiTenancy;
using Environment.Persistence;
using Exceptions;
using FakeItEasy;
using Patterns.DependencyInjection;
using Patterns.EventAggregation;
Expand All @@ -30,7 +29,6 @@ public TheSimpleInjectorRuntime()
IDatabaseManager databaseManager = A.Fake<IDatabaseManager>();

tenantManager = A.Fake<ITenantManager>();
A.CallTo(() => tenantManager.IsActive(A<TenantId>._)).Returns(true);
TenantId[] tenantIds = {new TenantId(999)};
A.CallTo(() => tenantManager.GetTenantIds()).Returns(tenantIds);

Expand All @@ -47,14 +45,6 @@ public void CallsAllRelevantMethodsOnBoot()
Assert.True(sut.InitializeJobSchedulerWasCalled);
}

[Fact]
public void DoesNotAllowBeginningScopeWhenTenantIsDeactivated()
{
A.CallTo(() => tenantManager.IsActive(A<TenantId>._)).Returns(false);
sut.Boot();
Assert.Throws<UnprocessableException>(() => sut.BeginScope(new SystemIdentity(), new TenantId(111)));
}

[Fact]
public void ProvidesAutoRegisteredDomainServices()
{
Expand Down
20 changes: 10 additions & 10 deletions tests/Backend.Fx.EfCorePersistence.Tests/TheTenantManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public void CanCreateTenant()
[Fact]
public void CanUpdateTenant()
{
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, IsActive, IsDemoTenant, IsInitialized, IsDefault) VALUES ('4711', 'The Tenant', 'The Description', 1, 0, 1, 0)");
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, State, IsDemoTenant, IsDefault) VALUES ('4711', 'The Tenant', 'The Description', 2, 0, 0)");

var tenant = new Tenant("Tenant 1", "Lorem Ipsum", false) { Id = 4711 };
sut.SaveTenantX(tenant);
Expand All @@ -42,7 +42,7 @@ public void CanUpdateTenant()
[Fact]
public void CanFindTenant()
{
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, IsActive, IsDemoTenant, IsInitialized, IsDefault) VALUES ('4711', 'The Tenant', 'The Description', 1, 0, 1, 0)");
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, State, IsDemoTenant, IsDefault) VALUES ('4711', 'The Tenant', 'The Description', 2, 1, 0)");

var tenant = sut.FindTenantX(new TenantId(4711));
Assert.Equal("The Tenant", tenant.Name);
Expand All @@ -52,10 +52,10 @@ public void CanFindTenant()
[Fact]
public void CanGetTenants()
{
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, IsActive, IsDemoTenant, IsInitialized, IsDefault) VALUES ('4711', 'The Tenant 1', 'The Description 1', 1, 0, 1, 0)");
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, IsActive, IsDemoTenant, IsInitialized, IsDefault) VALUES ('4712', 'The Tenant 2', 'The Description 2', 1, 0, 1, 0)");
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, IsActive, IsDemoTenant, IsInitialized, IsDefault) VALUES ('4713', 'The Tenant 3', 'The Description 3', 1, 0, 1, 0)");
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, IsActive, IsDemoTenant, IsInitialized, IsDefault) VALUES ('4714', 'The Tenant 4', 'The Description 4', 1, 0, 1, 0)");
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, State, IsDemoTenant, IsDefault) VALUES ('4711', 'The Tenant 1', 'The Description 1', 2, 1, 0)");
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, State, IsDemoTenant, IsDefault) VALUES ('4712', 'The Tenant 2', 'The Description 2', 2, 1, 0)");
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, State, IsDemoTenant, IsDefault) VALUES ('4713', 'The Tenant 3', 'The Description 3', 2, 1, 0)");
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, State, IsDemoTenant, IsDefault) VALUES ('4714', 'The Tenant 4', 'The Description 4', 2, 1, 0)");

var tenants = sut.GetTenants();
Assert.Equal(4, tenants.Length);
Expand All @@ -68,10 +68,10 @@ public void CanGetTenants()
[Fact]
public void CanGetTenantIds()
{
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, IsActive, IsDemoTenant, IsInitialized, IsDefault) VALUES ('4711', 'The Tenant 1', 'The Description 1', 1, 0, 1, 0)");
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, IsActive, IsDemoTenant, IsInitialized, IsDefault) VALUES ('4712', 'The Tenant 2', 'The Description 2', 1, 0, 1, 0)");
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, IsActive, IsDemoTenant, IsInitialized, IsDefault) VALUES ('4713', 'The Tenant 3', 'The Description 3', 1, 0, 1, 0)");
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, IsActive, IsDemoTenant, IsInitialized, IsDefault) VALUES ('4714', 'The Tenant 4', 'The Description 4', 1, 0, 1, 0)");
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, State, IsDemoTenant, IsDefault) VALUES ('4711', 'The Tenant 1', 'The Description 1', 2, 1, 0)");
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, State, IsDemoTenant, IsDefault) VALUES ('4712', 'The Tenant 2', 'The Description 2', 2, 1, 0)");
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, State, IsDemoTenant, IsDefault) VALUES ('4713', 'The Tenant 3', 'The Description 3', 2, 1, 0)");
ExecuteNonQuery("INSERT INTO Tenants (Id, Name, Description, State, IsDemoTenant, IsDefault) VALUES ('4714', 'The Tenant 4', 'The Description 4', 2, 1, 0)");

var tenants = sut.GetTenantIds();
Assert.Equal(4, tenants.Length);
Expand Down

0 comments on commit 405f0ae

Please sign in to comment.