Custom conditions with the Sitecore xConnect purging tool

I wrote previously (https://devsencore.com/2023/08/24/sitecore-xconnect-purging-tool-keeps-xdb-data-in-check/) about using the Sitecore xConnect purge tool to keep xDB instances in check by removing superfluous data. This can optimise performance, costs and improve overall data quality. Out of the box, the purge tool allows maintainers to trim contact or interaction data based on age (Last Modified date), but in some cases finer grained control is needed. Enter, custom purge conditions.

Allowing conditions

Recent versions of Sitecore ship with one contact purge condition available OOTB, the “AnonymousCondition”. This appears to be relatively undocumented, but is used in the example walkthrough on how to create a custom condition. As the name suggests, using this condition will only purge contacts that are not known. Conditions can be specified in a comma separated list when calling purge tasks in the CLI like so:

> dotnet sitecore xconnect purge contacts start --conditions AnonymousCondition --cutoffdays 365
The start command deletes data. Are you sure you want to continue?
        [Y|y] - Yes
        [N|n] - No
y
Approved Task registration.
Registered task id: 554cc0d9-33af-476a-a852-80043d3a3d85
To get the status of the purge task, run the command: sitecore xconnect purge status --pti 554cc0d9-33af-476a-a852-80043d3a3d85
To cancel the purge task, run the command: sitecore xconnect purge cancel --pti 554cc0d9-33af-476a-a852-80043d3a3d85

Conditions will be validated at the time of task registration and need to be explicitly whitelisted (AnonymousCondition is already added for you in the OOTB configs) in the cortex processing role (in an OOTB xp0 implementation, this would be the xconnect service). Failing to add this to configuration will result in the following error from the CLI

> dotnet sitecore xconnect purge contacts start --cds gwdtcondition --cutoffdays 365
The start command deletes data. Are you sure you want to continue?
        [Y|y] - Yes
        [N|n] - No
y
Approved Task registration.
Cannot register delete contacts task. The following conditions are not found: gwdtcondition
An error has occurred, and the task is not registered.

Unfortunately the doco glosses over this part if you’re creating your own condition, but a simple patch (below) can be added to whitelist your conditions in the AllowedContactConditionIds element. (NB: Interaction conditions will need to add to the <AllowedInteractionConditionIds> in the same location. Check App_Data/Config/Sitecore/Processing/sc.XConnect.DataPurge.Validation.xml for reference)

<?xml version="1.0" encoding="utf-8" ?>
<Settings>
	<Sitecore>
		<Processing>
			<Services>
				<DataPurgeTaskOptionsValidatorOptions>
					<Options>
						<AllowedContactConditionIds>
							<Gwdt>GWDTCondition</Gwdt>
						</AllowedContactConditionIds>
					</Options>
				</DataPurgeTaskOptionsValidatorOptions>
			</Services>
		</Processing>
	</Sitecore>
</Settings>

Implementing and registering conditions

The custom condition logic can be implemented by inheriting from Sitecore.XConnect.DataTools.Abstractions.Conditions.IConditon as per the walkthrough documentation and then register it on the Cortex processing worker role. Any logic could be run at this point, but keep performance in mind as large batches may have significant impact on the workers or downstream systems. These processes often need to run at scale with big xdb instances! Out of the box, only very basic info is available in the “Contact” parameter of the IsAccepted method (I assume for performance reasons), as noted in the documentation.

The conditions are limited to filter by contact data and contact identifiers. You cannot create a condition based on the contact facet or interaction data in Sitecore 10.1.

In this example I have added a condition that will accept any contact for purging with an Identifier that was created by xGenerator.

using Sitecore.XConnect;
using Sitecore.XConnect.DataTools.Abstractions.Conditions;
using Microsoft.Extensions.Logging;
using System.Linq;

namespace GWDT.XConnect.Conditions
{
    public class GWDTCondition : ICondition
    {
        private readonly ILogger<GWDTCondition> _logger;

        public GWDTCondition(ILogger<GWDTCondition> logger)
        {
            _logger = logger;
        }

        public bool IsAccepted(Contact contact)
        {
            _logger.LogInformation($"GWDTCondition IsAccepted: {contact.Identifiers.Any(x => x.Source == "xGenerator")}");
           
            //Run your conditional logic
            return contact.Identifiers.Any(x=>x.Source == "xGenerator");
        }

        public string ConditionId { get; } = "GWDTCondition";
    }
}

To register the above condition, patch in the appropriate service declaration on the cortex processing worker:

<?xml version="1.0" encoding="utf-8" ?>
<Settings>
	<Sitecore>
		<Processing>
			<Services>				
				<Condition.GWDTCondition>
					<Type>GWDT.XConnect.Conditions.GWDTCondition, GWDT.XConnect</Type>
					<As>Sitecore.XConnect.DataTools.Abstractions.Conditions.ICondition, Sitecore.XConnect.DataTools.Abstractions</As>
					<LifeTime>Singleton</LifeTime>					       
				</Condition.GWDTCondition>				
			</Services>
		</Processing>
	</Sitecore>
</Settings>

With all configs and code in place, the purge command can now be called with the appropriate condition from the CLI or WebAPI. e.g.

> dotnet sitecore xconnect purge contacts start --conditions gwdtcondition --cutoffdays 365
The start command deletes data. Are you sure you want to continue?
        [Y|y] - Yes
        [N|n] - No
y
Approved Task registration.
Registered task id: 6e626f4e-cb17-43c8-ba94-ebaab86dd2ec
To get the status of the purge task, run the command: sitecore xconnect purge status --pti 6e626f4e-cb17-43c8-ba94-ebaab86dd2ec
To cancel the purge task, run the command: sitecore xconnect purge cancel --pti 6e626f4e-cb17-43c8-ba94-ebaab86dd2ec

While I focussed here on conditions that are run when purging contacts, the process is almost identical for Interaction purge conditions. As always, be careful when purging things! Have appropriate backups and testing regimes in place before executing.

Leave a comment