@Override
    @SuppressWarnings("nls")
    public void listClientVersions(String organizationId, String clientId, int page, int pageSize, IAsyncResultHandler<List<String>> handler) {
        String query = "{" +
                "  \"query\": {" +
                "    \"bool\": {" +
                "      \"filter\": [" +
                "        {" +
                "          \"term\": {" +
                "            \"organizationId\": \"{{organizationId}}\"" +  // organizationId
                "          }" +
                "        }," +
                "        {" +
                "          \"term\": {" +
                "            \"clientId\": \"{{clientId}}\"" + // clientId
                "          }" +
                "        }" +
                "      ]" +
                "    }" +
                "  }," +
                "    \"aggs\": {" +
                "      \"client_versions\": {" +
                "        \"terms\": {" +
                "          \"field\": \"version\"" + // only return version fields of clients
                "        }" +
                "      }" +
                "    }" +
                "}";

        SearchTemplateRequest searchTemplateRequest = new SearchTemplateRequest();
        searchTemplateRequest.setRequest(new SearchRequest(getIndexPrefixWithJoiner() + EsConstants.INDEX_CLIENTS));
        searchTemplateRequest.setScriptType(ScriptType.INLINE);
        searchTemplateRequest.setScript(query);

        Map<String, Object> scriptParams = new HashMap<>();
        scriptParams.put("organizationId", organizationId);
        scriptParams.put("clientId", clientId);

        searchTemplateRequest.setScriptParams(scriptParams);

        try {
            SearchTemplateResponse response = getClient().searchTemplate(searchTemplateRequest, RequestOptions.DEFAULT);
            SearchResponse searchResponse = response.getResponse();

            List terms = ((ParsedTerms) searchResponse.getAggregations().asMap().get("client_versions")).getBuckets();
            // Grab only the name of each aggregation (we don't care about count
            List<String> results = (List<String>) terms.stream()
                    .map(o -> ((ParsedTerms.ParsedBucket) o).getKey())
                    .collect(Collectors.toList());

            handler.handle(AsyncResultImpl.create(results));
        } catch (IOException e) {
            LOGGER.error(e.getMessage(), e);
        }
    }
@see io.apiman.gateway.engine.IRegistry#getContract(java.lang.String, java.lang.String, java.lang.String, java.lang.String, io.apiman.gateway.engine.async.IAsyncResultHandler)
gateway/engine/es/src/main/java/io/apiman/gateway/engine/es/EsRegistry.java