- Adding TenantState to the ShellSettings.

- Changes to the setup controller, multi tenancy controller/command handler to accomodate new ShellSettings like host,url prefix and state.
- Integration tests.

--HG--
branch : dev
This commit is contained in:
Suha Can 2010-04-22 17:38:02 -07:00
parent 1fa348b6b6
commit 91bb52c8af
15 changed files with 149 additions and 50 deletions

View File

@ -25,8 +25,19 @@ Scenario: A new tenant is created
And I fill in And I fill in
| name | value | | name | value |
| Name | Scott | | Name | Scott |
| DataProvider | SQLite |
And I hit "Save" And I hit "Save"
And I am redirected And I am redirected
Then I should see "<td>Scott</td>" Then I should see "<td>Scott</td>"
And the status should be 200 OK And the status should be 200 OK
Scenario: A new tenant is created with uninitialized state
Given I have installed Orchard
And I have installed "Orchard.MultiTenancy"
When I go to "Admin/MultiTenancy/Add"
And I fill in
| name | value |
| Name | Scott |
And I hit "Save"
And I am redirected
Then I should see "<td>Uninitialized</td>"
And the status should be 200 OK

View File

@ -2,7 +2,7 @@
// <auto-generated> // <auto-generated>
// This code was generated by SpecFlow (http://www.specflow.org/). // This code was generated by SpecFlow (http://www.specflow.org/).
// SpecFlow Version:1.2.0.0 // SpecFlow Version:1.2.0.0
// Runtime Version:2.0.50727.4200 // Runtime Version:2.0.50727.3603
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@ -114,18 +114,49 @@ this.ScenarioSetup(scenarioInfo);
table1.AddRow(new string[] { table1.AddRow(new string[] {
"Name", "Name",
"Scott"}); "Scott"});
table1.AddRow(new string[] {
"DataProvider",
"SQLite"});
#line 25 #line 25
testRunner.And("I fill in", ((string)(null)), table1); testRunner.And("I fill in", ((string)(null)), table1);
#line 29 #line 28
testRunner.And("I hit \"Save\""); testRunner.And("I hit \"Save\"");
#line 30 #line 29
testRunner.And("I am redirected"); testRunner.And("I am redirected");
#line 31 #line 30
testRunner.Then("I should see \"<td>Scott</td>\""); testRunner.Then("I should see \"<td>Scott</td>\"");
#line 32 #line 31
testRunner.And("the status should be 200 OK");
#line hidden
testRunner.CollectScenarioErrors();
}
[NUnit.Framework.TestAttribute()]
[NUnit.Framework.DescriptionAttribute("A new tenant is created with uninitialized state")]
public virtual void ANewTenantIsCreatedWithUninitializedState()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("A new tenant is created with uninitialized state", ((string[])(null)));
#line 33
this.ScenarioSetup(scenarioInfo);
#line 34
testRunner.Given("I have installed Orchard");
#line 35
testRunner.And("I have installed \"Orchard.MultiTenancy\"");
#line 36
testRunner.When("I go to \"Admin/MultiTenancy/Add\"");
#line hidden
TechTalk.SpecFlow.Table table2 = new TechTalk.SpecFlow.Table(new string[] {
"name",
"value"});
table2.AddRow(new string[] {
"Name",
"Scott"});
#line 37
testRunner.And("I fill in", ((string)(null)), table2);
#line 40
testRunner.And("I hit \"Save\"");
#line 41
testRunner.And("I am redirected");
#line 42
testRunner.Then("I should see \"<td>Uninitialized</td>\"");
#line 43
testRunner.And("the status should be 200 OK"); testRunner.And("the status should be 200 OK");
#line hidden #line hidden
testRunner.CollectScenarioErrors(); testRunner.CollectScenarioErrors();

View File

