There are two ways to create a native client to communicate with an Elasticsearch server:
In this recipe, we will see how to create these clients.
You need an up-and-running Elasticsearch installation as we described in the Downloading and installing Elasticsearch recipe in Chapter 2, Downloading and Setup
A Maven tool, or an IDE that natively supports it for Java programming such as Eclipse or IntelliJ IDEA, must be installed
The code for this recipe is in the chapter_14/nativeclient
directory.
To create a native client, we will perform the following steps:
log4j
required dependencies, by adding the following lines to the pom.xml
:<dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>transport</artifactId> <version>5.0.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.6.2</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.6.2</version> </dependency>
log4j2.properties
file with a similar content:appender.console.type = Console appender.console.name = console appender.console.layout.type = PatternLayout rootLogger.level = info rootLogger.appenderRef.console.ref = console
Getting the client from the transport protocol, which is the simplest way to get an Elasticsearch client:
import org.elasticsearch.client.Client; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.transport.client.PreBuiltTransportClient; // on startup final Settings settings = Settings.builder() .put("client.transport.sniff", true) .put("cluster.name", "elasticsearch").build(); TransportClient client = new PreBuiltTransportClient(settings) .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300)); // on shutdown client.close();
Getting the client from a node, which is quite tricky, because we need to define a PluginNode
that loads the transport plugin and retrieve a connection from it:
import org.elasticsearch.client.Client; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.node.Node; // on startup private final Node node; private final Client client; private static class PluginNode extends Node { public PluginNode(Settings preparedSettings, List<Class<? extends Plugin>> plugins) { super(InternalSettingsPreparer.prepareEnvironment (preparedSettings, null), plugins); } } public NativeClient() throws NodeValidationException { final Settings settings = Settings.builder() .put("path.home", "/tmp") .put("client.transport.sniff", true) .put("cluster.name", "elasticsearch") .put("node.data", false) .put("node.master", false) .put("node.ingest", false).build(); node = new PluginNode(settings, Collections.<Class<? extends Plugin>>singletonList(Netty4Plugin.class)); node.start(); client = node.client(); } // on shutdown client.close(); node.close();
The steps to create a TransportClient
are as follows:
final Settings settings = Settings.settingsBuilder() .put("client.transport.sniff", true) .put("cluster.name", "elasticsearch").build();
TransportClient client = new PreBuiltTransportClient(settings) .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300)); ;
addTransportAddress
method can be called several times until all the required addresses and ports are set.pom.xml
the transport plugin must be defined as follows:<dependency> <groupId>org.elasticsearch.plugin</groupId> <artifactId>transport-netty4-client</artifactId> <version>5.0.0</version> </dependency>
PluginNode
, which allows the transport plugin to be loaded:private static class PluginNode extends Node { public PluginNode(Settings preparedSettings, List<Class<? extends Plugin>> plugins) { super(InternalSettingsPreparer.prepareEnvironment (preparedSettings, null), plugins); } }
node
. We need to disable the master, data, and ingest functionalities:final Settings settings = Settings.builder() .put("path.home", "/tmp") .put("client.transport.sniff", true) .put("cluster.name", "elasticsearch") .put("node.data", false) .put("node.master", false) .put("node.ingest", false).build();
node
:node = new PluginNode(settings, Collections.<Class<? extends Plugin>>singletonList(Netty4Plugin.class)); node.start();
node
object, client
can be easily obtained:client = node.client();
client
is retrieved from an embedded node, before closing the application, we need to free the resource needed by the node; this can be done by calling the close()
method on the client
and node
:client.close(); node.close();
The result is the same with both approaches to creating a native client--a working client allows the execution of native calls on an Elasticsearch server.
In both approaches, it is important to correctly define the name of the cluster, otherwise there are problems in node-joining or the transport client gives you a warning about invalid names.
There are several settings that can be passed when creating a transport client. They are as follows:
client.transport.ignore_cluster_name
: If you set it to true
, the cluster name validation of connected nodes is ignored. This prevents a warning being printed if the client cluster name is different from the connected cluster name (default: false
).client.transport.ping_timeout
: Every client pings the node to check its state. This value defines how much time it waits before a timeout (default: 5s
).client.transport.nodes_sampler_interval
: This interval defines how often to sample/ping the nodes listed and connected. These pings reduce the failures if a node is down and allows the requests to be balanced with the available node (default: 5s
).TransportClient
at https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/transport-client.html for more details about it3.148.104.124