Could you please advise us on how to trigger singleIndexRequest from the pricing microservice? We want to generate this event whenever the price data for a particular product is updated.
For example, we have a product with sku = ‘product’, and we created a new contributor for indexing that adds price data information to the product document. So, whenever we update the price data for price target = ‘product’, we want to trigger an event for product indexing to ensure that the document is updated with the new price data.
Thanks for submitting this question! There are several customizations needed to get this working as desired. The first step is creating the message from PricingServices, and the second step is adding new components to IndexerServices in order to use SKUs instead of product context id for determining what products to reindex.
There are some existing examples out of the box that will help you create your own custom message. SingleIndexRequestMessageBuilder is in the Data Tracking common library, so the PricingServices microservices has access to it. Look at AbstractAncillaryProductSingleIndexRequestMessageBuilder from and its implementations like JpaProductTagSingleIndexRequestMessageBuilderin CatalogServices microservices for an example. Once you have your own instance of this message builder in your PricingServices package and it is registered as a Spring bean, it should get automatically hooked up to the messaging pipeline.
Pricing Service doesn’t have access to the product context IDs which is how single index events for products are typically built. The SingleIndexEvent contains a generic “payload” based on the Identifiable interface that can be implemented with various properties.
An example of this is the AncillaryProductSingleIndexRequestPayload.java which passes only the productContextId for various ancillary entity updates in Catalog. For pricing, you could create a new AncillaryProductPricingSingleIndexRequestPayload which passes the SKU as the ID via message to the IndexerService.
You would then need to add a few components on the IndexerServices side of things for that to be processed correctly.
In Indexer, for the typical ancillary product index events, there’s a handler called AncillaryProductSingleIndexRequestHandler.java, which would typically look up products via DefaultCatalogService based on the payload of context IDs passed and send those to be indexed. Since the events coming from Pricing would contain a SKU instead of a product ID, there’s some additional hydration that needs to occur first in order to get the product IDs.
- You would create a new
AncillaryProductPricingSingleIndexRequestHandler that accepts the pricing entity type & new payload of SKUs.
- Then you could call the
DefaultCatalogService.java to read the batch of product IDs via the method readBatchOfProductIds(String startId, int batchSize, @Nullable Map<String, Object> additionalProperties), and passing the SKUs into additionalProperties.
- Then you could extend
DefaultCatalogService#buildBatchProductIdsFilters to build RSQL filters based on those SKUs.
AncillaryProductPricingSingleIndexRequestHandler could then pass the fetched product IDs to readBatchOfProducts(List<String> ids) to fetch the products to index and, on return, call the reindexDelegationService#reindex(List<Product> products) to index those products.
That’s a high level outline of what we think you would need to get this working. Hope this helps!