Last active
September 14, 2018 13:22
-
-
Save hkorte/cb20352171702446505d6bee693114a3 to your computer and use it in GitHub Desktop.
This example shows a strange behavior of the Elasticsearch TransportClient in version 5.6.11
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<project xmlns="http://maven.apache.org/POM/4.0.0" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<groupId>toyexample</groupId> | |
<artifactId>es-tester</artifactId> | |
<version>1.0-SNAPSHOT</version> | |
<dependencies> | |
<dependency> | |
<groupId>org.testcontainers</groupId> | |
<artifactId>testcontainers</artifactId> | |
<version>1.8.0</version> | |
</dependency> | |
<dependency> | |
<groupId>org.elasticsearch</groupId> | |
<artifactId>elasticsearch</artifactId> | |
<version>5.6.11</version> | |
</dependency> | |
<dependency> | |
<groupId>org.elasticsearch.client</groupId> | |
<artifactId>transport</artifactId> | |
<version>5.6.11</version> | |
</dependency> | |
<dependency> | |
<groupId>org.elasticsearch.client</groupId> | |
<artifactId>elasticsearch-rest-high-level-client</artifactId> | |
<version>5.6.11</version> | |
</dependency> | |
</dependencies> | |
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package test; | |
import org.apache.http.HttpEntity; | |
import org.apache.http.HttpHost; | |
import org.apache.http.entity.ContentType; | |
import org.apache.http.nio.entity.NStringEntity; | |
import org.apache.http.util.EntityUtils; | |
import org.elasticsearch.client.Response; | |
import org.elasticsearch.client.RestClient; | |
import org.elasticsearch.client.transport.TransportClient; | |
import org.elasticsearch.common.bytes.BytesArray; | |
import org.elasticsearch.common.settings.Settings; | |
import org.elasticsearch.common.transport.InetSocketTransportAddress; | |
import org.elasticsearch.common.xcontent.XContentType; | |
import org.elasticsearch.transport.client.PreBuiltTransportClient; | |
import org.testcontainers.containers.GenericContainer; | |
import java.io.IOException; | |
import java.net.InetAddress; | |
import java.util.Collections; | |
import java.util.Map; | |
public class PutStoredScriptExample { | |
public static void main(String[] args) throws IOException { | |
// start an ES node, a transport client, and a rest client | |
GenericContainer service = | |
new GenericContainer("docker.elastic.co/elasticsearch/elasticsearch:5.6.11") | |
.withEnv("xpack.security.enabled", "false") | |
.withExposedPorts(9200, 9300); | |
service.start(); | |
String ip = service.getContainerIpAddress(); | |
RestClient restClient = | |
RestClient.builder(new HttpHost(ip, service.getMappedPort(9200), "http")).build(); | |
Settings settings = Settings.builder().put("cluster.name", "docker-cluster").build(); | |
TransportClient transportClient = | |
new PreBuiltTransportClient(settings) | |
.addTransportAddress( | |
new InetSocketTransportAddress( | |
InetAddress.getByName(ip), service.getMappedPort(9300))); | |
// store a script using the transport client | |
String scriptSource = "{\"size\": 6,\"query\": {\"match_all\": {}}}"; | |
transportClient | |
.admin() | |
.cluster() | |
.preparePutStoredScript() | |
.setId("TEST1") | |
.setLang("mustache") | |
.setContent(new BytesArray(scriptSource), XContentType.JSON) | |
.get(); | |
// actually stored is only the first field of the source! | |
// this prints: | |
// {"_id":"TEST1","found":true,"script":{"lang":"mustache","source":"{\"size\":6}"}} | |
Response response = restClient.performRequest("GET", "/_scripts/TEST1"); | |
System.out.println(EntityUtils.toString(response.getEntity())); | |
// we swap the field order in the source.. | |
scriptSource = "{\"query\": {\"match_all\": {}},\"size\": 6}"; | |
transportClient | |
.admin() | |
.cluster() | |
.preparePutStoredScript() | |
.setId("TEST2") | |
.setLang("mustache") | |
.setContent(new BytesArray(scriptSource), XContentType.JSON) | |
.get(); | |
// now only the query is stored - the size field is ignored! | |
// this prints: | |
// {"_id":"TEST2","found":true,"script":{"lang":"mustache","source":"{\"query\":{\"match_all\":{}}}"}} | |
response = restClient.performRequest("GET", "/_scripts/TEST2"); | |
System.out.println(EntityUtils.toString(response.getEntity())); | |
// we try to store the same script using the rest client | |
Map<String, String> params = Collections.emptyMap(); | |
String body = "{\"script\":{\"lang\":\"mustache\",\"source\":" + scriptSource + "}}"; | |
HttpEntity entity = new NStringEntity(body, ContentType.APPLICATION_JSON); | |
restClient.performRequest("PUT", "/_scripts/TEST3", params, entity); | |
// using the rest client the whole script with query and size fields is stored.. | |
// this prints: | |
// {"_id":"TEST3","found":true,"script":{"lang":"mustache","source":"{\"query\":{\"match_all\":{}},\"size\":6}","options":{"content_type":"application/json; charset=UTF-8"}}} | |
response = restClient.performRequest("GET", "/_scripts/TEST3"); | |
System.out.println(EntityUtils.toString(response.getEntity())); | |
// as it turned out, the trick is to wrap the script source in a script element.. | |
// see: https://discuss.elastic.co/t/scripts-stored-via-transportclient-lose-fields-in-source/148473/3 | |
transportClient | |
.admin() | |
.cluster() | |
.preparePutStoredScript() | |
.setId("TEST4") | |
.setLang("mustache") | |
.setContent(new BytesArray("{\"script\":" + scriptSource + "}"), XContentType.JSON) | |
.get(); | |
// and - tadaa - the whole script with query and size fields is stored! | |
// this prints: | |
// {"_id":"TEST4","found":true,"script":{"lang":"mustache","source":"{\"query\":{\"match_all\":{}},\"size\":6}"}} | |
response = restClient.performRequest("GET", "/_scripts/TEST4"); | |
System.out.println(EntityUtils.toString(response.getEntity())); | |
transportClient.close(); | |
restClient.close(); | |
service.stop(); | |
service.close(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment