diff --git a/src/Orchard.Tests.Modules/Settings/Topology/TopologyDescriptorManagerTests.cs b/src/Orchard.Tests.Modules/Settings/Topology/ShellDescriptorManagerTests.cs similarity index 63% rename from src/Orchard.Tests.Modules/Settings/Topology/TopologyDescriptorManagerTests.cs rename to src/Orchard.Tests.Modules/Settings/Topology/ShellDescriptorManagerTests.cs index ca1634f95..ae058f009 100644 --- a/src/Orchard.Tests.Modules/Settings/Topology/TopologyDescriptorManagerTests.cs +++ b/src/Orchard.Tests.Modules/Settings/Topology/ShellDescriptorManagerTests.cs @@ -11,9 +11,9 @@ using Orchard.Events; namespace Orchard.Tests.Modules.Settings.Topology { [TestFixture] - public class TopologyDescriptorManagerTests : DatabaseEnabledTestsBase { + public class ShellDescriptorManagerTests : DatabaseEnabledTestsBase { public override void Register(ContainerBuilder builder) { - builder.RegisterType().As(); + builder.RegisterType().As(); builder.RegisterType().As().SingleInstance(); } @@ -40,104 +40,104 @@ namespace Orchard.Tests.Modules.Settings.Topology { [Test] public void TopologyShouldBeNullWhenItsNotInitialized() { - var manager = _container.Resolve(); - var topology = manager.GetTopologyDescriptor(); + var manager = _container.Resolve(); + var topology = manager.GetShellDescriptor(); Assert.That(topology, Is.Null); } [Test] public void PriorSerialNumberOfZeroIsAcceptableForInitialUpdateAndSerialNumberIsNonzeroAfterwards() { - var manager = _container.Resolve(); - manager.UpdateTopologyDescriptor( + var manager = _container.Resolve(); + manager.UpdateShellDescriptor( 0, - Enumerable.Empty(), - Enumerable.Empty()); + Enumerable.Empty(), + Enumerable.Empty()); - var topology = manager.GetTopologyDescriptor(); + var topology = manager.GetShellDescriptor(); Assert.That(topology, Is.Not.Null); Assert.That(topology.SerialNumber, Is.Not.EqualTo(0)); } [Test] public void NonZeroInitialUpdateThrowsInvalidOperationException() { - var manager = _container.Resolve(); - Assert.Throws(() => manager.UpdateTopologyDescriptor( + var manager = _container.Resolve(); + Assert.Throws(() => manager.UpdateShellDescriptor( 1, - Enumerable.Empty(), - Enumerable.Empty())); + Enumerable.Empty(), + Enumerable.Empty())); } [Test] public void OnlyCorrectSerialNumberOnLaterUpdatesDoesNotThrowException() { - var manager = _container.Resolve(); - manager.UpdateTopologyDescriptor( + var manager = _container.Resolve(); + manager.UpdateShellDescriptor( 0, - Enumerable.Empty(), - Enumerable.Empty()); + Enumerable.Empty(), + Enumerable.Empty()); - var topology = manager.GetTopologyDescriptor(); + var topology = manager.GetShellDescriptor(); Assert.That(topology.SerialNumber, Is.Not.EqualTo(0)); - Assert.Throws(() => manager.UpdateTopologyDescriptor( + Assert.Throws(() => manager.UpdateShellDescriptor( 0, - Enumerable.Empty(), - Enumerable.Empty())); + Enumerable.Empty(), + Enumerable.Empty())); - Assert.Throws(() => manager.UpdateTopologyDescriptor( + Assert.Throws(() => manager.UpdateShellDescriptor( topology.SerialNumber + 665321, - Enumerable.Empty(), - Enumerable.Empty())); + Enumerable.Empty(), + Enumerable.Empty())); - manager.UpdateTopologyDescriptor( + manager.UpdateShellDescriptor( topology.SerialNumber, - Enumerable.Empty(), - Enumerable.Empty()); + Enumerable.Empty(), + Enumerable.Empty()); - var topology2 = manager.GetTopologyDescriptor(); + var topology2 = manager.GetShellDescriptor(); Assert.That(topology2.SerialNumber, Is.Not.EqualTo(0)); Assert.That(topology2.SerialNumber, Is.Not.EqualTo(topology.SerialNumber)); - Assert.Throws(() => manager.UpdateTopologyDescriptor( + Assert.Throws(() => manager.UpdateShellDescriptor( 0, - Enumerable.Empty(), - Enumerable.Empty())); + Enumerable.Empty(), + Enumerable.Empty())); - Assert.Throws(() => manager.UpdateTopologyDescriptor( + Assert.Throws(() => manager.UpdateShellDescriptor( topology.SerialNumber, - Enumerable.Empty(), - Enumerable.Empty())); + Enumerable.Empty(), + Enumerable.Empty())); - manager.UpdateTopologyDescriptor( + manager.UpdateShellDescriptor( topology2.SerialNumber, - Enumerable.Empty(), - Enumerable.Empty()); + Enumerable.Empty(), + Enumerable.Empty()); - Assert.Throws(() => manager.UpdateTopologyDescriptor( + Assert.Throws(() => manager.UpdateShellDescriptor( topology2.SerialNumber, - Enumerable.Empty(), - Enumerable.Empty())); + Enumerable.Empty(), + Enumerable.Empty())); } [Test] public void SuccessfulUpdateRaisesAnEvent() { - var manager = _container.Resolve(); + var manager = _container.Resolve(); var eventBus = _container.Resolve() as StubEventBus; Assert.That(eventBus.LastMessageName, Is.Null); - Assert.Throws(() => manager.UpdateTopologyDescriptor( + Assert.Throws(() => manager.UpdateShellDescriptor( 5, - Enumerable.Empty(), - Enumerable.Empty())); + Enumerable.Empty(), + Enumerable.Empty())); Assert.That(eventBus.LastMessageName, Is.Null); - manager.UpdateTopologyDescriptor( + manager.UpdateShellDescriptor( 0, - Enumerable.Empty(), - Enumerable.Empty()); + Enumerable.Empty(), + Enumerable.Empty()); - Assert.That(eventBus.LastMessageName, Is.EqualTo(typeof(ITopologyDescriptorManager).FullName + ".UpdateTopologyDescriptor")); + Assert.That(eventBus.LastMessageName, Is.EqualTo(typeof(IShellDescriptorManager).FullName + ".UpdateShellDescriptor")); } } } diff --git a/src/Orchard.Tests/Environment/Topology/DefaultTopologyDescriptorCacheTests.cs b/src/Orchard.Tests/Environment/Topology/DefaultShellDescriptorCacheTests.cs similarity index 70% rename from src/Orchard.Tests/Environment/Topology/DefaultTopologyDescriptorCacheTests.cs rename to src/Orchard.Tests/Environment/Topology/DefaultShellDescriptorCacheTests.cs index 51fe39aaf..426d919a4 100644 --- a/src/Orchard.Tests/Environment/Topology/DefaultTopologyDescriptorCacheTests.cs +++ b/src/Orchard.Tests/Environment/Topology/DefaultShellDescriptorCacheTests.cs @@ -9,7 +9,7 @@ using Orchard.Environment.Topology.Models; namespace Orchard.Tests.Environment.Topology { [TestFixture] - public class DefaultTopologyDescriptorCacheTests { + public class DefaultShellDescriptorCacheTests { private IContainer _container; private string _tempFolder; private IAppDataFolder _appDataFolder; @@ -23,7 +23,7 @@ namespace Orchard.Tests.Environment.Topology { _appDataFolder.SetBasePath(_tempFolder); var builder = new ContainerBuilder(); builder.RegisterInstance(_appDataFolder).As(); - builder.RegisterType().As(); + builder.RegisterType().As(); _container = builder.Build(); } @@ -34,15 +34,15 @@ namespace Orchard.Tests.Environment.Topology { [Test] public void FetchReturnsNullForCacheMiss() { - var service = _container.Resolve(); + var service = _container.Resolve(); var descriptor = service.Fetch("No such shell"); Assert.That(descriptor, Is.Null); } [Test] public void StoreCanBeCalledMoreThanOnceOnTheSameName() { - var service = _container.Resolve(); - var descriptor = new ShellTopologyDescriptor { SerialNumber = 6655321 }; + var service = _container.Resolve(); + var descriptor = new ShellDescriptor { SerialNumber = 6655321 }; service.Store("Hello", descriptor); service.Store("Hello", descriptor); var result = service.Fetch("Hello"); @@ -52,10 +52,10 @@ namespace Orchard.Tests.Environment.Topology { [Test] public void SecondCallUpdatesData() { - var service = _container.Resolve(); - var descriptor1 = new ShellTopologyDescriptor { SerialNumber = 6655321 }; + var service = _container.Resolve(); + var descriptor1 = new ShellDescriptor { SerialNumber = 6655321 }; service.Store("Hello", descriptor1); - var descriptor2 = new ShellTopologyDescriptor { SerialNumber = 42 }; + var descriptor2 = new ShellDescriptor { SerialNumber = 42 }; service.Store("Hello", descriptor2); var result = service.Fetch("Hello"); Assert.That(result, Is.Not.Null); @@ -64,9 +64,9 @@ namespace Orchard.Tests.Environment.Topology { [Test] public void StoreNullWillClearEntry() { - var service = _container.Resolve(); + var service = _container.Resolve(); - var descriptor1 = new ShellTopologyDescriptor { SerialNumber = 6655321 }; + var descriptor1 = new ShellDescriptor { SerialNumber = 6655321 }; service.Store("Hello", descriptor1); var result1 = service.Fetch("Hello"); Assert.That(result1, Is.Not.Null); @@ -79,17 +79,17 @@ namespace Orchard.Tests.Environment.Topology { [Test] public void AllDataWillRoundTrip() { - var service = _container.Resolve(); + var service = _container.Resolve(); - var descriptor = new ShellTopologyDescriptor { + var descriptor = new ShellDescriptor { SerialNumber = 6655321, EnabledFeatures = new[] { - new TopologyFeature { Name = "f2"}, - new TopologyFeature { Name = "f4"}, + new ShellFeature { Name = "f2"}, + new ShellFeature { Name = "f4"}, }, Parameters = new[] { - new TopologyParameter {Component = "p1", Name = "p2",Value = "p3"}, - new TopologyParameter {Component = "p4",Name = "p5", Value = "p6"}, + new ShellParameter {Component = "p1", Name = "p2",Value = "p3"}, + new ShellParameter {Component = "p4",Name = "p5", Value = "p6"}, }, }; var descriptorInfo = descriptor.ToDataString(); @@ -107,7 +107,7 @@ namespace Orchard.Tests.Environment.Topology { static class DataContractExtensions { public static string ToDataString(this T obj) { - var serializer = new DataContractSerializer(typeof(ShellTopologyDescriptor)); + var serializer = new DataContractSerializer(typeof(ShellDescriptor)); var writer = new StringWriter(); using (var xmlWriter = XmlWriter.Create(writer)) { serializer.WriteObject(xmlWriter, obj); diff --git a/src/Orchard.Web/Core/Settings/Module.txt b/src/Orchard.Web/Core/Settings/Module.txt index d1451d2e0..fe53403bc 100644 --- a/src/Orchard.Web/Core/Settings/Module.txt +++ b/src/Orchard.Web/Core/Settings/Module.txt @@ -1,2 +1,5 @@ name: Settings -antiforgery: enabled \ No newline at end of file +antiforgery: enabled +features: + Settings: + description: Site configuration support diff --git a/src/Orchard.Web/Core/Settings/Topology/TopologyDescriptorManager.cs b/src/Orchard.Web/Core/Settings/Topology/ShellDescriptorManager.cs similarity index 100% rename from src/Orchard.Web/Core/Settings/Topology/TopologyDescriptorManager.cs rename to src/Orchard.Web/Core/Settings/Topology/ShellDescriptorManager.cs diff --git a/src/Orchard/Environment/ShellBuilders/ShellContextFactory.cs b/src/Orchard/Environment/ShellBuilders/ShellContextFactory.cs index d1fae0557..5d37735a6 100644 --- a/src/Orchard/Environment/ShellBuilders/ShellContextFactory.cs +++ b/src/Orchard/Environment/ShellBuilders/ShellContextFactory.cs @@ -7,7 +7,7 @@ using Orchard.Logging; namespace Orchard.Environment.ShellBuilders { - public interface IShellContextFactory { + public interface IShellContextFactory { ShellContext Create(ShellSettings settings); } @@ -35,18 +35,13 @@ namespace Orchard.Environment.ShellBuilders { Logger.Debug("Creating shell context for tenant {0}", settings.Name); - var cachedDescriptor = _topologyDescriptorCache.Fetch(settings.Name); - if (cachedDescriptor == null) { + var knownDescriptor = _topologyDescriptorCache.Fetch(settings.Name); + if (knownDescriptor == null) { Logger.Information("No topology cached. Starting with minimum components."); - cachedDescriptor = new ShellTopologyDescriptor { - SerialNumber = 0, - EnabledFeatures = Enumerable.Empty(), - Parameters = Enumerable.Empty(), - }; + knownDescriptor = MinimumTopologyDescriptor(); } - // handle null-(e.g. cache miss) - var topology = _compositionStrategy.Compose(cachedDescriptor); + var topology = _compositionStrategy.Compose(knownDescriptor); var shellScope = _shellContainerFactory.CreateContainer(settings, topology); ShellTopologyDescriptor currentDescriptor; @@ -55,7 +50,7 @@ namespace Orchard.Environment.ShellBuilders { currentDescriptor = topologyDescriptorProvider.GetTopologyDescriptor(); } - if (cachedDescriptor.SerialNumber != currentDescriptor.SerialNumber) { + if (currentDescriptor != null && knownDescriptor.SerialNumber != currentDescriptor.SerialNumber) { Logger.Information("Newer topology obtained. Rebuilding shell container."); _topologyDescriptorCache.Store(settings.Name, currentDescriptor); @@ -72,6 +67,17 @@ namespace Orchard.Environment.ShellBuilders { }; } + private static ShellTopologyDescriptor MinimumTopologyDescriptor() { + return new ShellTopologyDescriptor { + SerialNumber = -1, + EnabledFeatures = new[] { + new TopologyFeature {Name = "Orchard.Framework"}, + new TopologyFeature {Name = "Settings"}, + }, + Parameters = Enumerable.Empty(), + }; + } + private ShellContext CreateSetupContext() { Logger.Warning("No shell settings available. Creating shell context for setup"); diff --git a/src/Orchard/Environment/Topology/ITopologyDescriptorManager.cs b/src/Orchard/Environment/Topology/IShellDescriptorManager.cs similarity index 73% rename from src/Orchard/Environment/Topology/ITopologyDescriptorManager.cs rename to src/Orchard/Environment/Topology/IShellDescriptorManager.cs index 769eb7cdb..1a539c8c9 100644 --- a/src/Orchard/Environment/Topology/ITopologyDescriptorManager.cs +++ b/src/Orchard/Environment/Topology/IShellDescriptorManager.cs @@ -5,23 +5,23 @@ namespace Orchard.Environment.Topology { /// /// Service resolved out of the shell container. Primarily used by host. /// - public interface ITopologyDescriptorManager { + public interface IShellDescriptorManager : IDependency { /// /// Uses shell-specific database or other resources to return /// the current "correct" configuration. The host will use this information /// to reinitialize the shell. /// - ShellTopologyDescriptor GetTopologyDescriptor(); + ShellDescriptor GetShellDescriptor(); /// /// Alters databased information to match information passed as arguments. /// Prior SerialNumber used for optomistic concurrency, and an exception /// should be thrown if the number in storage doesn't match what's provided. /// - void UpdateTopologyDescriptor( + void UpdateShellDescriptor( int priorSerialNumber, - IEnumerable enabledFeatures, - IEnumerable parameters); + IEnumerable enabledFeatures, + IEnumerable parameters); } diff --git a/src/Orchard/Environment/Topology/Models/ShellDescriptor.cs b/src/Orchard/Environment/Topology/Models/ShellDescriptor.cs new file mode 100644 index 000000000..9b9da6365 --- /dev/null +++ b/src/Orchard/Environment/Topology/Models/ShellDescriptor.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Orchard.Environment.Topology.Models { + public class ShellDescriptor { + public ShellDescriptor() { + EnabledFeatures = Enumerable.Empty(); + Parameters = Enumerable.Empty(); + } + + public int SerialNumber { get; set; } + public IEnumerable EnabledFeatures { get; set; } + public IEnumerable Parameters { get; set; } + } + + public class ShellFeature { + public string Name { get; set; } + } + + public class ShellParameter { + public string Component { get; set; } + public string Name { get; set; } + public string Value { get; set; } + } +} diff --git a/src/Orchard/Environment/Topology/Models/ShellTopologyDescriptor.cs b/src/Orchard/Environment/Topology/Models/ShellTopologyDescriptor.cs deleted file mode 100644 index dd93919b2..000000000 --- a/src/Orchard/Environment/Topology/Models/ShellTopologyDescriptor.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace Orchard.Environment.Topology.Models { - public class ShellTopologyDescriptor { - public ShellTopologyDescriptor() { - EnabledFeatures = Enumerable.Empty(); - Parameters = Enumerable.Empty(); - } - - public int SerialNumber { get; set; } - public IEnumerable EnabledFeatures { get; set; } - public IEnumerable Parameters { get; set; } - } - - public class TopologyFeature { - public string Name { get; set; } - } - - public class TopologyParameter { - public string Component { get; set; } - public string Name { get; set; } - public string Value { get; set; } - } -} diff --git a/src/Orchard/Environment/Topology/TopologyDescriptorCache.cs b/src/Orchard/Environment/Topology/ShellDescriptorCache.cs similarity index 100% rename from src/Orchard/Environment/Topology/TopologyDescriptorCache.cs rename to src/Orchard/Environment/Topology/ShellDescriptorCache.cs