Friday, March 9, 2018

Sitecore Experience Commerce - Creating a minion

Minions in Sitecore Experience Commerce can be thought of as a scheduled task. Many of the example minions that come with the Habitat commerce solution will access and watch a list of data from commerce. For example the ReleasedOrdersMinion watches the ReleasedOrders list. Other more general minions may not watch a list at all, such as the NodeHeartBeatMinion for example.

In my implementation I needed a process which would run in the background to watch an external system for product changes and then import them into Sitecore Experience Commerce. I decided to create a minion for this task (as it needed to run on a schedule and I wanted to have commerce context). This minion would not be watching a list, as one was not relevant to this case.

The full source code for the Sitecore Experience Commerce minion is available on GitHub. Also included in this example is a block and pipeline example.
The key part of this project is the minion defintion itself, this is what is configured in the minions environment and what is run on the schedule:
namespace Plugin.MyProject.Import
{
    public class ImportMinion : Minion
    {
        protected IImportMinionMinionPipeline MinionPipeline { get; set; }

        public override void Initialize(IServiceProvider serviceProvider, ILogger logger, MinionPolicy policy, CommerceEnvironment environment, CommerceContext globalContext)
        {
            base.Initialize(serviceProvider, logger, policy, environment, globalContext);
            MinionPipeline = serviceProvider.GetService<IImportMinionMinionPipeline>();
        }

        public override async Task<MinionRunResultsModel> Run()
        {
            this.Logger.LogInformation("ImportMinion running");

            var commerceContext = new CommerceContext(this.Logger, this.MinionContext.TelemetryClient, null);
            commerceContext.Environment = this.Environment;

            CommercePipelineExecutionContextOptions executionContextOptions = new CommercePipelineExecutionContextOptions(commerceContext, null, null, null, null, null);

            MinionRunResultsModel res = await this.MinionPipeline.Run(new MinionRunResultsModel(), executionContextOptions);

            return new MinionRunResultsModel();
        }
    }
}
To actually get this minion to run it needs to be added to the environment definition for your minions environment. In the Sitecore.Commerce.Engine project is the JSON file PlugIn.Habitat.CommerceMinions-1.0.0.json which is the definition for the habitat minions environment. This is the active environment on the commerce minions web site (one of 4 in IIS installed as part of commerce).

Inside this file, you can see some example minions have been added:

Sitecore Experience Commerce Minions environment definition

Here we can inject in the definition of our custom minion:
{
    "$type": "Sitecore.Commerce.Core.MinionPolicy, Sitecore.Commerce.Core",
    "WakeupInterval": "00:05:00",
    "ListToWatch": "",
    "FullyQualifiedName": "Plugin.MyProject.Import.ImportMinion, Plugin.MyProject.Import",
    "ItemsPerBatch": 10,
    "SleepBetweenBatches": 500
}
Notice that there is no ListToWatch and that the minion is set to run every 5 minutes. The type of Sitecore.Commerce.Core.MinionPolicy is important as this is what defines this as a minion definition and ensures that it will be started during environment initialization.

Now you simply deploy the Sitecore.Commerce.Engine project to your commerce minions IIS website (ensuring that the correct EnvironmentName is set the the config.json file. If you check the logs for that IIS website, it should show the minion running every 5 minutes:
7 11:33:02 INFO ImportMinion running
If all else fails, try a Bootstrap Sitecore Commerce call in Postman as this tends to fix most commerce errors.

No comments:

Post a Comment