Friday, 29 January 2016

Sitecore Azure module - separating config

Those of you who have used the Sitecore Azure module will know that the final deployed package does not contain your .config / patch files in the same way as you have in your solution.  The module uses the fully-built Sitecore config tree, does a bunch of config transforms (I won't go into the details in this post, it uses files in a separate Azure folder and the fields in your Azure module content) and then splits this fully-built config into separate custom .config files based on their node name under <sitecore></sitecore>.

This split happens in the Sitecore.Azure.Pipelines.CreateAzurePackage.Azure.SaveConfigFiles pipeline, and based on your configuration you then end up with the following config files in your Include directory:

  • commands.config

  • mediaLibrary.config

  • icons.config

  • portraits.config

  • languageDefinitions.config

  • xamlsharp.config

  • fieldTypes.config

  • events.config

  • processors.config

  • analyticsExcludeRobots.config

  • settings.config

  • pipelines.config

  • contentSearch.config

  • scheduling.config

  • ui.confi

  • databases.config

  • search.config


So, what if we want to split another config section out into its own file? Say, the <sites></sites> section?  Having a look at the decompiled pipeline, we can simply create our pipeline to extend it (making sure to move our config section before the rest).  You could just as easily put a new pipeline before this one, but I wanted to reuse the 'move' method in the original code. Unfortunately the Sitecore devs did not make this method protected, so we have to duplicate the code or use reflection :(
using System.IO;
using System.Xml.Linq;
using Sitecore.Azure.Pipelines.BasePipeline;
using Sitecore.Azure.Pipelines.CreateAzurePackage;
using Sitecore.Diagnostics;
using Sitecore.IO;
using Extensions = System.Xml.XPath.Extensions;

public class SaveConfigFiles : Sitecore.Azure.Pipelines.CreateAzurePackage.Azure.SaveConfigFiles
{
protected override void Action(RolePipelineArgsBase arguments)
{
CreateAzureDeploymentPipelineArgs args = arguments as CreateAzureDeploymentPipelineArgs;
Assert.IsNotNull(args, "args");
DirectoryInfo sourceIncludeDir = args.SourceIncludeDir;
sourceIncludeDir.Create();
this.MoveSectionToIncludeFile("sites", sourceIncludeDir, args);
base.Action(arguments);
}

private void MoveSectionToIncludeFile(string nodename, DirectoryInfo includeDir, CreateAzureDeploymentPipelineArgs args)
{
Assert.ArgumentNotNull(nodename, "nodename");
Assert.ArgumentNotNull(includeDir, "includeDir");
Assert.ArgumentNotNull(args, "args");
XDocument xdocument = XDocument.Parse("<configuration xmlns:patch=\"http://www.sitecore.net/xmlconfig/\"><sitecore></sitecore></configuration>");
XElement xelement = Extensions.XPathSelectElement(args.WebConfig, "./configuration/sitecore/" + nodename);
if (xelement == null)
{
return;
}
xelement.Remove();
Extensions.XPathSelectElement(xdocument, "./configuration/sitecore").Add(xelement);
xdocument.Save(FileUtil.MakePath(includeDir.FullName, nodename + ".config", '\\'));
}
}
}

And replace the pipeline with ours
App_Config\Include\zCustom\CustomAzure.config
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<processors>
<CreateAzurePackage>
<processor patch:instead="processor[@type='Sitecore.Azure.Pipelines.CreateAzurePackage.Azure.SaveConfigFiles, Sitecore.Azure']"
type="Custom.SaveConfigFiles, Custom" />
</CreateAzurePackage>
</processors>
</sitecore>
</configuration>

No comments:

Post a Comment