diff --git a/src/Umbraco.Core/CoreBootManager.cs b/src/Umbraco.Core/CoreBootManager.cs index 59bda786c9..1a8f72e356 100644 --- a/src/Umbraco.Core/CoreBootManager.cs +++ b/src/Umbraco.Core/CoreBootManager.cs @@ -404,18 +404,16 @@ namespace Umbraco.Core ServerRegistrarResolver.Current = new ServerRegistrarResolver( new ConfigServerRegistrar()); - //by default (outside of the web) we'll use the default server messenger without - //supplying a username/password, this will automatically disable distributed calls - // .. we'll override this in the WebBootManager + //by default we'll use the database server messenger with default options (no callbacks), + // this will be overridden in the web startup ServerMessengerResolver.Current = new ServerMessengerResolver( - new WebServiceServerMessenger()); + new DatabaseServerMessenger(ApplicationContext, true, new DatabaseServerMessengerOptions())); MappingResolver.Current = new MappingResolver( ServiceProvider, LoggerResolver.Current.Logger, () => PluginManager.ResolveAssignedMapperTypes()); - //RepositoryResolver.Current = new RepositoryResolver( // new RepositoryFactory(ApplicationCache)); diff --git a/src/Umbraco.Core/Sync/BatchedDatabaseServerMessenger.cs b/src/Umbraco.Core/Sync/BatchedDatabaseServerMessenger.cs deleted file mode 100644 index b16caa8779..0000000000 --- a/src/Umbraco.Core/Sync/BatchedDatabaseServerMessenger.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; -using Umbraco.Core.Models.Rdbms; -using umbraco.interfaces; - -namespace Umbraco.Core.Sync -{ - /// - /// An that works by storing messages in the database. - /// - /// - /// abstract because it needs to be inherited by a class that will - /// - trigger FlushBatch() when appropriate - /// - trigger Boot() when appropriate - /// - trigger Sync() when appropriate - /// - public abstract class BatchedDatabaseServerMessenger : DatabaseServerMessenger - { - - protected BatchedDatabaseServerMessenger(ApplicationContext appContext, bool enableDistCalls, DatabaseServerMessengerOptions options) - : base(appContext, enableDistCalls, options) - { - - } - - protected abstract ICollection GetBatch(bool ensureHttpContext); - - public void FlushBatch() - { - var batch = GetBatch(false); - if (batch == null) return; - - var instructions = batch.SelectMany(x => x.Instructions).ToArray(); - batch.Clear(); - if (instructions.Length == 0) return; - - var dto = new CacheInstructionDto - { - UtcStamp = DateTime.UtcNow, - Instructions = JsonConvert.SerializeObject(instructions, Formatting.None), - OriginIdentity = LocalIdentity - }; - - ApplicationContext.DatabaseContext.Database.Insert(dto); - } - - protected override void DeliverRemote(IEnumerable servers, ICacheRefresher refresher, MessageType messageType, IEnumerable ids = null, string json = null) - { - var idsA = ids == null ? null : ids.ToArray(); - - Type arrayType; - if (GetArrayType(idsA, out arrayType) == false) - throw new ArgumentException("All items must be of the same type, either int or Guid.", "ids"); - - BatchMessage(servers, refresher, messageType, idsA, arrayType, json); - } - - protected void BatchMessage( - IEnumerable servers, - ICacheRefresher refresher, - MessageType messageType, - IEnumerable ids = null, - Type idType = null, - string json = null) - { - var batch = GetBatch(true); - if (batch == null) - throw new Exception("Failed to get a batch."); - - batch.Add(new RefreshInstructionEnvelope(servers, refresher, - RefreshInstruction.GetInstructions(refresher, messageType, ids, idType, json))); - } - } -} diff --git a/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs b/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs index 4081bfc7c3..57f0907e10 100644 --- a/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs +++ b/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs @@ -21,15 +21,11 @@ namespace Umbraco.Core.Sync /// An that works by storing messages in the database. /// // - // abstract because it needs to be inherited by a class that will - // - trigger Boot() when appropriate - // - trigger Sync() when appropriate - // // this messenger writes ALL instructions to the database, // but only processes instructions coming from remote servers, // thus ensuring that instructions run only once // - public abstract class DatabaseServerMessenger : ServerMessengerBase + public class DatabaseServerMessenger : ServerMessengerBase { private readonly ApplicationContext _appContext; private readonly DatabaseServerMessengerOptions _options; @@ -45,7 +41,7 @@ namespace Umbraco.Core.Sync protected ApplicationContext ApplicationContext { get { return _appContext; } } - protected DatabaseServerMessenger(ApplicationContext appContext, bool distributedEnabled, DatabaseServerMessengerOptions options) + public DatabaseServerMessenger(ApplicationContext appContext, bool distributedEnabled, DatabaseServerMessengerOptions options) : base(distributedEnabled) { if (appContext == null) throw new ArgumentNullException("appContext"); diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 045877d52f..9256e00a2c 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -1238,7 +1238,6 @@ - diff --git a/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs b/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs index 38de7ef3cc..1e4f94a3c0 100644 --- a/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs +++ b/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs @@ -1,8 +1,12 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Web; +using Newtonsoft.Json; +using umbraco.interfaces; using Umbraco.Core; using Umbraco.Core.Logging; +using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Sync; using Umbraco.Web.Routing; @@ -14,7 +18,7 @@ namespace Umbraco.Web /// /// This binds to appropriate umbraco events in order to trigger the Boot(), Sync() & FlushBatch() calls /// - public class BatchedDatabaseServerMessenger : Core.Sync.BatchedDatabaseServerMessenger + public class BatchedDatabaseServerMessenger : Core.Sync.DatabaseServerMessenger { public BatchedDatabaseServerMessenger(ApplicationContext appContext, bool enableDistCalls, DatabaseServerMessengerOptions options) : base(appContext, enableDistCalls, options) @@ -66,7 +70,37 @@ namespace Umbraco.Web FlushBatch(); } - protected override ICollection GetBatch(bool ensureHttpContext) + protected override void DeliverRemote(IEnumerable servers, ICacheRefresher refresher, MessageType messageType, IEnumerable ids = null, string json = null) + { + var idsA = ids == null ? null : ids.ToArray(); + + Type arrayType; + if (GetArrayType(idsA, out arrayType) == false) + throw new ArgumentException("All items must be of the same type, either int or Guid.", "ids"); + + BatchMessage(servers, refresher, messageType, idsA, arrayType, json); + } + + public void FlushBatch() + { + var batch = GetBatch(false); + if (batch == null) return; + + var instructions = batch.SelectMany(x => x.Instructions).ToArray(); + batch.Clear(); + if (instructions.Length == 0) return; + + var dto = new CacheInstructionDto + { + UtcStamp = DateTime.UtcNow, + Instructions = JsonConvert.SerializeObject(instructions, Formatting.None), + OriginIdentity = LocalIdentity + }; + + ApplicationContext.DatabaseContext.Database.Insert(dto); + } + + protected ICollection GetBatch(bool ensureHttpContext) { var httpContext = UmbracoContext.Current == null ? null : UmbracoContext.Current.HttpContext; if (httpContext == null) @@ -84,5 +118,21 @@ namespace Umbraco.Web httpContext.Items[key] = batch = new List(); return batch; } + + protected void BatchMessage( + IEnumerable servers, + ICacheRefresher refresher, + MessageType messageType, + IEnumerable ids = null, + Type idType = null, + string json = null) + { + var batch = GetBatch(true); + if (batch == null) + throw new Exception("Failed to get a batch."); + + batch.Add(new RefreshInstructionEnvelope(servers, refresher, + RefreshInstruction.GetInstructions(refresher, messageType, ids, idType, json))); + } } } \ No newline at end of file diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index 99bdaada4c..497056a518 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -329,32 +329,60 @@ namespace Umbraco.Web //set the default RenderMvcController DefaultRenderMvcControllerResolver.Current = new DefaultRenderMvcControllerResolver(typeof(RenderMvcController)); - ServerMessengerResolver.Current.SetServerMessenger(new BatchedWebServiceServerMessenger(() => + //Override the default server messenger, we need to check if the legacy dist calls is enabled, if that is the + // case, then we'll set the default messenger to be the old one, otherwise we'll set it to the db messenger + // which will always be on. + if (UmbracoConfig.For.UmbracoSettings().DistributedCall.Enabled) { - //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) + //set the legacy one by default - this maintains backwards compat + ServerMessengerResolver.Current.SetServerMessenger(new BatchedWebServiceServerMessenger(() => { - //disable if they are not enabled - if (UmbracoConfig.For.UmbracoSettings().DistributedCall.Enabled == false) + //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) { - return null; - } + //disable if they are not enabled + if (UmbracoConfig.For.UmbracoSettings().DistributedCall.Enabled == false) + { + return null; + } - try - { - var user = User.GetUser(UmbracoConfig.For.UmbracoSettings().DistributedCall.UserId); - return new System.Tuple(user.LoginName, user.GetPassword()); + try + { + var user = ApplicationContext.Services.UserService.GetUserById(UmbracoConfig.For.UmbracoSettings().DistributedCall.UserId); + return new Tuple(user.Username, user.RawPasswordValue); + } + catch (Exception e) + { + LoggerResolver.Current.Logger.Error("An error occurred trying to set the IServerMessenger during application startup", e); + return null; + } } - catch (Exception e) + LoggerResolver.Current.Logger.Warn("Could not initialize the DefaultServerMessenger, the application is not configured or the database is not configured"); + return null; + })); + } + else + { + 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[] { - LoggerResolver.Current.Logger.Error("An error occurred trying to set the IServerMessenger during application startup", e); - return null; + //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. + () => Examine.ExamineManager.Instance.RebuildIndex() } - } - LoggerResolver.Current.Logger.Warn("Could not initialize the DefaultServerMessenger, the application is not configured or the database is not configured"); - return null; - })); + })); + } SurfaceControllerResolver.Current = new SurfaceControllerResolver( ServiceProvider, LoggerResolver.Current.Logger,