diff --git a/src/Umbraco.Core/Persistence/Mappers/MappingResolver.cs b/src/Umbraco.Core/Persistence/Mappers/MappingResolver.cs index 6aa6d8f368..abb220a66c 100644 --- a/src/Umbraco.Core/Persistence/Mappers/MappingResolver.cs +++ b/src/Umbraco.Core/Persistence/Mappers/MappingResolver.cs @@ -22,6 +22,7 @@ namespace Umbraco.Core.Persistence.Mappers { return MapperCache.GetOrAdd(type, type1 => { + var mappers = TypeFinder.FindClassesOfTypeWithAttribute(); //first check if we can resolve it by attribute diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixOneZero/CreateServerRegistryTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixOneZero/CreateServerRegistryTable.cs index 61c757332b..757e5fd4f0 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixOneZero/CreateServerRegistryTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSixOneZero/CreateServerRegistryTable.cs @@ -7,19 +7,17 @@ using Umbraco.Core.Models.Rdbms; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSixOneZero { - //NOTE: SD: Commenting out for now until we want to release a distributed cache provider that - // uses internal DNS names for each website to 'call' home intead of the current configuration based approach. + + [Migration("6.1.0", 0, GlobalSettings.UmbracoMigrationName)] + public class CreateServerRegistryTable : MigrationBase + { + public override void Up() + { + base.Context.Database.CreateTable(); + } - //[Migration("6.1.0", 0, GlobalSettings.UmbracoMigrationName)] - //public class CreateServerRegistryTable : MigrationBase - //{ - // public override void Up() - // { - // base.Context.Database.CreateTable(); - // } - - // public override void Down() - // { - // } - //} + public override void Down() + { + } + } } diff --git a/src/Umbraco.Core/Services/ServiceContext.cs b/src/Umbraco.Core/Services/ServiceContext.cs index 3ea667cb89..7d7d877a86 100644 --- a/src/Umbraco.Core/Services/ServiceContext.cs +++ b/src/Umbraco.Core/Services/ServiceContext.cs @@ -20,10 +20,7 @@ namespace Umbraco.Core.Services private Lazy _dataTypeService; private Lazy _fileService; private Lazy _localizationService; - - //NOTE: SD: Commenting out for now until we want to release a distributed cache provider that - // uses internal DNS names for each website to 'call' home intead of the current configuration based approach. - //private Lazy _serverRegistrationService; + private Lazy _serverRegistrationService; /// /// Constructor @@ -51,10 +48,8 @@ namespace Umbraco.Core.Services var provider = dbUnitOfWorkProvider; var fileProvider = fileUnitOfWorkProvider; - //NOTE: SD: Commenting out for now until we want to release a distributed cache provider that - // uses internal DNS names for each website to 'call' home intead of the current configuration based approach. - //if (_serverRegistrationService == null) - // _serverRegistrationService = new Lazy(() => new ServerRegistrationService(provider, repositoryFactory.Value)); + if (_serverRegistrationService == null) + _serverRegistrationService = new Lazy(() => new ServerRegistrationService(provider, repositoryFactory.Value)); if (_userService == null) _userService = new Lazy(() => new UserService(provider, repositoryFactory.Value)); @@ -81,16 +76,13 @@ namespace Umbraco.Core.Services _localizationService = new Lazy(() => new LocalizationService(provider, repositoryFactory.Value)); } - //NOTE: SD: Commenting out for now until we want to release a distributed cache provider that - // uses internal DNS names for each website to 'call' home intead of the current configuration based approach. - - ///// - ///// Gets the - ///// - //internal ServerRegistrationService ServerRegistrationService - //{ - // get { return _serverRegistrationService.Value; } - //} + /// + /// Gets the + /// + internal ServerRegistrationService ServerRegistrationService + { + get { return _serverRegistrationService.Value; } + } /// /// Gets the diff --git a/src/Umbraco.Core/Sync/DatabaseServerRegistrar.cs b/src/Umbraco.Core/Sync/DatabaseServerRegistrar.cs index 3ddbf6e9d1..5c487d8a3f 100644 --- a/src/Umbraco.Core/Sync/DatabaseServerRegistrar.cs +++ b/src/Umbraco.Core/Sync/DatabaseServerRegistrar.cs @@ -3,24 +3,22 @@ using Umbraco.Core.Services; namespace Umbraco.Core.Sync { - //NOTE: SD: Commenting out for now until we want to release a distributed cache provider that - // uses internal DNS names for each website to 'call' home intead of the current configuration based approach. + + /// + /// A registrar that stores registered server nodes in a database + /// + internal class DatabaseServerRegistrar : IServerRegistrar + { + private readonly ServerRegistrationService _registrationService; - ///// - ///// A registrar that stores registered server nodes in a database - ///// - //internal class DatabaseServerRegistrar : IServerRegistrar - //{ - // private readonly ServerRegistrationService _registrationService; + public DatabaseServerRegistrar(ServerRegistrationService registrationService) + { + _registrationService = registrationService; + } - // public DatabaseServerRegistrar(ServerRegistrationService registrationService) - // { - // _registrationService = registrationService; - // } - - // public IEnumerable Registrations - // { - // get { return _registrationService.GetActiveServers(); } - // } - //} + public IEnumerable Registrations + { + get { return _registrationService.GetActiveServers(); } + } + } } \ No newline at end of file diff --git a/src/Umbraco.Web/Strategies/ServerRegistrationEventHandler.cs b/src/Umbraco.Web/Strategies/ServerRegistrationEventHandler.cs index 905618f7ed..c1d38d1d55 100644 --- a/src/Umbraco.Web/Strategies/ServerRegistrationEventHandler.cs +++ b/src/Umbraco.Web/Strategies/ServerRegistrationEventHandler.cs @@ -1,146 +1,146 @@ - -//NOTE: SD: Commenting out for now until we want to release a distributed cache provider that -// uses internal DNS names for each website to 'call' home intead of the current configuration based approach. +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Web; +using Umbraco.Core; +using Umbraco.Core.Configuration; +using Umbraco.Core.Logging; +using Umbraco.Core.Sync; +using Umbraco.Web.Routing; + +namespace Umbraco.Web.Strategies +{ + /// + /// This will ensure that the server is automatically registered in the database as an active node + /// on application startup and whenever a back office request occurs. + /// + /// + /// We do this on app startup to ensure that the server is in the database but we also do it for the first 'x' times + /// a back office request is made so that we can tell if they are using https protocol which would update to that address + /// in the database. The first front-end request probably wouldn't be an https request. + /// + /// For back office requests (so that we don't constantly make db calls), we'll only update the database when we detect at least + /// a timespan of 1 minute between requests. + /// + public sealed class ServerRegistrationEventHandler : ApplicationEventHandler + { + private static bool _initUpdated = false; + private static DateTime _lastUpdated = DateTime.MinValue; + private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim(); + + /// + /// Update the database with this entry and bind to request events + /// + /// + /// + protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + //no need to bind to the event if we are not actually using the database server registrar + if (ServerRegistrarResolver.Current.Registrar is DatabaseServerRegistrar) + { + //bind to event + UmbracoModule.RouteAttempt += UmbracoModuleRouteAttempt; + } + } -//using System; -//using System.Collections.Generic; -//using System.Linq; -//using System.Text; -//using System.Threading; -//using System.Web; -//using Umbraco.Core; -//using Umbraco.Core.Configuration; -//using Umbraco.Core.Logging; -//using Umbraco.Web.Routing; + static void UmbracoModuleRouteAttempt(object sender, Routing.RoutableAttemptEventArgs e) + { + if (e.HttpContext.Request == null || e.HttpContext.Request.Url == null) return; -//namespace Umbraco.Web.Strategies -//{ -// /// -// /// This will ensure that the server is automatically registered in the database as an active node -// /// on application startup and whenever a back office request occurs. -// /// -// /// -// /// We do this on app startup to ensure that the server is in the database but we also do it for the first 'x' times -// /// a back office request is made so that we can tell if they are using https protocol which would update to that address -// /// in the database. The first front-end request probably wouldn't be an https request. -// /// -// /// For back office requests (so that we don't constantly make db calls), we'll only update the database when we detect at least -// /// a timespan of 1 minute between requests. -// /// -// public sealed class ServerRegistrationEventHandler : ApplicationEventHandler -// { -// private static bool _initUpdated = false; -// private static DateTime _lastUpdated = DateTime.MinValue; -// private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim(); + if (e.Outcome == EnsureRoutableOutcome.IsRoutable) + { + using (var lck = new UpgradeableReadLock(Locker)) + { + //we only want to do the initial update once + if (!_initUpdated) + { + lck.UpgradeToWriteLock(); + _initUpdated = true; + UpdateServerEntry(e.HttpContext, e.UmbracoContext.Application); + return; + } + } + } -// /// -// /// Update the database with this entry and bind to request events -// /// -// /// -// /// -// protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) -// { -// //bind to event -// UmbracoModule.RouteAttempt += UmbracoModuleRouteAttempt; -// } + //if it is not a document request, we'll check if it is a back end request + if (e.Outcome == EnsureRoutableOutcome.NotDocumentRequest) + { + var authority = e.HttpContext.Request.Url.GetLeftPart(UriPartial.Authority); + var afterAuthority = e.HttpContext.Request.Url.GetLeftPart(UriPartial.Query) + .TrimStart(authority) + .TrimStart("/"); + + //check if this is in the umbraco back office + if (afterAuthority.InvariantStartsWith(GlobalSettings.Path.TrimStart("/"))) + { + //yup it's a back office request! + using (var lck = new UpgradeableReadLock(Locker)) + { + //we don't want to update if it's not been at least a minute since last time + var isItAMinute = DateTime.Now.Subtract(_lastUpdated).TotalSeconds >= 60; + if (isItAMinute) + { + lck.UpgradeToWriteLock(); + _initUpdated = true; + _lastUpdated = DateTime.Now; + UpdateServerEntry(e.HttpContext, e.UmbracoContext.Application); + } + } + } + } + } -// static void UmbracoModuleRouteAttempt(object sender, Routing.RoutableAttemptEventArgs e) -// { -// if (e.HttpContext.Request == null || e.HttpContext.Request.Url == null) return; + private static void UpdateServerEntry(HttpContextBase httpContext, ApplicationContext applicationContext) + { + try + { + //var asdf = GetBindings(httpContext); + var address = httpContext.Request.Url.GetLeftPart(UriPartial.Authority); + applicationContext.Services.ServerRegistrationService.EnsureActive(address); + } + catch (Exception e) + { + LogHelper.Error("Failed to update server record in database.", e); + } + } -// if (e.Outcome == EnsureRoutableOutcome.IsRoutable) -// { -// using (var lck = new UpgradeableReadLock(Locker)) -// { -// //we only want to do the initial update once -// if (!_initUpdated) -// { -// lck.UpgradeToWriteLock(); -// _initUpdated = true; -// UpdateServerEntry(e.HttpContext, e.UmbracoContext.Application); -// return; -// } -// } -// } + //private static IEnumerable> GetBindings(HttpContextBase context) + //{ + // // Get the Site name + // string siteName = System.Web.Hosting.HostingEnvironment.SiteName; -// //if it is not a document request, we'll check if it is a back end request -// if (e.Outcome == EnsureRoutableOutcome.NotDocumentRequest) -// { -// var authority = e.HttpContext.Request.Url.GetLeftPart(UriPartial.Authority); -// var afterAuthority = e.HttpContext.Request.Url.GetLeftPart(UriPartial.Query) -// .TrimStart(authority) -// .TrimStart("/"); + // // Get the sites section from the AppPool.config + // Microsoft.Web.Administration.ConfigurationSection sitesSection = + // Microsoft.Web.Administration.WebConfigurationManager.GetSection(null, null, "system.applicationHost/sites"); -// //check if this is in the umbraco back office -// if (afterAuthority.InvariantStartsWith(GlobalSettings.Path.TrimStart("/"))) -// { -// //yup it's a back office request! -// using (var lck = new UpgradeableReadLock(Locker)) -// { -// //we don't want to update if it's not been at least a minute since last time -// var isItAMinute = DateTime.Now.Subtract(_lastUpdated).TotalSeconds >= 60; -// if (isItAMinute) -// { -// lck.UpgradeToWriteLock(); -// _initUpdated = true; -// _lastUpdated = DateTime.Now; -// UpdateServerEntry(e.HttpContext, e.UmbracoContext.Application); -// } -// } -// } -// } -// } + // foreach (Microsoft.Web.Administration.ConfigurationElement site in sitesSection.GetCollection()) + // { + // // Find the right Site + // if (String.Equals((string)site["name"], siteName, StringComparison.OrdinalIgnoreCase)) + // { + // // For each binding see if they are http based and return the port and protocol + // foreach (Microsoft.Web.Administration.ConfigurationElement binding in site.GetCollection("bindings")) + // { + // string protocol = (string)binding["protocol"]; + // string bindingInfo = (string)binding["bindingInformation"]; -// private static void UpdateServerEntry(HttpContextBase httpContext, ApplicationContext applicationContext) -// { -// try -// { -// //var asdf = GetBindings(httpContext); -// var address = httpContext.Request.Url.GetLeftPart(UriPartial.Authority); -// applicationContext.Services.ServerRegistrationService.EnsureActive(address); -// } -// catch (Exception e) -// { -// LogHelper.Error("Failed to update server record in database.", e); -// } -// } - -// //private static IEnumerable> GetBindings(HttpContextBase context) -// //{ -// // // Get the Site name -// // string siteName = System.Web.Hosting.HostingEnvironment.SiteName; - -// // // Get the sites section from the AppPool.config -// // Microsoft.Web.Administration.ConfigurationSection sitesSection = -// // Microsoft.Web.Administration.WebConfigurationManager.GetSection(null, null, "system.applicationHost/sites"); - -// // foreach (Microsoft.Web.Administration.ConfigurationElement site in sitesSection.GetCollection()) -// // { -// // // Find the right Site -// // if (String.Equals((string)site["name"], siteName, StringComparison.OrdinalIgnoreCase)) -// // { - -// // // For each binding see if they are http based and return the port and protocol -// // foreach (Microsoft.Web.Administration.ConfigurationElement binding in site.GetCollection("bindings")) -// // { -// // string protocol = (string)binding["protocol"]; -// // string bindingInfo = (string)binding["bindingInformation"]; - -// // if (protocol.StartsWith("http", StringComparison.OrdinalIgnoreCase)) -// // { -// // string[] parts = bindingInfo.Split(':'); -// // if (parts.Length == 3) -// // { -// // string port = parts[1]; -// // yield return new KeyValuePair(protocol, port); -// // } -// // } -// // } -// // } -// // } -// //} -// } -//} + // if (protocol.StartsWith("http", StringComparison.OrdinalIgnoreCase)) + // { + // string[] parts = bindingInfo.Split(':'); + // if (parts.Length == 3) + // { + // string port = parts[1]; + // yield return new KeyValuePair(protocol, port); + // } + // } + // } + // } + // } + //} + } +}