I have been using the SearchTemplateRequest class to execute my requests which uses Mustache templating to parse my template string with the passed parameters.
Elasticsearch Template - Converting Parameters to JSON
However, I have to change my implementation where I will be switching to the Java Low-Level Client. I want to use the Mustache implementation that SearchTemplateRequest uses internally to parse the template.
I'm okay to use the Mustache dependency or use the Elasticsearch implementation of it. Could someone help me out here?
My Template String:
{
"query": {
"bool": {
"filter": "{{#toJson}}clauses{{/toJson}}"
}
}
}
My Params Object:
{
"clauses": [
{
"term": {
"field1": "field1Value"
}
}
]
}
My test code:
StringWriter writer = new StringWriter();
MustacheFactory mustacheFactory = new DefaultMustacheFactory();
mustacheFactory.compile(new StringReader(requestTemplate), "templateName").execute(writer, params);
writer.flush();
The above code returns me the request template string with empty strings replacing the template.
Returned Response:
{
"query": {
"bool": {
"filter": ""
}
}
}
Expected Response:
{
"query": {
"bool": {
"filter": [
{
"term": {
"field1": "field1Value"
}
}
]
}
}
}
I finally figured out the solution.
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptEngine;
import org.elasticsearch.script.TemplateScript;
import org.elasticsearch.script.mustache.MustacheScriptEngine;
import java.util.Map;
import static java.util.Collections.singletonMap;
public class CustomMustacheScriptEngine {
private final String JSON_MIME_TYPE_WITH_CHARSET = "application/json; charset=UTF-8";
private final String JSON_MIME_TYPE = "application/json";
private final String PLAIN_TEXT_MIME_TYPE = "text/plain";
private final String X_WWW_FORM_URLENCODED_MIME_TYPE = "application/x-www-form-urlencoded";
private final String DEFAULT_MIME_TYPE = JSON_MIME_TYPE;
private final Map<String, String> params = singletonMap(Script.CONTENT_TYPE_OPTION, JSON_MIME_TYPE_WITH_CHARSET);
public String compile(String jsonScript, final Map<String, Object> scriptParams) {
jsonScript = jsonScript.replaceAll("\"\\{\\{#toJson}}", "{{#toJson}}").replaceAll("\\{\\{/toJson}}\"", "{{/toJson}}");
final ScriptEngine engine = new MustacheScriptEngine();
TemplateScript.Factory compiled = engine.compile("ScriptTemplate", jsonScript, TemplateScript.CONTEXT, params);
TemplateScript executable = compiled.newInstance(scriptParams);
String renderedJsonScript = executable.execute();
return renderedJsonScript;
}
}