@ -7,7 +7,7 @@ namespace Orchard.MultiTenancy {
public void GetNavigation(NavigationBuilder builder) { public void GetNavigation(NavigationBuilder builder) {
builder.Add("MultiTenancy", "2", builder.Add("MultiTenancy", "2",
menu => menu menu => menu
.Add("Manage Tenants", "1.0", item => item.Action("List", "Admin", new { area = "Orchard.MultiTenancy" }).Permission(Permissions.ManageTenants)) .Add("Manage Tenants", "1.0", item => item.Action("Index", "Admin", new { area = "Orchard.MultiTenancy" }).Permission(Permissions.ManageTenants))
.Add("Add New Tenant", "1.1", item => item.Action("Add", "Admin", new { area = "Orchard.MultiTenancy" }).Permission(Permissions.ManageTenants))); .Add("Add New Tenant", "1.1", item => item.Action("Add", "Admin", new { area = "Orchard.MultiTenancy" }).Permission(Permissions.ManageTenants)));
} }
} }

View File

@ -17,9 +17,6 @@ namespace Orchard.MultiTenancy.Commands {
[OrchardSwitch] [OrchardSwitch]
public string UrlPrefix { get; set; } public string UrlPrefix { get; set; }
[OrchardSwitch]
public string ConnectionString { get; set; }
[CommandHelp("tenant list: Display current tenants of a site")] [CommandHelp("tenant list: Display current tenants of a site")]
[CommandName("tenant list")] [CommandName("tenant list")]
public void List() { public void List() {
@ -31,22 +28,25 @@ namespace Orchard.MultiTenancy.Commands {
Context.Output.WriteLine(T("Name: ") + tenant.Name); Context.Output.WriteLine(T("Name: ") + tenant.Name);
Context.Output.WriteLine(T("Provider: ") + tenant.DataProvider); Context.Output.WriteLine(T("Provider: ") + tenant.DataProvider);
Context.Output.WriteLine(T("ConnectionString: ") + tenant.DataConnectionString); Context.Output.WriteLine(T("ConnectionString: ") + tenant.DataConnectionString);
Context.Output.WriteLine(T("Prefix: ") + tenant.DataTablePrefix); Context.Output.WriteLine(T("Data Table Prefix: ") + tenant.DataTablePrefix);
Context.Output.WriteLine(T("Request Url Host: ") + tenant.RequestUrlHost);
Context.Output.WriteLine(T("Request Url Prefix: ") + tenant.RequestUrlPrefix);
Context.Output.WriteLine(T("State: ") + tenant.State.ToString());
Context.Output.WriteLine(T("---------------------------")); Context.Output.WriteLine(T("---------------------------"));
} }
} }
[CommandHelp("tenant add <tenantName> <providerName> <dataPrefix> /ConnectionString:<SQL connection string> /Host:<hostname> /UrlPrefix:<url prefix>" + [CommandHelp("tenant add <tenantName> /Host:<hostname> /UrlPrefix:<url prefix>" +
": create new tenant named <tenantName> on the site")] ": create new tenant named <tenantName> on the site")]
[CommandName("tenant add")] [CommandName("tenant add")]
public void Create(string tenantName, string providerName, string prefix) { public void Create(string tenantName) {
Context.Output.WriteLine(T("Creating tenant")); Context.Output.WriteLine(T("Creating tenant"));
_tenantService.CreateTenant( _tenantService.CreateTenant(
new ShellSettings { new ShellSettings {
Name = tenantName, Name = tenantName,
DataProvider = providerName, RequestUrlHost = Host,
DataConnectionString = ConnectionString, RequestUrlPrefix = UrlPrefix,
DataTablePrefix = prefix State = new TenantState("Uninitialized")
}); });
} }
@ -64,7 +64,10 @@ namespace Orchard.MultiTenancy.Commands {
Context.Output.WriteLine(T("Name: ") + tenant.Name); Context.Output.WriteLine(T("Name: ") + tenant.Name);
Context.Output.WriteLine(T("Provider: ") + tenant.DataProvider); Context.Output.WriteLine(T("Provider: ") + tenant.DataProvider);
Context.Output.WriteLine(T("ConnectionString: ") + tenant.DataConnectionString); Context.Output.WriteLine(T("ConnectionString: ") + tenant.DataConnectionString);
Context.Output.WriteLine(T("Prefix: ") + tenant.DataTablePrefix); Context.Output.WriteLine(T("Data Table Prefix: ") + tenant.DataTablePrefix);
Context.Output.WriteLine(T("Request Url Host: ") + tenant.RequestUrlHost);
Context.Output.WriteLine(T("Request Url Prefix: ") + tenant.RequestUrlPrefix);
Context.Output.WriteLine(T("State: ") + tenant.State.ToString());
Context.Output.WriteLine(T("---------------------------")); Context.Output.WriteLine(T("---------------------------"));
} }
} }

