I'm building a Sitecore Commerce 9 plugin that connects to a Message Queue and performs SellableItems updates based on the message.
I created a method to update the SellableItem and I tested it using a new CommerceCommand called from Postman - it works fine. The problem is that when I call same method from queue Message Handler, the context seems to be different then when called from Command, and the IFindEntityPipeline can't find same Category to assign the SellableItem to.
Here is my code:
Starting the Message Queue client:
public void ConfigureServices(IServiceCollection services)
{
var assembly = Assembly.GetExecutingAssembly();
services.RegisterAllPipelineBlocks(assembly);
services.Sitecore().Pipelines(config =>
config.ConfigurePipeline<IStartEnvironmentPipeline>(configure => {
configure.Add<StartQueueReceiverBlock>();
})
);
services.RegisterAllCommands(assembly);
services.AddSingleton<IReceiveClient, ReceiveClient>();
}
The pipeline block:
public class StartQueueReceiverBlock : PipelineBlock<CommerceEnvironment,CommerceEnvironment, CommercePipelineExecutionContext>
{
private readonly IReceiveClient _client;
public StartQueueReceiverBlock(IReceiveClient client)
{
_client = client;
}
public override Task<CommerceEnvironment> Run(CommerceEnvironment arg, CommercePipelineExecutionContext context)
{
return Task.Run<CommerceEnvironment>(() =>
{
if(arg.Name == "HabitatAuthoring")
_client.Receive(context.CommerceContext);
return arg;
}
);
}
}
The queue message handler calls my SellableItemUpsertPipeline:
private async Task ProcessMessagesAsync(Message message, CancellationToken token)
{
await _sellableItemUpsertPipeline.Run(new SellableItemUpsertArgument(message), _context.GetPipelineContextOptions()); //_context passed from StartQueueReceiverBlock
await queueClient.CompleteAsync(message.SystemProperties.LockToken);
}
Here is the troublesome part:
public class SellableItemUpsertBlock : PipelineBlock<SellableItemUpsertArgument, SellableItem, CommercePipelineExecutionContext>
{
private readonly IFindEntityPipeline _findEntityPipeline;
public SellableItemUpsertBlock(IFindEntityPipeline findEntityPipeline)
{
this._findEntityPipeline = findEntityPipeline;
}
public override async Task<SellableItem> Run(SellableItemUpsertArgument arg, CommercePipelineExecutionContext context)
{
//If finds Category when called from Postman, but returns null when triggered by queue message
var entity = await _findEntityPipeline.Run(new FindEntityArgument(typeof(Category), "Entity-Category-Habitat_Master-FeaturedProducts"), context);
return new SellableItem();
}
How to retrieve same entity when triggering the pipeline from queue Message Handler?