HCL Commerce Version 9.1.4.0 or later

Ampliación del servicio de consulta

HCL Commerce Version 9.1.4.0 or laterEl servicio de consulta crea las expresiones de búsqueda y, a continuación, entrega la expresión a Elasticsearch. Puede personalizar este servicio para crear sus propios proveedores de expresiones, preprocesadores, posprocesadores y controladores personalizados según sus requisitos comerciales. No hay conectividad JDBC desde el servicio de consultas a la base de datos de Commerce. Esta arquitectura asegura que la aplicación pueda ser carecer de estado y escalarse de forma independiente. Los datos comerciales aún se pueden proporcionar al servicio de consultas mediante la indexación o mediante otros microservicios.

Before you begin

Asegúrese de haber instalado y configurado el entorno de trabajo de Eclipse para utilizarlo como su propio kit de herramientas de búsqueda.

Se han añadido varias clases ayudantes nuevas al archivo query-api.jar. Estas adiciones facilitan el uso de funciones comunes definidas en las clases predeterminadas y se listan en Clases de consulta en el archivo query-api.jar para su comodidad.

About this task

Para personalizar el servicio de consulta:

Procedure

  1. El query-api.jar se entrega como un paquete Git, HCL_Commerce_Search_Bundle_9.1.x.x.zip. Para obtener la última versión de query-api.jar, revise la lista de los últimos paquetes de descarga disponibles para asegurarse de que obtiene la versión más actualizada.
  2. Abra un navegador web e inicie sesión en el sitio de HCL Software License & Delivery para descargar y extraer la versión más reciente del paquete de HCL Commerce Search para obtener HCL_Commerce_Search_Bundle_9.1.x.x.zip.
  3. Crea run nuevo proyecto de Gradle. Extraiga la versión del archivo query-api-9.1.x.x.jar desde Búsqueda de paquetes compuestos en un directorio /lib en la raíz del proyecto, incluso si el número de la versión es inferior a la versión actual, HCL Commerce Search.
    Note: Si la API de QUERY no ha cambiado, este archivo no se volverá a compilar, por lo que la última versión disponible puede ser anterior a la última instalada, por ejemplo, 9.1.11 cuando usted tiene 9.1.12. Esto es normal.
    Cree el directorio /lib si aún no existe.
  4. Añada las dependencias siguientes al archivo 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')
    
    Sustituya la 9.1.x.x por la versión correcta del archivo jar descargado.
  5. Para crear los manejadores personalizados:
    1. Utilice las anotaciones spring boot siguientes para la clase de manejador rest:
      @RestController
      @RequestMapping
      
    2. Puede utilizar el entorno de ejecución de consulta si desea utilizar un controlados existente o implementar un controlador personalizado para crear un nuevo endpoint y recuperar datos personalizados del índice. Para obtener una visión general de la interfaz de búsqueda y de las descripciones de los controladores predeterminados, consulte HCL Commerce Search Interfaz.
      1. Llame al método performSearch desde SearchServiceFacade proporcionado como parte de query-api.jar. Para obtener un ejemplo, consulte el código siguiente.
        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 no necesita la arquitectura de tiempo de ejecución de consulta y desea consultar directamente el índice de elasticsearch, puede hacerlo utilizando las API java proporcionadas por ElasticSearch. Por ejemplo, consulte el siguiente fragmento de código de ejemplo:
        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. Para el escaneo de componentes, declare su paquete de controlador personalizado com.samplecompany.search.rest contra la clave scan.packages como valores separados por comas en application.properties que se encuentra en: /opt/WebSphere/Liberty/usr/servers/default/apps/search-query.ear/search-query.war/WEB-INF/classes dentro del contenedor query-service.
  6. Para agregar proveedores de expresiones personalizados:
    Los proveedores de expresiones son las clases java que toman SearchCriteria como parámetro. SearchCriteria es un objeto Java que encapsula los atributos de criterio enviados por el escaparate y algunos atributos internos necesarios para generar SearchSourceBuilder de Elasticsearch. SearchCriteria es la versión Java de la expresión de búsqueda. Los proveedores leen y procesan los atributos de los criterios y agregan ciertos atributos internos que los preprocesadores utilizan en mayor medida.
    1. Cree una nueva clase que amplíe la clase AbstractSearchExpressionProvider e implemente la interfaz SearchExpressionProvider desde la dependencia de la API de consulta.
      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. Declare el nombre de clase de su proveedor personalizado en la sección de proveedor del perfil de zookeeper relevante utilizando el punto final de Search-Profile-Resource del servicio de consulta.
  7. Para añadir un preprocesador personalizado:
    Los preprocesadores de expresiones son las clases de Java que toman SearchCriteria y queryRequestObjects como parámetros. queryRequestObjects es un tipo de objeto java varargs (argumentos variables) que contiene perfiles de búsqueda y una instancia de SearchSourceBuilder vacía. La instancia de SearchSourceBuilder es el objeto binario nativo que se utilizará en el motor de búsqueda (Elasticsearch). La principal responsabilidad del preprocesador es preparar el objeto SearchSourceBuilder que se puede utilizar para consultar el índice Elasticsearch.
    1. Cree una nueva clase que amplíe la clase AbstractSearchQueryPreprocessor e implemente la interfaz SearchQueryPreprocessor desde la dependencia de la API de consulta. Revise el fragmento de código siguiente:
      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. Declare el nombre de su clase de preprocesador personalizado en la sección de preprocesador del perfil de zookeeper relevante utilizando el punto final de búsqueda-perfil-recurso del servicio de consulta.
  8. Para añadir un postprocesador personalizado:
    Los postprocesadores de expresión son las clases de java que toman SearchCriteria y queryResponseObjects como parámetros. queryResponseObjects es un tipo de objeto java varargs (argumentos variables) que contiene un objeto de tipo de datos SearchResponse. SearchResponse es un objeto de respuesta nativo que representa la respuesta de búsqueda de Elasticsearch. La principal responsabilidad del postprocesador es procesar los resultados devueltos de Elasticsearch y transformarlos al formato que el escaparate necesita.
    1. Cree una nueva clase que amplíe la clase AbstractSearchQueryPostprocessor e implemente la dependencia SearchQueryPostprocessor de la API de consulta. Revise el fragmento de código siguiente:
      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. Declare el nombre de su clase de posprocesador personalizada en la sección de posprocesador del perfil de zookeeper relevante utilizando el punto final de Search-Profile-Resource del servicio de consulta.
  9. Cree el proyecto en la raíz del proyecto, utilizando el comando gradlew build. Los jars construidos se encuentran en el directorio /build/libs, bajo la raíz del proyecto. Copie los nuevos archivos jar en el directorio de extensión designado (/opt/WebSphere/Liberty/usr/servers/default/apps/search-query.ear/search-query.war/WEB-INF/lib) en su máquina anfitriona. Este directorio se monta como un volumen en su contenedor Docker del servicio Query.
    Note:
    • Consulte el siguiente comando como referencia para proporcionar la extensión jar como un montaje de volumen en el contenedor de Docker de servicio de consulta:
      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
    • Aunque el paso antes mencionado sugiere el uso de montajes externos para almacenar sus personalizaciones, esta es solo una configuración recomendada en un entorno de desarrollo ágil donde se realizan cambios de código frecuentes y se vuelven a probar una y otra vez. Pero cuando se llega a entornos de implementación superiores, como QA y entornos de producción, se recomienda tener estas personalizaciones integradas en la imagen de la aplicación a través de una canalización de CI/CD para lograr coherencia y facilidad de implementación.
  10. Reinicie el contenedor del servicio de consultas para que los cambios surtan efecto.