View File

@ -21,11 +21,7 @@ namespace Orchard.MultiTenancy.Controllers {
public IOrchardServices Services { get; set; } public IOrchardServices Services { get; set; }
public ActionResult Index() { public ActionResult Index() {
return View("List", new TenantsListViewModel { TenantSettings = _tenantService.GetTenants() }); return View(new TenantsIndexViewModel { TenantSettings = _tenantService.GetTenants() });
}
public ActionResult List() {
return View(new TenantsListViewModel { TenantSettings = _tenantService.GetTenants() });
} }
public ActionResult Add() { public ActionResult Add() {
@ -40,12 +36,12 @@ namespace Orchard.MultiTenancy.Controllers {
_tenantService.CreateTenant( _tenantService.CreateTenant(
new ShellSettings { new ShellSettings {
Name = viewModel.Name, Name = viewModel.Name,
DataProvider = viewModel.DataProvider, RequestUrlHost = viewModel.RequestUrlHost,
DataConnectionString = viewModel.ConnectionString, RequestUrlPrefix = viewModel.RequestUrlPrefix,
DataTablePrefix = viewModel.Prefix State = new TenantState("Uninitialized")
}); });
return RedirectToAction("List"); return RedirectToAction("Index");
} }
catch (Exception exception) { catch (Exception exception) {
Services.Notifier.Error(T("Creating Tenant failed: ") + exception.Message); Services.Notifier.Error(T("Creating Tenant failed: ") + exception.Message);

View File

@ -66,14 +66,14 @@
<Compile Include="Services\ITenantService.cs" /> <Compile Include="Services\ITenantService.cs" />
<Compile Include="Services\TenantService.cs" /> <Compile Include="Services\TenantService.cs" />
<Compile Include="ViewModels\TenantsAddViewModel.cs" /> <Compile Include="ViewModels\TenantsAddViewModel.cs" />
<Compile Include="ViewModels\TenantsListViewModel.cs" /> <Compile Include="ViewModels\TenantsIndexViewModel.cs" />
<Compile Include="Permissions.cs" /> <Compile Include="Permissions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Module.txt" /> <Content Include="Module.txt" />
<Content Include="Views\Admin\Add.ascx" /> <Content Include="Views\Admin\Add.ascx" />
<Content Include="Views\Admin\List.ascx" /> <Content Include="Views\Admin\Index.ascx" />
<Content Include="Web.config" /> <Content Include="Web.config" />
<Content Include="Views\Web.config" /> <Content Include="Views\Web.config" />
</ItemGroup> </ItemGroup>

View File

@ -6,10 +6,8 @@ namespace Orchard.MultiTenancy.ViewModels {
public class TenantsAddViewModel : BaseViewModel { public class TenantsAddViewModel : BaseViewModel {
[Required, DisplayName("Tenant Name:")] [Required, DisplayName("Tenant Name:")]
public string Name { get; set; } public string Name { get; set; }
[Required] public string RequestUrlHost { get; set; }
public string DataProvider { get; set; } public string RequestUrlPrefix { get; set; }
public string ConnectionString { get; set; }
public string Prefix { get; set; }
} }
} }

View File

@ -3,7 +3,7 @@ using Orchard.Environment.Configuration;
using Orchard.Mvc.ViewModels; using Orchard.Mvc.ViewModels;
namespace Orchard.MultiTenancy.ViewModels { namespace Orchard.MultiTenancy.ViewModels {
public class TenantsListViewModel : BaseViewModel { public class TenantsIndexViewModel : BaseViewModel {
public IEnumerable<ShellSettings> TenantSettings { get; set; } public IEnumerable<ShellSettings> TenantSettings { get; set; }
} }
} }

View File

@ -9,12 +9,10 @@
<fieldset> <fieldset>
<label for="Name"><%=_Encoded("Tenant Name") %></label> <label for="Name"><%=_Encoded("Tenant Name") %></label>
<input id="Name" class="textMedium" name="Name" type="text" /><br /> <input id="Name" class="textMedium" name="Name" type="text" /><br />
<label for="DataProvider"><%=_Encoded("Data Provider Name") %></label> <label for="RequestUrlHost"><%=_Encoded("Host Prefix") %></label>
<input id="DataProvider" class="textMedium" name="DataProvider" type="text" /><br /> <input id="RequestUrlHost" class="textMedium" name="RequestUrlHost" type="text" /><br />
<label for="Name"><%=_Encoded("Connection String") %></label> <label for="RequestUrlPrefix"><%=_Encoded("Url Prefix") %></label>
<input id="ConnectionString" class="textMedium" name="ConnectionString" type="text" /><br /> <input id="RequestUrlPrefix" class="textMedium" name="RequestUrlPrefix" type="text" /><br />
<label for="Name"><%=_Encoded("Prefix") %></label>
<input id="Prefix" class="textMedium" name="Prefix" type="text" /><br />
</fieldset> </fieldset>
<fieldset> <fieldset>
<input type="submit" class="button primaryAction" value="<%=_Encoded("Save") %>" /> <input type="submit" class="button primaryAction" value="<%=_Encoded("Save") %>" />

View File

@ -1,21 +1,26 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<TenantsListViewModel>" %> <%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<TenantsIndexViewModel>" %>
<%@ Import Namespace="Orchard.Mvc.Html"%> <%@ Import Namespace="Orchard.Mvc.Html"%>
<%@ Import Namespace="Orchard.MultiTenancy.ViewModels"%> <%@ Import Namespace="Orchard.MultiTenancy.ViewModels"%>
<%@ Import Namespace="Orchard.ContentManagement"%>
<h1><%=Html.TitleForPage(T("List of Site's Tenants").ToString())%></h1> <h1><%=Html.TitleForPage(T("List of Site's Tenants").ToString())%></h1>
<table class="items"> <table class="items">
<colgroup> <colgroup>
<col id="Name" /> <col id="Name" />
<col id="Provider" /> <col id="Data Provider" />
<col id="ConnectionString" /> <col id="ConnectionString" />
<col id="Prefix" /> <col id="TablePrefix" />
<col id="RequestUrlHost" />
<col id="RequestUrlPrefix" />
<col id="TenantState" />
</colgroup> </colgroup>
<thead> <thead>
<tr> <tr>
<td scope="col"><%=_Encoded("Name") %></td> <td scope="col"><%=_Encoded("Name") %></td>
<td scope="col"><%=_Encoded("Provider") %></td> <td scope="col"><%=_Encoded("Data Provider") %></td>
<td scope="col"><%=_Encoded("ConnectionString") %></td> <td scope="col"><%=_Encoded("ConnectionString") %></td>
<td scope="col"><%=_Encoded("Prefix") %></td> <td scope="col"><%=_Encoded("Table Prefix") %></td>
<td scope="col"><%=_Encoded("Request Url Host") %></td>
<td scope="col"><%=_Encoded("Request Url Prefix") %></td>
<td scope="col"><%=_Encoded("State") %></td>
</tr> </tr>
</thead> </thead>
<tbody><% <tbody><%
@ -25,7 +30,10 @@
<td><%= tenant.DataProvider %></td> <td><%= tenant.DataProvider %></td>
<td><%= tenant.DataConnectionString %></td> <td><%= tenant.DataConnectionString %></td>
<td><%= tenant.DataTablePrefix %></td> <td><%= tenant.DataTablePrefix %></td>
<td><%= tenant.RequestUrlHost %></td>
<td><%= tenant.RequestUrlPrefix %></td>
<td><%= tenant.State %></td>
</tr><% </tr><%
} %> } %>
</tbody> </tbody>
</table> </table>

View File

@ -163,6 +163,7 @@ namespace Orchard.Setup.Controllers {
} }
} }
shellSettings.State = new TenantState("Running");
_shellSettingsManager.SaveSettings(shellSettings); _shellSettingsManager.SaveSettings(shellSettings);
_orchardHost.Reinitialize_Obsolete(); _orchardHost.Reinitialize_Obsolete();

