From 1d1c45c7a6710f02779365d6619eba0a9017fd9f Mon Sep 17 00:00:00 2001 From: Kevin Jump Date: Fri, 27 Sep 2019 16:17:17 +0100 Subject: [PATCH 1/4] Working around the issues you get trying to work with content at startup. --- uSync8.BackOffice/uSync8BackOffice.cs | 2 + uSync8.BackOffice/uSyncBackofficeComponent.cs | 47 ++++++---- .../Serializers/ContentSerializer.cs | 92 +++++++++++-------- 3 files changed, 87 insertions(+), 54 deletions(-) diff --git a/uSync8.BackOffice/uSync8BackOffice.cs b/uSync8.BackOffice/uSync8BackOffice.cs index 47bc2797..12728dca 100644 --- a/uSync8.BackOffice/uSync8BackOffice.cs +++ b/uSync8.BackOffice/uSync8BackOffice.cs @@ -9,6 +9,8 @@ namespace uSync8.BackOffice public class uSync8BackOffice { public static bool eventsPaused { get; set; } + + public static bool inStartup { get; set; } } internal class uSync diff --git a/uSync8.BackOffice/uSyncBackofficeComponent.cs b/uSync8.BackOffice/uSyncBackofficeComponent.cs index c260accc..2ea236b3 100644 --- a/uSync8.BackOffice/uSyncBackofficeComponent.cs +++ b/uSync8.BackOffice/uSyncBackofficeComponent.cs @@ -30,13 +30,13 @@ public class uSyncBackofficeComponent : IComponent public uSyncBackofficeComponent( SyncHandlerFactory handlerFactory, IProfilingLogger logger, - SyncFileService fileService, + SyncFileService fileService, uSyncService uSyncService, IRuntimeState runtimeState) { globalSettings = Current.Configs.uSync(); - this.runtimeState = runtimeState; + this.runtimeState = runtimeState; this.logger = logger; this.handlerFactory = handlerFactory; @@ -82,28 +82,41 @@ private void ServerVariablesParser_Parsing(object sender, Dictionary($"Starting up Handler {syncHandler.Handler.Name}"); - syncHandler.Handler.Initialize(syncHandler.Settings); + var handlers = handlerFactory.GetValidHandlers(new SyncHandlerOptions(handlerFactory.DefaultSet, HandlerActions.Save)); + + foreach (var syncHandler in handlers) + { + logger.Debug($"Starting up Handler {syncHandler.Handler.Name}"); + syncHandler.Handler.Initialize(syncHandler.Settings); + } } } + catch(Exception ex) + { + logger.Warn($"Error Importing at startup {ex.Message}"); + } + finally + { + uSync8BackOffice.inStartup = true; + } } diff --git a/uSync8.ContentEdition/Serializers/ContentSerializer.cs b/uSync8.ContentEdition/Serializers/ContentSerializer.cs index a69be074..df97f5f3 100644 --- a/uSync8.ContentEdition/Serializers/ContentSerializer.cs +++ b/uSync8.ContentEdition/Serializers/ContentSerializer.cs @@ -9,6 +9,7 @@ using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; using Umbraco.Core.Services; +using uSync8.BackOffice; using uSync8.ContentEdition.Mapping; using uSync8.Core; using uSync8.Core.Extensions; @@ -195,59 +196,65 @@ protected override void HandleTrashedState(IContent item, bool trashed) protected virtual Attempt DoSaveOrPublish(IContent item, XElement node) { - - var publishedNode = node.Element("Info")?.Element("Published"); - if (publishedNode != null) + // at the moment <= 8.1.5 we can't publish during startup. + if (!uSync8BackOffice.inStartup) { - if (publishedNode.HasElements) + var publishedNode = node.Element("Info")?.Element("Published"); + if (publishedNode != null) { - // culture based publishing. - var publishedCultures = new List(); - foreach (var culturePublish in publishedNode.Elements("Published")) + if (publishedNode.HasElements) { - var culture = culturePublish.Attribute("Culture").ValueOrDefault(string.Empty); - var status = culturePublish.ValueOrDefault(false); - - if (!string.IsNullOrWhiteSpace(culture) && status) + // culture based publishing. + var publishedCultures = new List(); + foreach (var culturePublish in publishedNode.Elements("Published")) { - publishedCultures.Add(culture); + var culture = culturePublish.Attribute("Culture").ValueOrDefault(string.Empty); + var status = culturePublish.ValueOrDefault(false); + + if (!string.IsNullOrWhiteSpace(culture) && status) + { + publishedCultures.Add(culture); + } } - } - if (publishedCultures.Count > 0) - { - var culturePublishResult = contentService.SaveAndPublish(item, publishedCultures.ToArray()); - if (culturePublishResult.Success) - return Attempt.Succeed($"Published {publishedCultures.Count} Cultures"); + if (publishedCultures.Count > 0) + { + var culturePublishResult = contentService.SaveAndPublish(item, publishedCultures.ToArray()); + if (culturePublishResult.Success) + return Attempt.Succeed($"Published {publishedCultures.Count} Cultures"); - return Attempt.Fail("Publish Failed " + culturePublishResult.EventMessages); + return Attempt.Fail("Publish Failed " + culturePublishResult.EventMessages); + } } - } - else - { - // default publish the lot. - if (publishedNode.Attribute("Default").ValueOrDefault(false)) + else { - var publishResult = contentService.SaveAndPublish(item); - if (publishResult.Success) - return Attempt.Succeed("Published"); + // default publish the lot. + if (publishedNode.Attribute("Default").ValueOrDefault(false)) + { + var publishResult = contentService.SaveAndPublish(item); + if (publishResult.Success) + return Attempt.Succeed("Published"); - return Attempt.Fail("Publish Failed " + publishResult.EventMessages); - } - else if (item.Published) - { - // unpublish - contentService.Unpublish(item); + return Attempt.Fail("Publish Failed " + publishResult.EventMessages); + } + else if (item.Published) + { + // unpublish + contentService.Unpublish(item); + } } } } // if we get here, save + /* var result = contentService.Save(item); - if (result.Success) - return Attempt.Succeed("Saved"); + if (result.Success) */ + + this.SaveItem(item); + return Attempt.Succeed("Saved"); - return Attempt.Fail("Save Failed " + result.EventMessages); + // return Attempt.Fail("Save Failed " + result.EventMessages); } #endregion @@ -289,7 +296,18 @@ public override void Save(IEnumerable items) => contentService.Save(items); protected override void SaveItem(IContent item) - => contentService.Save(item); + { + try + { + contentService.Save(item); + } + catch (ArgumentNullException ex) + { + // we can get thrown a null argument exception by the notifer, + // which is non critical! but we are ignoring this error. ! <= 8.1.5 + if (!ex.Message.Contains("siteUri")) throw ex; + } + } protected override void DeleteItem(IContent item) => contentService.Delete(item); From 0352af00a645a1a88f95e9250bf67d6df9b44f22 Mon Sep 17 00:00:00 2001 From: Kevin Jump Date: Fri, 27 Sep 2019 16:44:17 +0100 Subject: [PATCH 2/4] Ensure Context so we can publish from outside of a request. --- uSync8.BackOffice/uSync8BackOffice.cs | 2 - uSync8.BackOffice/uSyncBackofficeComponent.cs | 42 +++++----- .../Serializers/ContentSerializer.cs | 83 ++++++++++--------- 3 files changed, 68 insertions(+), 59 deletions(-) diff --git a/uSync8.BackOffice/uSync8BackOffice.cs b/uSync8.BackOffice/uSync8BackOffice.cs index 12728dca..47bc2797 100644 --- a/uSync8.BackOffice/uSync8BackOffice.cs +++ b/uSync8.BackOffice/uSync8BackOffice.cs @@ -9,8 +9,6 @@ namespace uSync8.BackOffice public class uSync8BackOffice { public static bool eventsPaused { get; set; } - - public static bool inStartup { get; set; } } internal class uSync diff --git a/uSync8.BackOffice/uSyncBackofficeComponent.cs b/uSync8.BackOffice/uSyncBackofficeComponent.cs index 2ea236b3..0bff24ef 100644 --- a/uSync8.BackOffice/uSyncBackofficeComponent.cs +++ b/uSync8.BackOffice/uSyncBackofficeComponent.cs @@ -27,12 +27,15 @@ public class uSyncBackofficeComponent : IComponent private readonly uSyncService uSyncService; private readonly IRuntimeState runtimeState; + private readonly IUmbracoContextFactory umbracoContextFactory; + public uSyncBackofficeComponent( SyncHandlerFactory handlerFactory, IProfilingLogger logger, SyncFileService fileService, uSyncService uSyncService, - IRuntimeState runtimeState) + IRuntimeState runtimeState, + IUmbracoContextFactory umbracoContextFactory) { globalSettings = Current.Configs.uSync(); @@ -44,6 +47,8 @@ public uSyncBackofficeComponent( this.syncFileService = fileService; this.uSyncService = uSyncService; + this.umbracoContextFactory = umbracoContextFactory; + } public void Initialize() @@ -86,26 +91,29 @@ private void InitBackOffice() { try { - uSync8BackOffice.inStartup = true; - if (globalSettings.ExportAtStartup || (globalSettings.ExportOnSave && !syncFileService.RootExists(globalSettings.RootFolder))) + using (var reference = umbracoContextFactory.EnsureUmbracoContext()) { - uSyncService.Export(globalSettings.RootFolder, default(SyncHandlerOptions)); - } - if (globalSettings.ImportAtStartup) - { - uSyncService.Import(globalSettings.RootFolder, false, default(SyncHandlerOptions)); - } + if (globalSettings.ExportAtStartup || (globalSettings.ExportOnSave && !syncFileService.RootExists(globalSettings.RootFolder))) + { + uSyncService.Export(globalSettings.RootFolder, default(SyncHandlerOptions)); + } - if (globalSettings.ExportOnSave) - { - var handlers = handlerFactory.GetValidHandlers(new SyncHandlerOptions(handlerFactory.DefaultSet, HandlerActions.Save)); + if (globalSettings.ImportAtStartup) + { + uSyncService.Import(globalSettings.RootFolder, false, default(SyncHandlerOptions)); + } - foreach (var syncHandler in handlers) + if (globalSettings.ExportOnSave) { - logger.Debug($"Starting up Handler {syncHandler.Handler.Name}"); - syncHandler.Handler.Initialize(syncHandler.Settings); + var handlers = handlerFactory.GetValidHandlers(new SyncHandlerOptions(handlerFactory.DefaultSet, HandlerActions.Save)); + + foreach (var syncHandler in handlers) + { + logger.Debug($"Starting up Handler {syncHandler.Handler.Name}"); + syncHandler.Handler.Initialize(syncHandler.Settings); + } } } } @@ -113,10 +121,6 @@ private void InitBackOffice() { logger.Warn($"Error Importing at startup {ex.Message}"); } - finally - { - uSync8BackOffice.inStartup = true; - } } diff --git a/uSync8.ContentEdition/Serializers/ContentSerializer.cs b/uSync8.ContentEdition/Serializers/ContentSerializer.cs index df97f5f3..ced2526d 100644 --- a/uSync8.ContentEdition/Serializers/ContentSerializer.cs +++ b/uSync8.ContentEdition/Serializers/ContentSerializer.cs @@ -196,52 +196,40 @@ protected override void HandleTrashedState(IContent item, bool trashed) protected virtual Attempt DoSaveOrPublish(IContent item, XElement node) { - // at the moment <= 8.1.5 we can't publish during startup. - if (!uSync8BackOffice.inStartup) + var publishedNode = node.Element("Info")?.Element("Published"); + if (publishedNode != null) { - var publishedNode = node.Element("Info")?.Element("Published"); - if (publishedNode != null) + if (publishedNode.HasElements) { - if (publishedNode.HasElements) + // culture based publishing. + var publishedCultures = new List(); + foreach (var culturePublish in publishedNode.Elements("Published")) { - // culture based publishing. - var publishedCultures = new List(); - foreach (var culturePublish in publishedNode.Elements("Published")) - { - var culture = culturePublish.Attribute("Culture").ValueOrDefault(string.Empty); - var status = culturePublish.ValueOrDefault(false); - - if (!string.IsNullOrWhiteSpace(culture) && status) - { - publishedCultures.Add(culture); - } - } + var culture = culturePublish.Attribute("Culture").ValueOrDefault(string.Empty); + var status = culturePublish.ValueOrDefault(false); - if (publishedCultures.Count > 0) + if (!string.IsNullOrWhiteSpace(culture) && status) { - var culturePublishResult = contentService.SaveAndPublish(item, publishedCultures.ToArray()); - if (culturePublishResult.Success) - return Attempt.Succeed($"Published {publishedCultures.Count} Cultures"); - - return Attempt.Fail("Publish Failed " + culturePublishResult.EventMessages); + publishedCultures.Add(culture); } } - else - { - // default publish the lot. - if (publishedNode.Attribute("Default").ValueOrDefault(false)) - { - var publishResult = contentService.SaveAndPublish(item); - if (publishResult.Success) - return Attempt.Succeed("Published"); - return Attempt.Fail("Publish Failed " + publishResult.EventMessages); - } - else if (item.Published) - { - // unpublish - contentService.Unpublish(item); - } + if (publishedCultures.Count > 0) + { + return PublishItem(item, publishedCultures.ToArray()); + } + } + else + { + // default publish the lot. + if (publishedNode.Attribute("Default").ValueOrDefault(false)) + { + return PublishItem(item, null); + } + else if (item.Published) + { + // unpublish + contentService.Unpublish(item); } } } @@ -257,6 +245,25 @@ protected virtual Attempt DoSaveOrPublish(IContent item, XElement node) // return Attempt.Fail("Save Failed " + result.EventMessages); } + private Attempt PublishItem(IContent item, string[] cultures) + { + try + { + var culturePublishResult = contentService.SaveAndPublish(item, cultures); + if (culturePublishResult.Success) + return Attempt.Succeed($"Published {cultures != null: cultures.Count : 'All'} Cultures"); + + return Attempt.Fail("Publish Failed " + culturePublishResult.EventMessages); + } + catch (ArgumentNullException ex) + { + // we can get thrown a null argument exception by the notifer, + // which is non critical! but we are ignoring this error. ! <= 8.1.5 + if (!ex.Message.Contains("siteUri")) throw ex; + return Attempt.Succeed($"Published"); + } + } + #endregion protected override IContent CreateItem(string alias, ITreeEntity parent, string itemType) From 8a7c21f54bed8bcddf5fbf6372b5a209ec5213fc Mon Sep 17 00:00:00 2001 From: Kevin Jump Date: Fri, 27 Sep 2019 16:49:36 +0100 Subject: [PATCH 3/4] Tidy usings / --- uSync8.ContentEdition/Serializers/ContentSerializerBase.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/uSync8.ContentEdition/Serializers/ContentSerializerBase.cs b/uSync8.ContentEdition/Serializers/ContentSerializerBase.cs index e96e8b90..9d4b4d07 100644 --- a/uSync8.ContentEdition/Serializers/ContentSerializerBase.cs +++ b/uSync8.ContentEdition/Serializers/ContentSerializerBase.cs @@ -1,18 +1,16 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Xml.Linq; + using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; using Umbraco.Core.Services; + using uSync8.ContentEdition.Mapping; -using uSync8.Core; using uSync8.Core.Extensions; -using uSync8.Core.Models; using uSync8.Core.Serialization; namespace uSync8.ContentEdition.Serializers From cb4c8d7aaf313fb56639e8f06eee80cd108a8561 Mon Sep 17 00:00:00 2001 From: Kevin Jump Date: Fri, 27 Sep 2019 16:51:31 +0100 Subject: [PATCH 4/4] Tidy ContentSerializer's usings. --- uSync8.ContentEdition/Serializers/ContentSerializer.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/uSync8.ContentEdition/Serializers/ContentSerializer.cs b/uSync8.ContentEdition/Serializers/ContentSerializer.cs index ced2526d..fe0916c9 100644 --- a/uSync8.ContentEdition/Serializers/ContentSerializer.cs +++ b/uSync8.ContentEdition/Serializers/ContentSerializer.cs @@ -1,15 +1,14 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Xml.Linq; + using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; using Umbraco.Core.Services; -using uSync8.BackOffice; + using uSync8.ContentEdition.Mapping; using uSync8.Core; using uSync8.Core.Extensions;