REST Service Integration

In case you are unable to use the Java library directly (most likely due to your system not running on the JVM), you can use the REST-service wrapper for smartQuery. It’s delivered as a docker image and must run in your environment.

Requirements

Start the service

The service is provided as a docker image on docker hub with the name commerceexperts/smartquery-service:2.3.1

The container must be initiated with your API key set to the environment variable SH_API_KEY (for legacy support SQ_API_KEY is also accepted). The container exposes port 8081 which can be mapped to any port. Please consider, that the docker container needs access to the remote URLs mentioned above in the Requirements section.

# use the API key we provide
docker run -d --name=smartquery-service -e SH_API_KEY=<YourS3cr3tAPIkey> -P commerceexperts/smartquery-service:2.3.1

Using the service

The service offers two endpoints to get a query mapping:

Service Endpoint V1

URL Scheme:

http://<host>:<port>/smartquery/v1/<tenant-name>/<tenant-channel>?userQuery=<user-query>

Parameters:
  • tenant-name (path): the first part of the tenant provided by searchHub

  • tenant-channel (path): the second part of the tenant provided by searchHub

  • userQuery (query): the text the user entered in the search box

  • sessionId (query): optional parameter that MUST contain the value of the SearchCollectorSession (see details below)

Example:
curl localhost:10240/smartquery/v1/test/working?userQuery=bierzellt -o -
# returns 'bierzelt' on success
# returns 'bierzellt' if no mapping was found or no data is available

The response is a simple string which is either the mapped query, or in the event no mapping is found, the original user query. Redirects are not supported for this endpoint and won’t be returned, even if available.

Keep in mind, smartQuery starts fetching mapping data, after the initial request for a specific tenant is received. As a result, for the first ~5 seconds all mappings will return the input query, due to mapping data having not yet been fetched. You should begin receiving mapped queries within a few seconds - provided data is available.

Alternatively, it’s possible to remove the aforementioned startup latency by specifying the desired tenants by invoking the preloadTenants parameter outlined below. This variation will make the service available as soon as the mappings have been loaded.

Integration with sessionID

If the search collector is integrated into your system’s frontend, it’s advisable to pass the corresponding sessionId to smartQuery. This sessionId helps ensure that search traffic for queries under testing is evenly distributed across both versions. Without the sessionId, the reliability and accuracy of these tests is significantly reduced.

For implementation, the value of the SearchCollectorSession cookie MUST be used and passed with the ‘sessionId’ parameter. Using a different value may result in unexpected behavior. If the SearchCollectorSession cookie is missing or not available for a request, the ‘sessionId’ parameter should not be set.

More information about this extended integration in the best practices section.

Configuration

Update Rate

Sets the rate (in seconds) at which the update should run. The value must be between 5 and 3600. This can be set as part of the JAVA_OPTS environment variable:

JAVA_OPTS="-Dsmartquery.updateRateInSeconds=60"

Preload Tenants

Specify tenants that should be loaded immediately following initialization. Can be set either as a comma-separated list, via the environment variable:

SH_INIT_TENANTS="example.num1,example.num2"

(for legacy support SQ_INIT_TENANTS is also accepted) or as part of the JAVA_OPTS environment variable with one parameter per tenant:

JAVA_OPTS="-Dsmartquery.preloadTenants[0]=example.num1 -Dsmartquery.preloadTenants[1]=example.num2"

Basic Authentication

In case you want to enable basic authentication, add the following properties to the JAVA_OPTS environment variable.

JAVA_OPTS="-Dserver.auth.enabled=true -Dspring.security.user.password=<desired-password>"

The user that is linked to that password is user. To use a different username, add the property -Dspring.security.user.name=<your-username> to JAVA_OPTS.

If server authentication is enabled but the password property is omitted, a random password will be generated and printed to the logs / standard out.

Note

Due to an update of Spring Boot to Version 2 with smartquery 1.2.10, the security properties changed. For smartquery service version <= 1.2.9 the properties are without the ‘spring.’:

JAVA_OPTS=”-Dserver.auth.enabled=true -Dsecurity.user.password=<desired-password> -Dsecurity.user.name=<your-username>”

Port and other

Since the service is built with Spring Boot 2, please have a look at the according Spring Boot 2 web server configuration.

For a quick reference here are a few options that might be interesting for your operational goal:

  • Use server.port=8080 to change to desired web application port (defaults to 8081)

  • Use management.server.port=8081 to change to another port than the main port which is default.

  • Use server.compression.enabled=false to disable compression, which is enabled by default.

Internally the Jetty Server is used, so to enable access logging for example, use the according jetty properties:

  • server.jetty.accesslog.enabled=true (Without a specified file, these logs are routed to System.Err)

  • server.jetty.accesslog.filename=/var/log/jetty-access.log (Make sure to get those files out of the running container to avoid disk pressure problems)

Set all those properties via the JAVA_OPTS environment variable prefixed with -D.

Monitoring

A health status can be retrieved at the endpoint /health.

Application metrics are exposed at the management port in the prometheus format through the /prometheus endpoint of the service. In addition to the metrics described in the monitoring section of the direct integration docs, this endpoint also exposes several HTTP and Java metrics.

Due to backwards compatibility these endpoints are exposed at the same port as the service itself. It is recommended to change this with the startup property JAVA_OPTS=”-Dmanagement.server.port=8082 setting it to your desired port.

To disable this endpoint completely use the startup property JAVA_OPTS=”-Dmanagement.endpoint.prometheus.enable=false”

For more options see the Spring Boot 2 Monitoring Reference.

Troubleshooting

  • The container won’t start, if you forget to specify the API key.

  • Should you attempt to access an non-permitted tenant/channel (due to an incorrect API key, for example), you will see an error message similar to: update failed: FeignException: status 403 reading QueryApiTarget#getModificationTime(Tenant); content: {“message”:”Invalid authentication credentials”}

  • Enable debug logging, in order to obtain more information concerning internal activities. Activate this using the following docker startup parameter -e JAVA_OPTS=”-Dlogging.level.io.searchhub=DEBUG”