View File

@ -13,5 +13,7 @@
public string RequestUrlHost { get; set; } public string RequestUrlHost { get; set; }
public string RequestUrlPrefix { get; set; } public string RequestUrlPrefix { get; set; }
public TenantState State { get; set; }
} }
} }

View File

@ -50,6 +50,9 @@ namespace Orchard.Environment.Configuration {
public string DataProvider { get; set; } public string DataProvider { get; set; }
public string DataConnectionString { get; set; } public string DataConnectionString { get; set; }
public string DataPrefix { get; set; } public string DataPrefix { get; set; }
public string RequestUrlHost { get; set; }
public string RequestUrlPrefix { get; set; }
public string State { get; set; }
} }
static ShellSettings ParseSettings(string text) { static ShellSettings ParseSettings(string text) {
@ -60,6 +63,9 @@ namespace Orchard.Environment.Configuration {
DataProvider = content.DataProvider, DataProvider = content.DataProvider,
DataConnectionString = content.DataConnectionString, DataConnectionString = content.DataConnectionString,
DataTablePrefix = content.DataPrefix, DataTablePrefix = content.DataPrefix,
RequestUrlHost = content.RequestUrlHost,
RequestUrlPrefix = content.RequestUrlPrefix,
State = new TenantState(content.State)
}; };
} }
@ -73,6 +79,9 @@ namespace Orchard.Environment.Configuration {
DataProvider = settings.DataProvider, DataProvider = settings.DataProvider,
DataConnectionString = settings.DataConnectionString, DataConnectionString = settings.DataConnectionString,
DataPrefix = settings.DataTablePrefix, DataPrefix = settings.DataTablePrefix,
RequestUrlHost = settings.RequestUrlHost,
RequestUrlPrefix = settings.RequestUrlPrefix,
State = settings.State != null ? settings.State.ToString() : String.Empty
}); });
} }
} }

