HCL Commerce Version 9.1.4.0 or later

Extension du service Query

HCL Commerce Version 9.1.4.0 or laterLe service Query génère les expressions de recherche, puis transmet l'expression à Elasticsearch. Vous pouvez personnaliser ce service pour créer vos propres fournisseurs d'expressions, préprocesseurs, postprocesseurss et gestionnaires personnalisés en fonction de vos besoins métier. Il n'y a pas de connectivité JDBC entre le service Query et la base de données Commerce. Cette architecture garantit que l'application peut être sans état et mise à l'échelle indépendamment. Les données métier peuvent toujours être fournies au service Query via l'indexation ou via d'autres microservices.

Before you begin

Veillez à avoir installé et défini le plan de travail Eclipse pour l'utiliser comme votre propre kit d'outils de recherche.

Plusieurs nouvelles classes d'aide ont été ajoutées au fichier query-api.jar. Ces ajouts facilitent l'utilisation des fonctions communes définies dans les classes par défaut et sont répertoriés dans Classes de requête dans le fichier query-api.jar pour plus de commodité.

About this task

Pour personnaliser le service Query :

Procedure

  1. Le query-api.jar est fourni en tant que groupement Git, HCL_Commerce_Search_Bundle_9.1.x.x.zip. Pour obtenir la dernière version de query-api.jar, consultez la liste des derniers packages de téléchargement disponibles pour vous assurer que vous obtenez la version la plus récente.
  2. Ouvrez un navigateur Web et connectez-vous au site HCL Software License & Delivery pour télécharger et extraire la dernière version du groupement HCL Commerce Search afin d'obtenir le fichier HCL_Commerce_Search_Bundle_9.1.x.x.zip.
  3. Créez un projet Gradle. Extrayez la version du fichier query-api-9.1.x.x.jar du groupement de recherche dans un répertoire /lib à la racine du projet, même si le numéro de version est inférieur à votre version actuelle de HCL Commerce Search.
    Note: Si l'API QUERY n'a pas changé, ce fichier n'est pas régénéré. Par conséquent, la dernière version disponible peut être antérieure à votre dernière installation, par exemple, la 9.1.11 lorsque vous êtes sous la 9.1.12. Ceci est normal.
    Créez le répertoire /lib s'il n'existe pas.
  4. Ajoutez les dépendances suivantes au fichier build.gradle :
    implementation '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')
    
    Remplacez 9.1.x.x par la version correcte du fichier JAR téléchargé.
  5. Pour créer les gestionnaires personnalisés :
    1. Utilisez les annotations spring boot suivantes pour la classe de gestionnaire REST :
      @RestController
      @RequestMapping
      
    2. Vous pouvez utiliser l'environnement d'exécution de requête si vous souhaitez utiliser un contrôleur existant ou implémenter un contrôleur personnalisé pour créer un nœud final et extraire des données personnalisées à partir de l'index. Pour une présentation de l'interface de recherche et des descriptions des contrôleurs par défaut, voir HCL Commerce Search Interface.
      1. Appelez la méthode performSearch à partir de SearchServiceFacade fourni dans le cadre de query-api.jar. Consultez par exemple le code suivant.
        package com.samplecompany.search.rest;
        
        import org.springframework.http.ResponseEntity;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RequestParam;
        import org.springframework.web.bind.annotation.RestController;
        
        import com.hcl.commerce.search.expression.SearchCriteria;
        import com.hcl.commerce.search.internal.runtime.SearchServiceFacade;
        
        @RestController
        @RequestMapping("/api/url")
        public class URLResource {
        	
        	@RequestMapping("/id")
        	private ResponseEntity findUrlsByIds(@RequestParam("storeId") Integer iStoreId,
        			@RequestParam("id") String id) throws Exception {
        		
        		ResponseEntity result = null; 
        		SearchCriteria searchCriteria = SearchCriteria.getCriteria();
        		//Set all the necessary control parameters in the searchCriteria. Below is just a sample about how to set parameters.
        		searchCriteria.setControlParameterValue("_wcf.search.profile","Mycompany_customProfile");
        		searchCriteria.setControlParameterValue("_wcf.search.term",id);
        		searchCriteria.setControlParameterValue("_wcf.search.language","-1");
        		result = SearchServiceFacade.getInstance().performSearch(searchCriteria);
        		return result;
        	
        	}
        
        }
        
      2. 2. Si vous n'avez pas besoin de l'architecture d'environnement d'exécution des requêtes et que vous souhaitez interroger directement l'index Elasticsearch, vous pouvez le faire à l'aide des API Java fournies par ElasticSearch. Voir, par exemple, l'exemple de fragment de code suivant.
        package com.samplecompany.search.rest;
        
        import java.util.Arrays;
        import java.util.HashMap;
        import java.util.Map;
        
        import org.springframework.http.HttpStatus;
        import org.springframework.http.MediaType;
        import org.springframework.http.ResponseEntity;
        import org.springframework.web.bind.annotation.PathVariable;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RequestMethod;
        import org.springframework.web.bind.annotation.RestController;
        
        
        import org.apache.http.HttpHost;
        import org.elasticsearch.action.search.SearchRequest;
        import org.elasticsearch.action.search.SearchResponse;
        import org.elasticsearch.client.RequestOptions;
        import org.elasticsearch.client.RestClient;
        import org.elasticsearch.client.RestHighLevelClient;
        import org.elasticsearch.index.query.BoolQueryBuilder;
        import org.elasticsearch.index.query.QueryBuilders;
        import org.elasticsearch.index.query.QueryStringQueryBuilder;
        import org.elasticsearch.search.builder.SearchSourceBuilder;
        
        @RestController
        @RequestMapping("/store/{storeId}/attrview")
        public class AttributeResource {
        	
        	private static final String ES_SCHEME = System.getenv("ELASTICSEARCH_SCHEME");
        	private static final String ES_HOST = System.getenv("ELASTICSEARCH_HOST");
        	private static final String ES_PORT = System.getenv("ELASTICSEARCH_PORT");
        	private static final String ENV_TYPE = System.getenv("ENVTYPE");
        
        	private static final String BY_ATTR_ID = "/{attrId}";
        
        	@RequestMapping(value = BY_ATTR_ID, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
        	public ResponseEntity findAttrById(@PathVariable("storeId") String storeId, @PathVariable("attrId") String attrId) throws Exception {
        
        		ResponseEntity result = null;
        		SearchResponse searchResponse = null;
        		
        		RestHighLevelClient elasticServer = new RestHighLevelClient(RestClient.builder
        				(new HttpHost(ES_HOST, Integer.valueOf(ES_PORT), ES_SCHEME)));
        		
        		String strIndexName = "auth" + "." + storeId + "." + "attribute";
        		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        		
        		BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        		
        		QueryStringQueryBuilder queryStringStore = QueryBuilders.queryStringQuery(attrId.toString());
        		queryStringStore.field("id.attribute");
        		boolQuery.filter(queryStringStore);
        		
        		searchSourceBuilder.query(boolQuery);
        		searchSourceBuilder.fetchSource(false);
        		searchSourceBuilder.storedFields(Arrays.asList("*"));
        		searchSourceBuilder.size(1000);
        		
        		SearchRequest request = new SearchRequest(strIndexName);
        		// Set search source builder in request
        		request.source(searchSourceBuilder);
        		
        		searchResponse = elasticServer.search(request, RequestOptions.DEFAULT);
        		
        		searchResponse.getHits().getAt(0).getId();
        		
        		Map resultMap = new HashMap();
        		
        		resultMap.put("id", searchResponse.getHits().getAt(0).getId());
        		
        		result = new ResponseEntity(resultMap, HttpStatus.OK);
        
        		return result;
        	}
        }
        
    3. Pour l'examen des composants, déclarez votre package de gestionnaire personnalisé com.samplecompany.search.rest par rapport à la clé scan.packages en tant que valeurs séparées par des virgules dans le fichier application.properties situé à l'emplacement suivant : /opt/WebSphere/Liberty/usr/servers/default/apps/search-query.ear/search-query.war/WEB-INF/classes dans le conteneur query-service.
  6. Pour ajouter des fournisseurs d'expressions personnalisés :
    Les fournisseurs d'expressions sont les classes Java qui prennent SearchCriteria comme paramètre. SearchCriteria est un objet Java qui encapsule les attributs de critères envoyés par la vitrine et certains attributs internes requis pour générer SearchSourceBuilder d'Elasticsearch. SearchCriteria est la version Java de l'expression de recherche. Les fournisseurs lisent et traitent les attributs de critères à partir de celui-ci et ajoutent certains attributs internes qui sont ensuite utilisés par les préprocesseurs.
    1. Créez une classe qui étend la classe AbstractSearchExpressionProvider et implémente l'interface SearchExpressionProvider à partir de la dépendance query-API.
      public class SearchByCustomProvider extends AbstractSearchExpressionProvider
      	implements SearchExpressionProvider {
      
      	private static final String CLASSNAME = SearchByCustomProvider.class.getName();
      	private static final Logger LOGGER = LoggerFactory.getLogger(CLASSNAME);
      
      	@Override
      	public void invoke(SearchCriteria searchCriteria) throws Exception {
      		// your logic here
      	}	
      }
      
    2. Déclarez le nom de classe de votre fournisseur personnalisé dans la section du fournisseur du profil ZooKeeper approprié à l'aide du nœud final Search-Profile-Resource de query-service.
  7. Pour ajouter un préprocesseur personnalisé :
    Les préprocesseurs d'expression sont les classes Java qui prennent SearchCriteria et queryRequestObjects comme paramètres. queryRequestObjects est un type d'objet java varargs (Arguments variables) qui contient des profils de recherche et une instance SearchSourceBuilder vide. L'instance SearchSourceBuilder est l'objet binaire natif à utiliser par rapport au moteur de recherche (Elasticsearch). La principale responsabilité du préprocesseur est de préparer l'objet SearchSourceBuilder qui peut être utilisé pour interroger l'index Elasticsearch.
    1. Créez une classe qui étend la classe AbstractSearchQueryPreprocessor et implémente l'interface SearchQueryPreprocessor à partir de la dépendance query-API . Reportez-vous au fragment de code suivant :
      public class SearchCustomQueryPreprocessor extends AbstractSearchQueryPreprocessor 
      	implements SearchQueryPreprocessor {
      
      	private static final String CLASSNAME = SearchCustomQueryPreprocessor.class.getName();
      	private static final Logger LOGGER = LoggerFactory.getLogger(CLASSNAME);
      
      	@Override
      	public void invoke(SearchCriteria searchCriteria, Object... queryRequestObjects) throws Exception {
      		// your logic here
      	}	
      }
      
    2. Déclarez le nom de votre classe de préprocesseur personnalisée dans la section de préprocesseur du profil Zookeeper approprié à l'aide du nœud final Search-Profile-Resource de query-service.
  8. Pour ajouter un postprocesseurs personnalisé :
    Les postprocesseurss d'expression sont les classes Java qui prennent SearchCriteria et queryResponseObjects comme paramètres. queryResponseObjects est un type d'objet java varargs (Arguments variables) qui contient un objet de type de données SearchResponse. SearchResponse est un objet de réponse natif qui représente la réponse de recherche d'Elasticsearch. La responsabilité principale du postprocesseurs est de traiter les résultats renvoyés par Elasticsearch et de les transformer au format requis par la vitrine.
    1. Créez une classe qui étend la classe AbstractSearchQueryPostprocessor et implémente SearchQueryPostprocessor à partir de la dépendance query-API. Reportez-vous au fragment de code suivant :
      public class SearchCustomQueryPostprocessor extends AbstractSearchQueryPostprocessor 
      implements SearchQueryPostprocessor {
      
      	private static final String CLASSNAME = SearchCustomQueryPostprocessor.class.getName();
      	private static final Logger LOGGER = LoggerFactory.getLogger(CLASSNAME);
      
      	@Override
      	public void invoke(SearchCriteria searchCriteria, Object... queryResponseObjects) throws Exception {
      		// your logic here
      	}	
      }
      
      
    2. Déclarez le nom de votre classe de postprocesseurs personnalisée dans la section postprocesseurs du profil Zookeeper approprié à l'aide du point d'extrémité Search-Profile-Resource de query-service.
  9. Créez le projet à la racine du projet à l'aide de la commande gradlew build. Les fichiers JAR créés se trouvent dans le répertoire /build/libs, sous la racine du projet. Copiez les nouveaux fichiers JAR dans le répertoire d'extension désigné (/opt/WebSphere/Liberty/usr/servers/default/apps/search-query.ear/search-query.war/WEB-INF/lib) sur votre machine hôte. Ce répertoire est monté en tant que volume sur votre conteneur Docker de service Query.
    Note:
    • Reportez-vous à la commande suivante comme exemple permettant de fournir l'extension jar en tant que montage de volume sur le conteneur Docker du service de requête :
      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
    • Bien que l'étape susmentionnée suggère d'utiliser des montages externes pour stocker vos personnalisations, il s'agit uniquement d'une procédure recommandée dans une environnement de développement agile où des modifications fréquentes du code sont apportées et sont testées de nombreuses fois. Toutefois, lorsqu'il arrive dans des environnements de déploiement plus élevés tels que l'assurance qualité et les environnements de production, il est recommandé d'avoir ces personnalisations intégrées dans l'image de l'application par le biais d'un pipeline CI/CD par souci de cohérence et de facilité de déploiement.
  10. Redémarrez le conteneur query-service pour que le changement soit appliqué.