Merge remote-tracking branch 'origin/master-v7' into dev-v7

Conflicts:
	build/UmbracoVersion.txt
	src/SolutionInfo.cs
	src/Umbraco.Core/Cache/FullDataSetRepositoryCachePolicy.cs
	src/Umbraco.Core/Cache/FullDataSetRepositoryCachePolicyFactory.cs
	src/Umbraco.Core/Configuration/UmbracoVersion.cs
	src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs
	src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs
	src/Umbraco.Core/Persistence/Repositories/DomainRepository.cs
	src/Umbraco.Core/Persistence/Repositories/LanguageRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs
	src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs
	src/Umbraco.Core/Persistence/Repositories/PublicAccessRepository.cs
	src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs
	src/Umbraco.Core/Umbraco.Core.csproj
	src/Umbraco.Tests/Cache/FullDataSetCachePolicyTests.cs
	src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js
	src/Umbraco.Web.UI.Client/src/less/hacks.less
	src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
	src/Umbraco.Web/WebBootManager.cs
This commit is contained in:
Shannon
2016-02-03 12:30:11 +01:00
50 changed files with 1213 additions and 611 deletions

View File

@@ -13,6 +13,7 @@ using System.Web.Routing;
using ClientDependency.Core.Config;
using Examine;
using Examine.Config;
using Examine.Providers;
using umbraco;
using Umbraco.Core;
using Umbraco.Core.Configuration;
@@ -53,13 +54,13 @@ using ProfilingViewEngine = Umbraco.Core.Profiling.ProfilingViewEngine;
namespace Umbraco.Web
{
/// <summary>
/// A bootstrapper for the Umbraco application which initializes all objects including the Web portion of the application
/// A bootstrapper for the Umbraco application which initializes all objects including the Web portion of the application
/// </summary>
public class WebBootManager : CoreBootManager
{
private readonly bool _isForTesting;
//NOTE: see the Initialize method for what this is used for
private readonly List<IIndexer> _indexesToRebuild = new List<IIndexer>();
private static readonly List<BaseIndexProvider> IndexesToRebuild = new List<BaseIndexProvider>();
public WebBootManager(UmbracoApplicationBase umbracoApplication)
: base(umbracoApplication)
@@ -147,7 +148,7 @@ namespace Umbraco.Web
{ "compositeFileHandlerPath", ClientDependencySettings.Instance.CompositeFileHandlerPath }
});
ClientDependencySettings.Instance.MvcRendererCollection.Add(renderer);
// Disable the X-AspNetMvc-Version HTTP Header
MvcHandler.DisableMvcResponseHeader = true;
@@ -156,9 +157,9 @@ namespace Umbraco.Web
return this;
}
/// <summary>
/// Override this method in order to ensure that the UmbracoContext is also created, this can only be
/// Override this method in order to ensure that the UmbracoContext is also created, this can only be
/// created after resolution is frozen!
/// </summary>
protected override void FreezeResolution()
@@ -172,8 +173,8 @@ namespace Umbraco.Web
httpContext,
ApplicationContext,
new WebSecurity(httpContext, ApplicationContext),
UmbracoConfig.For.UmbracoSettings(),
UrlProviderResolver.Current.Providers,
UmbracoConfig.For.UmbracoSettings(),
UrlProviderResolver.Current.Providers,
false);
}
@@ -183,13 +184,10 @@ namespace Umbraco.Web
protected override void InitializeProfilerResolver()
{
base.InitializeProfilerResolver();
//Set the profiler to be the web profiler
var profiler = new WebProfiler();
ProfilerResolver.Current.SetProfiler(profiler);
profiler.Start();
ProfilerResolver.Current.SetProfiler(new WebProfiler());
}
/// <summary>
/// Ensure that the OnApplicationStarted methods of the IApplicationEvents are called
/// </summary>
@@ -207,14 +205,14 @@ namespace Umbraco.Web
//Now, startup all of our legacy startup handler
ApplicationEventsResolver.Current.InstantiateLegacyStartupHandlers();
//Ok, now that everything is complete we'll check if we've stored any references to index that need rebuilding and run them
//Ok, now that everything is complete we'll check if we've stored any references to index that need rebuilding and run them
// (see the initialize method for notes) - we'll ensure we remove the event handler too in case examine manager doesn't actually
// initialize during startup, in which case we want it to rebuild the indexes itself.
ExamineManager.Instance.BuildingEmptyIndexOnStartup -= OnInstanceOnBuildingEmptyIndexOnStartup;
if (_indexesToRebuild.Any())
if (IndexesToRebuild.Any())
{
foreach (var indexer in _indexesToRebuild)
foreach (var indexer in IndexesToRebuild)
{
indexer.RebuildIndex();
}
@@ -246,14 +244,14 @@ namespace Umbraco.Web
{
//create a web-based cache helper
var cacheHelper = new CacheHelper(
//we need to have the dep clone runtime cache provider to ensure
//we need to have the dep clone runtime cache provider to ensure
//all entities are cached properly (cloned in and cloned out)
new DeepCloneRuntimeCacheProvider(new HttpRuntimeCacheProvider(HttpRuntime.Cache)),
new StaticCacheProvider(),
//we have no request based cache when not running in web-based context
new NullCacheProvider(),
new IsolatedRuntimeCache(type =>
//we need to have the dep clone runtime cache provider to ensure
//we need to have the dep clone runtime cache provider to ensure
//all entities are cached properly (cloned in and cloned out)
new DeepCloneRuntimeCacheProvider(new ObjectCacheRuntimeCacheProvider())));
@@ -284,7 +282,7 @@ namespace Umbraco.Web
//plugin controllers must come first because the next route will catch many things
RoutePluginControllers();
}
private void RoutePluginControllers()
{
var umbracoPath = GlobalSettings.UmbracoMvcArea;
@@ -351,14 +349,14 @@ namespace Umbraco.Web
umbracoPath + "/Surface/" + meta.ControllerName + "/{action}/{id}",//url to match
new { controller = meta.ControllerName, action = "Index", id = UrlParameter.Optional },
new[] { meta.ControllerNamespace }); //look in this namespace to create the controller
route.DataTokens.Add("umbraco", "surface"); //ensure the umbraco token is set
route.DataTokens.Add("umbraco", "surface"); //ensure the umbraco token is set
route.DataTokens.Add("UseNamespaceFallback", false); //Don't look anywhere else except this namespace!
//make it use our custom/special SurfaceMvcHandler
route.RouteHandler = new SurfaceRouteHandler();
}
/// <summary>
/// Initializes all web based and core resolves
/// Initializes all web based and core resolves
/// </summary>
protected override void InitializeResolvers()
{
@@ -379,7 +377,7 @@ namespace Umbraco.Web
//set the legacy one by default - this maintains backwards compat
ServerMessengerResolver.Current.SetServerMessenger(new BatchedWebServiceServerMessenger(() =>
{
//we should not proceed to change this if the app/database is not configured since there will
//we should not proceed to change this if the app/database is not configured since there will
// be no user, plus we don't need to have server messages sent if this is the case.
if (ApplicationContext.IsConfigured && ApplicationContext.DatabaseContext.IsDatabaseConfigured)
{
@@ -407,49 +405,40 @@ namespace Umbraco.Web
else
{
// NOTE: This is IMPORTANT! ... we don't want to rebuild any index that is already flagged to be re-indexed
// on startup based on our _indexesToRebuild variable and how Examine auto-rebuilds when indexes are empty
// this callback is used below for the DatabaseServerMessenger startup options
//We are using a custom action here so we can check the examine settings value first, we don't want to
// put that check into the CreateIndexesOnColdBoot method because developers may choose to use this
// method directly and they will be in charge of this check if they need it
Action rebuildIndexes = () =>
{
//If the developer has explicitly opted out of rebuilding indexes on startup then we
//If the developer has explicitly opted out of rebuilding indexes on startup then we
// should adhere to that and not do it, this means that if they are load balancing things will be
// out of sync if they are auto-scaling but there's not much we can do about that.
if (ExamineSettings.Instance.RebuildOnAppStart == false) return;
if (_indexesToRebuild.Any())
foreach (var indexer in GetIndexesForColdBoot())
{
var otherIndexes = ExamineManager.Instance.IndexProviderCollection.Except(_indexesToRebuild);
foreach (var otherIndex in otherIndexes)
{
otherIndex.RebuildIndex();
}
}
else
{
//rebuild them all
ExamineManager.Instance.RebuildIndex();
indexer.RebuildIndex();
}
};
ServerMessengerResolver.Current.SetServerMessenger(new BatchedDatabaseServerMessenger(
ApplicationContext,
true,
//Default options for web including the required callbacks to build caches
new DatabaseServerMessengerOptions
{
//These callbacks will be executed if the server has not been synced
// (i.e. it is a new server or the lastsynced.txt file has been removed)
InitializingCallbacks = new Action[]
ApplicationContext,
true,
//Default options for web including the required callbacks to build caches
new DatabaseServerMessengerOptions
{
//rebuild the xml cache file if the server is not synced
() => global::umbraco.content.Instance.RefreshContentFromDatabase(),
//rebuild indexes if the server is not synced
// NOTE: This will rebuild ALL indexes including the members, if developers want to target specific
// indexes then they can adjust this logic themselves.
rebuildIndexes
}
}));
//These callbacks will be executed if the server has not been synced
// (i.e. it is a new server or the lastsynced.txt file has been removed)
InitializingCallbacks = new Action[]
{
//rebuild the xml cache file if the server is not synced
() => global::umbraco.content.Instance.RefreshContentFromDatabase(),
//rebuild indexes if the server is not synced
// NOTE: This will rebuild ALL indexes including the members, if developers want to target specific
// indexes then they can adjust this logic themselves.
rebuildIndexes
}
}));
}
SurfaceControllerResolver.Current = new SurfaceControllerResolver(
@@ -474,7 +463,7 @@ namespace Umbraco.Web
new PublishedCache.XmlPublishedCache.PublishedContentCache(),
new PublishedCache.XmlPublishedCache.PublishedMediaCache(ApplicationContext)));
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector),
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector),
new NamespaceHttpControllerSelector(GlobalConfiguration.Configuration));
FilteredControllerFactoriesResolver.Current = new FilteredControllerFactoriesResolver(
@@ -537,12 +526,42 @@ namespace Umbraco.Web
new DefaultCultureDictionaryFactory());
}
/// <summary>
/// The method used to create indexes on a cold boot
/// </summary>
/// <remarks>
/// A cold boot is when the server determines it will not (or cannot) process instructions in the cache table and
/// will rebuild it's own caches itself.
/// </remarks>
public static IEnumerable<BaseIndexProvider> GetIndexesForColdBoot()
{
// NOTE: This is IMPORTANT! ... we don't want to rebuild any index that is already flagged to be re-indexed
// on startup based on our _indexesToRebuild variable and how Examine auto-rebuilds when indexes are empty.
// This callback is used above for the DatabaseServerMessenger startup options.
// all indexes
IEnumerable<BaseIndexProvider> indexes = ExamineManager.Instance.IndexProviderCollection;
// except those that are already flagged
// and are processed in Complete()
if (IndexesToRebuild.Any())
indexes = indexes.Except(IndexesToRebuild);
// return
foreach (var index in indexes)
yield return index;
// and clear
IndexesToRebuild.Clear();
}
private void OnInstanceOnBuildingEmptyIndexOnStartup(object sender, BuildingEmptyIndexOnStartupEventArgs args)
{
//store the indexer that needs rebuilding because it's empty for when the boot process
//store the indexer that needs rebuilding because it's empty for when the boot process
// is complete and cancel this current event so the rebuild process doesn't start right now.
args.Cancel = true;
_indexesToRebuild.Add(args.Indexer);
IndexesToRebuild.Add((BaseIndexProvider)args.Indexer);
}
}
}