View File

@ -0,0 +1,41 @@
namespace Orchard.Environment.Configuration {
public class TenantState {
public TenantState(string state) {
switch (state) {
case "Uninitialized":
CurrentState = State.Uninitialized;
break;
case "Running":
CurrentState = State.Running;
break;
case "Disabled":
CurrentState = State.Disabled;
break;
default:
CurrentState = State.Invalid;
break;
}
}
public State CurrentState { get; set; }
public enum State {
Uninitialized,
Running,
Disabled,
Invalid
}
public override string ToString() {
switch (CurrentState) {
case State.Uninitialized:
return "Uninitialized";
case State.Running:
return "Running";
case State.Disabled:
return "Disabled";
}
return "Invalid";
}
}
}

View File

@ -162,6 +162,7 @@
<Compile Include="Data\Conventions\StringLengthConvention.cs" /> <Compile Include="Data\Conventions\StringLengthConvention.cs" />
<Compile Include="Data\SessionFactoryHolder.cs" /> <Compile Include="Data\SessionFactoryHolder.cs" />
<Compile Include="Environment\AutofacUtil\LifetimeScopeContainer.cs" /> <Compile Include="Environment\AutofacUtil\LifetimeScopeContainer.cs" />
<Compile Include="Environment\Configuration\TenantState.cs" />
<Compile Include="Environment\RunningShellTable.cs" /> <Compile Include="Environment\RunningShellTable.cs" />
<Compile Include="Environment\AutofacUtil\DynamicProxy2\DynamicProxyContext.cs" /> <Compile Include="Environment\AutofacUtil\DynamicProxy2\DynamicProxyContext.cs" />
<Compile Include="Environment\AutofacUtil\DynamicProxy2\DynamicProxyExtensions.cs" /> <Compile Include="Environment\AutofacUtil\DynamicProxy2\DynamicProxyExtensions.cs" />