Custom storage provider and profiles example

Version: 10.4

In order to introduce custom Provider and Profiles:

  1. Introduce custom provider. You have to implement the logic how to store data inherited from IStorageProvider.

    RequestResponse
    using Sitecore.XConnect.DataTools.CortexWorkers.DataExport.StorageProviders;
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace CortexWorkers.DataExport.StorageProviders.Examples
    {
        internal class CustomProvider : IStorageProvider
        {
            public CustomProvider(IEnumerable<CustomProfile> profiles)
            {
                Profiles = profiles == null
                    ? new Dictionary<string, CustomProfile>()
                    : profiles.ToDictionary(x => x.ProfileName, x => x);
            }
            public IReadOnlyCollection<string> ProfileNames => Profiles.Keys;
            protected Dictionary<string, CustomProfile> Profiles { get; }
            protected CustomProfile GetProfile(string profileName)
            {
                if (!Profiles.TryGetValue(profileName, out CustomProfile profile))
                {
                    throw new InvalidOperationException();
                }
                return profile;
            }
            public Task UploadAsync(string fileName, string fileContent, string profileName, CancellationToken cancellationToken)
            {
                /*Implement the logic of the custom provider*/
            }
        }
    }
  2. Introduce custom storage Profile(s) that defines a specific set of storage parameters. You must add a ProfileName parameter to identify proper profile.

    RequestResponse
    using System;
    using System.Globalization;
    using Microsoft.Extensions.Configuration;
    
    namespace CortexWorkers.DataExport.StorageProviders.Examples
    {
        internal class CustomProfile
        {
            public CustomProfile(IConfiguration options)
            : this((options ?? throw new ArgumentNullException(nameof(options))).GetValue<string>(nameof(ProfileName)),
            options.GetValue<string>(nameof(Param1)), options.GetValue<string>(nameof(Param2)), options.GetValue<string>(nameof(Param3)))
            {    
            }
            public CustomProfile(string profileName, string param1, string param2, string param3)
            {
                if (string.IsNullOrWhiteSpace(profileName))
                {
                    throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Looks up a localized string similar to The {0} is not valid..", nameof(profileName)));
                }
                if (string.IsNullOrWhiteSpace(param1))
                {
                    throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Looks up a localized string similar to The {0} is not valid..", nameof(param1)));
                }
                if (string.IsNullOrWhiteSpace(param2))
                {
                    throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Looks up a localized string similar to The {0} is not valid..", nameof(param2)));
                }
                if (string.IsNullOrWhiteSpace(param3))
                {
                    throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Looks up a localized string similar to The {0} is not valid..", nameof(param3)));
                }
                ProfileName = profileName;
                Param1 = param1;
                Param2 = param2;
                Param3 = param3;
            }
            public string ProfileName { get; }
            public string Param1 { get; }
            public string Param2 { get; }
            public string Param3 { get; }
        }
    }
  3. Patch the Cortex Processing role and Processing Engine service configuration Sitecore\Processing\Services section with the new custom provider and profiles.

    RequestResponse
    <?xml version="1.0" encoding="utf-8" ?>
    <Settings>
        <Sitecore>
            <Processing>
                <Services>
                    <StorageProviders.CustomProfile>
                        <Type>CortexWorkers.DataExport.StorageProviders.Examples.CustomProfile, CortexWorkers.DataExport.StorageProviders.Examples</Type>
                        <As>CortexWorkers.DataExport.StorageProviders.Examples.CustomProfile, CortexWorkers.DataExport.StorageProviders.Examples</As>
                        <LifeTime>Singleton</LifeTime>
                        <Options>
                            <ProfileName>CustomProfile</ProfileName>
                            <Param1>Value1</Param1>
                            <Param2>Value2</Param2>
                            <Param3>Value3</Param3>
                        </Options>
                    </StorageProviders.CustomProfile>
                    <StorageProviders.CustomProvider>
                        <Type>CortexWorkers.DataExport.StorageProviders.Examples.CustomProvider, CortexWorkers.DataExport.StorageProviders.Examples</Type>
                        <As>Sitecore.XConnect.DataTools.CortexWorkers.DataExport.StorageProviders.IStorageProvider, Sitecore.XConnect.DataTools.CortexWorkers</As>
                        <LifeTime>Singleton</LifeTime>
                    </StorageProviders.CustomProvider>
                </Services>
            </Processing>
        </Sitecore>
    </Settings>
  4. Build your solution. Add the DLL files to the Cortex Processing role and the Processing Engine service.

  5. To apply the changes, restart the Processing Engine service.

Now it is possible to pass CustomProfile to the DataExport Tool and make new custom Provider execute upload.

Do you have some feedback for us?

If you have suggestions for improving this article,