Extending the Query Service
The Query service builds the search expressions and then hands the expression to Elasticsearch. You can customize this service to create your own expression providers, pre-processors, post-processors, and custom handlers as per your business requirements. There is no JDBC connectivity from the Query service to the Commerce database. This architecture ensures that the application can be stateless and scaled independently. Business data can still be provided to the Query service either by indexing or through other micro-services.
Before you begin
Several new helper classes have been added to the query-api.jar file. These additions make it easier for you to use common functions defined in the default classes, and are listed in Query classes in the query-api.jar file for your convenience.
About this task
Procedure
- The query-api.jar is delivered as a Git bundle, HCL_Commerce_Search_Bundle_9.1.x.x.zip. To get the latest version of the query-api.jar, review the list of the latest available download packages to ensure that you are obtaining the most up-to-date version.
- Open a web browser and log in to the HCL Software License & Delivery site to download and extract the latest version of the HCL Commerce Search bundle to obtain the HCL_Commerce_Search_Bundle_9.1.x.x.zip.
-
Create a new Gradle project. Extract the version of the file
query-api-9.1.x.x.jar from the Search bundle into a
/lib directory at the root of the project, even if the
version number is lower than your current HCL Commerce Search version.
Note: If the QUERY API has not changed, this file is not rebuilt, so the latest available version may be prior to your latest install, eg., 9.1.11 when you are on 9.1.12. This is normal.Create the /lib directory if it does not already exist.
-
Add the following dependencies to the build.gradle file:
Replaceimplementation 'org.elasticsearch:elasticsearch:7.9.3' implementation 'org.springframework.boot:spring-boot-starter-web:2.2.4.RELEASE' implementation 'org.springframework:spring-web:5.2.5.RELEASE' implementation 'org.springframework.boot:spring-boot-starter-validation:2.2.5.RELEASE' implementation 'org.elasticsearch.client:elasticsearch-rest-high-level-client:7.12.0' implementation 'org.elasticsearch:elasticsearch:7.12.0' implementation ('org.elasticsearch.client:elasticsearch-rest-client:7.12.0') { exclude module: 'snakeyaml:1.23' } implementation files('lib/query-api-9.1.x.x.jar')
9.1.x.x
with the correct version of the downloaded jar file. -
To create the custom handlers:
-
To add custom expression providers:
Expression Providers are the java classes that take SearchCriteria as a parameter. SearchCriteria is a java object which encapsulates the criteria attributes sent by the storefront, and some internal attributes required for generating Elasticsearch’s
SearchSourceBuilder
. SearchCriteria is the Java version of the search expression. Providers read and process the criteria attributes from it and add certain internal attributes which are further utilized by pre-processors. -
To add a custom pre-processor:
Expression pre-processors are the java classes that take SearchCriteria and queryRequestObjects as parameters.
queryRequestObjects
is a java varargs (Variable Arguments) object type which contains Search Profiles and an emptySearchSourceBuilder
instance. TheSearchSourceBuilder
instance is the native binary object to be used against the Search Engine (Elasticsearch). The pre-processor’s main responsibility is to prepare theSearchSourceBuilder
object that can be used to query the Elasticsearch index. -
To add a custom post-processor:
Expression post-processors are the java classes that take SearchCriteria and queryResponseObjects as parameters.
queryResponseObjects
is a java varargs (Variable Arguments) object type which contains an object of datatypeSearchResponse
.SearchResponse
is a native response object which represents the search response from Elasticsearch. The post-processor’s main responsibility is to process the results returned from Elasticsearch and transform them into the format required by the storefront. -
Build the project at the root of the project, using the gradlew
build command. The built jars can be found in the
/build/libs directory, under the root of the project.
Copy the new jar files to the designated extension directory
(/opt/WebSphere/Liberty/usr/servers/default/apps/search-query.ear/search-query.war/WEB-INF/lib)
in your host machine. This directory is mounted as a volume on your
query-service docker container.
Note:
- Refer to the following command as an example to provide the
extension jar as a volume mount to the query-service docker
container:
docker run -it -p 3737:3737 --name query-service -v /home/qsuser/ext/extension.jar:/opt/WebSphere/Liberty/usr/servers/default/apps/search-query.ear/search-query.war/WEB-INF/lib/extension.jar
- Although the aforementioned step suggests using external mounts for storing your customizations, this is only a recommended set up in an agile development environment where frequent code changes are made and being retested over and over again. But when it gets to higher deployment environments such as QA, and Production environments, it is recommended to have these customization built into the application image through a CI/CD pipeline for consistency and ease of deployment.
- Refer to the following command as an example to provide the
extension jar as a volume mount to the query-service docker
container:
- Restart the query-service container for the changes to take effect.