[[client]]
== Client

You can use the *Java client* in multiple ways:

* Perform standard <<index_,index>>, <<get,get>>,
  <<delete,delete>> and <<search,search>> operations on an
  existing cluster
* Perform administrative tasks on a running cluster
* Start full nodes when you want to run Elasticsearch embedded in your
  own application  or when you want to launch unit or integration tests

Obtaining an elasticsearch `Client` is simple. The most common way to
get a client is by:

1.  Creating an embedded <<node-client,`Node`>> that acts as a node
within a cluster.
2.  Requesting a `Client` from your embedded `Node`.

Another manner is by creating a <<transport-client,`TransportClient`>>
that connects to a cluster.

*Important:*

______________________________________________________________________________________________________________________________________________________________
Please note that you are encouraged to use the same version on client
and cluster sides. You may hit some incompatibility issues when mixing
major versions.
______________________________________________________________________________________________________________________________________________________________


[[node-client]]
=== Node Client

Instantiating a node based client is the simplest way to get a `Client`
that can execute operations against elasticsearch.

[source,java]
--------------------------------------------------
import static org.elasticsearch.node.NodeBuilder.*;

// on startup

Node node = nodeBuilder().node();
Client client = node.client();

// on shutdown

node.close();
--------------------------------------------------

When you start a `Node`, it joins an elasticsearch cluster. You can have
different clusters by simply setting the `cluster.name` setting, or
explicitly using the `clusterName` method on the builder.

You can define `cluster.name` in the `/src/main/resources/elasticsearch.yml`
file in your project. As long as `elasticsearch.yml` is present in the
classpath, it will be used when you start your node.

[source,yaml]
--------------------------------------------------
cluster.name: yourclustername
--------------------------------------------------

Or in Java:

[source,java]
--------------------------------------------------
Node node = nodeBuilder().clusterName("yourclustername").node();
Client client = node.client();
--------------------------------------------------

The benefit of using the `Client` is the fact that operations are
automatically routed to the node(s) the operations need to be executed
on, without performing a "double hop". For example, the index operation
will automatically be executed on the shard that it will end up existing
at.

When you start a `Node`, the most important decision is whether it
should hold data or not. In other words, should indices and shards be
allocated to it. Many times we would like to have the clients just be
clients, without shards being allocated to them. This is simple to
configure by setting either `node.data` setting to `false` or
`node.client` to `true` (the `NodeBuilder` respective helper methods on
it):

[source,java]
--------------------------------------------------
import static org.elasticsearch.node.NodeBuilder.*;

// on startup

// Embedded node clients behave just like standalone nodes,
// which means that they will leave the HTTP port open!
Node node =
    nodeBuilder()
        .settings(ImmutableSettings.settingsBuilder().put("http.enabled", false))
        .client(true)
    .node();

Client client = node.client();

// on shutdown

node.close();
--------------------------------------------------

Another common usage is to start the `Node` and use the `Client` in
unit/integration tests. In such a case, we would like to start a "local"
`Node` (with a "local" discovery and transport). Again, this is just a
matter of a simple setting when starting the `Node`. Note, "local" here
means local on the JVM (well, actually class loader) level, meaning that
two *local* servers started within the same JVM will discover themselves
and form a cluster.

[source,java]
--------------------------------------------------
import static org.elasticsearch.node.NodeBuilder.*;

// on startup

Node node = nodeBuilder().local(true).node();
Client client = node.client();

// on shutdown

node.close();
--------------------------------------------------

[[node-client-downsides]]
==== Node Client Downsides

Embedding a node client into your application is the easiest way to connect
to an Elasticsearch cluster, but it carries some downsides.

- Frequently starting and stopping one or more node clients creates unnecessary
noise across the cluster.
- Embedded node client will respond to outside requests, just like any other client.
** You almost always want to disable HTTP for an _embedded_ node client.

[[transport-client]]
=== Transport Client

The `TransportClient` connects remotely to an Elasticsearch cluster
using the transport module. It does not join the cluster, but simply
gets one or more initial transport addresses and communicates with them
in round robin fashion on each action (though most actions will probably
be "two hop" operations).

[source,java]
--------------------------------------------------
// on startup

Client client = new TransportClient()
        .addTransportAddress(new InetSocketTransportAddress("host1", 9300))
        .addTransportAddress(new InetSocketTransportAddress("host2", 9300));

// on shutdown

client.close();
--------------------------------------------------

Note that you have to set the cluster name if you use one different than
"elasticsearch":

[source,java]
--------------------------------------------------
Settings settings = ImmutableSettings.settingsBuilder()
        .put("cluster.name", "myClusterName").build();
Client client =    new TransportClient(settings);
//Add transport addresses and do something with the client...
--------------------------------------------------

Or using `elasticsearch.yml` file as shown in <<node-client>>

The client allows to sniff the rest of the cluster, and add those into
its list of machines to use. In this case, note that the IP addresses
used will be the ones that the other nodes were started with (the
"publish" address). In order to enable it, set the
`client.transport.sniff` to `true`:

[source,java]
--------------------------------------------------
Settings settings = ImmutableSettings.settingsBuilder()
        .put("client.transport.sniff", true).build();
TransportClient client = new TransportClient(settings);
--------------------------------------------------

Other transport client level settings include:

[cols="<,<",options="header",]
|=======================================================================
|Parameter |Description
|`client.transport.ignore_cluster_name` |Set to `true` to ignore cluster
name validation of connected nodes. (since 0.19.4)

|`client.transport.ping_timeout` |The time to wait for a ping response
from a node. Defaults to `5s`.

|`client.transport.nodes_sampler_interval` |How often to sample / ping
the nodes listed and connected. Defaults to `5s`.
|=======================================================================
