Showing posts with label configuration. Show all posts
Showing posts with label configuration. Show all posts

Wednesday, 1 March 2023

When Disabling xDB Isn't Enough

If you read the documentation on using CMS-only mode to run Sitecore without xDB you'd be forgiven for thinking that a config patch such as this is the simple end of the story:

<configuration>
    <sitecore>
        <settings>
            <setting name="Xdb.Enabled" value="false" />
            <setting name="Xdb.Tracking.Enabled" value="false" />
        </settings>
    </sitecore>
</configuration>

Unfortunately as someone on Slack recently discovered, this doesn't help if you're trying to run Sitecore (XP container images, but in CMS-only mode without the xConnect instances) in containers. 

The issue is fairly obvious when you notice CM is not starting and take a look at an example of the logs

920 08:52:34 ERROR Health check Sitecore.XConnect.Client.WebApi.CollectionWebApiClient completed after 0.0038ms with status Unhealthy and 'Error during CollectionWebApiClient initialization: An error occurred while sending the request.'

1920 08:52:35 ERROR Health check Sitecore.XConnect.Client.WebApi.ConfigurationWebApiClient completed after 0.0054ms with status Unhealthy and 'Error during ConfigurationWebApiClient initialization: An error occurred while sending the request.'

1920 08:52:36 ERROR Health check Sitecore.XConnect.Client.WebApi.SearchWebApiClient completed after 0.0068ms with status Unhealthy and 'Error during SearchWebApiClient initialization: An error occurred while sending the request.'

Yes, there are in fact health checks on CM and CD which check the status of xConnect, and completely ignore the config settings I mentioned above.

Not to worry, there are a couple of options at this point:

  1. Use a config patch to remove the health checks (the easier option)
  2. Update and override the health checks so that they respect the Xdb.Enabled setting

Config patch

Here's an easy patch you can apply which should remove these from your Sitecore configuration and complete the disabling of xDB:

Updating the code

The "proper" way, I feel, would be to update the code to respect the Xdb.Enabled setting. This is what the setting is indicating, and what the documentation explains that it is for.

To take XConnectCollectionHealthCheckServicesConfigurator as an example:

public class XConnectCollectionHealthCheckServicesConfigurator : Sitecore.XConnect.Client.Configuration.HealthCheckServicesConfigurators.XConnectCollectionHealthCheckServicesConfigurator
{
  protected override IHealthCheck CreateCommonWebApiHealthCheck(IServiceProvider provider)
  {
    if (Sitecore.Configuration.Settings.GetBoolSetting("Xdb.Enabled", true))
      return base.CreateCommonWebApiHealthCheck(provider);
    else
      return new SuccessHealthCheck();
  }
}

public class SuccessHealthCheck : IHealthCheck
{
  public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
  {
    return Task.FromResult(HealthCheckResult.Healthy());
  }
}

We add our settings check, and - because there does not seem to be any easy out-of-the-box way to return a successful health check - we also need to create a class for that. Repeat for all 3 health checks, and you're good to go.

Enjoy running your Sitecore topology nice and lean!

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>