﻿---
title: Sniffer in the Elasticsearch Java REST 5 client
description: Minimal library that allows to automatically discover nodes from a running Elasticsearch cluster and set them to an existing RestClient instance. It retrieves...
url: https://www.elastic.co/elastic/docs-builder/docs/2910/reference/elasticsearch/clients/java/transport/rest5-client/sniffer
products:
  - Elasticsearch Client
  - Elasticsearch Java Client
---

# Sniffer in the Elasticsearch Java REST 5 client
Minimal library that allows to automatically discover nodes from a running Elasticsearch cluster and set them to an existing `RestClient` instance. It retrieves by default the nodes that belong to the cluster using the Nodes Info api and uses jackson to parse the obtained json response.

# Usage

Once a `RestClient` instance has been created as shown in [Initialization](https://www.elastic.co/elastic/docs-builder/docs/2910/reference/elasticsearch/clients/java/transport/rest5-client/usage/initialization), a `Sniffer` can be associated to it. The `Sniffer` will make use of the provided `RestClient` to periodically (every 5 minutes by default) fetch the list of current nodes from the cluster and update them by calling `RestClient#setNodes`.
```java
Rest5Client restClient = Rest5Client
    .builder(HttpHost.create("http://localhost:9200"))
    .build();

Sniffer sniffer = Sniffer.builder(restClient).build();
```

It is important to close the `Sniffer` so that its background thread gets properly shutdown and all of its resources are released. The `Sniffer` object should have the same lifecycle as the `RestClient` and get closed right before the client:
```java
sniffer.close();
restClient.close();
```

The `Sniffer` updates the nodes by default every 5 minutes. This interval can be customized by providing it (in milliseconds) as follows:
```java
Rest5Client restClient = Rest5Client
    .builder(new HttpHost("localhost", 9200))
    .build();

Sniffer sniffer = Sniffer.builder(restClient)
    .setSniffIntervalMillis(60000).build();
```

It is also possible to enable sniffing on failure, meaning that after each failure the nodes list gets updated straightaway rather than at the following ordinary sniffing round. In this case a `SniffOnFailureListener` needs to be created at first and provided at `RestClient` creation. Also once the `Sniffer` is later created, it needs to be associated with that same `SniffOnFailureListener` instance, which will be notified at each failure and use the `Sniffer` to perform the additional sniffing round as described.
```java
SniffOnFailureListener sniffOnFailureListener =
    new SniffOnFailureListener();

Rest5Client restClient = Rest5Client
    .builder(new HttpHost("localhost", 9200))
    .setFailureListener(sniffOnFailureListener)
    .build();

Sniffer sniffer = Sniffer.builder(restClient)
    .setSniffAfterFailureDelayMillis(30000)
    .build();

sniffOnFailureListener.setSniffer(sniffer);
```

The Elasticsearch Nodes Info api doesn’t return the protocol to use when connecting to the nodes but only their `host:port` key-pair, hence `http` is used by default. In case `https` should be used instead, the `ElasticsearchNodesSniffer` instance has to be manually created and provided as follows:
```java
Rest5Client restClient = Rest5Client.builder(
        new HttpHost("localhost", 9200))
        .build();

NodesSniffer nodesSniffer = new ElasticsearchNodesSniffer(
        restClient,
        ElasticsearchNodesSniffer.DEFAULT_SNIFF_REQUEST_TIMEOUT,
        ElasticsearchNodesSniffer.Scheme.HTTPS
);

Sniffer sniffer = Sniffer.builder(restClient)
        .setNodesSniffer(nodesSniffer).build();
```

In the same way it is also possible to customize the `sniffRequestTimeout`, which defaults to one second. That is the `timeout` parameter provided as a query string parameter when calling the Nodes Info api, so that when the timeout expires on the server side, a valid response is still returned although it may contain only a subset of the nodes that are part of the cluster, the ones that have responded until then.
```java
Rest5Client restClient = Rest5Client.builder(
    new HttpHost("localhost", 9200))
    .build();

NodesSniffer nodesSniffer = new ElasticsearchNodesSniffer(
    restClient,
    TimeUnit.SECONDS.toMillis(5),
    ElasticsearchNodesSniffer.Scheme.HTTP
);

Sniffer sniffer = Sniffer.builder(restClient)
    .setNodesSniffer(nodesSniffer).build();
```

Also, a custom `NodesSniffer` implementation can be provided for advanced use cases that may require fetching the nodes from external sources rather than from Elasticsearch:
```java
Rest5Client restClient = Rest5Client
    .builder(URI.create("http://localhost:9200"))
    .build();

NodesSniffer nodesSniffer = new NodesSniffer() {
    @Override
    public List<Node> sniff() throws IOException {
        return null;
    }
};

Sniffer sniffer = Sniffer.builder(restClient)
    .setNodesSniffer(nodesSniffer).build();
```