123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456 |
- [[java-rest-low-usage]]
- == Getting started
- This section describes how to get started with the low-level REST client from
- getting the artifact to using it in an application.
- [[java-rest-low-javadoc]]
- === Javadoc
- The javadoc for the low level REST client can be found at {rest-client-javadoc}/index.html.
- [[java-rest-low-usage-maven]]
- === Maven Repository
- The low-level Java REST client is hosted on
- https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.elasticsearch.client%22[Maven
- Central]. The minimum Java version required is `1.8`.
- The low-level REST client is subject to the same release cycle as
- Elasticsearch. Replace the version with the desired client version, first
- released with `5.0.0-alpha4`. There is no relation between the client version
- and the Elasticsearch version that the client can communicate with. The
- low-level REST client is compatible with all Elasticsearch versions.
- If you are looking for a SNAPSHOT version, the Elastic Maven Snapshot repository is available
- at https://snapshots.elastic.co/maven/.
- [[java-rest-low-usage-maven-maven]]
- ==== Maven configuration
- Here is how you can configure the dependency using maven as a dependency manager.
- Add the following to your `pom.xml` file:
- ["source","xml",subs="attributes"]
- --------------------------------------------------
- <dependency>
- <groupId>org.elasticsearch.client</groupId>
- <artifactId>elasticsearch-rest-client</artifactId>
- <version>{version}</version>
- </dependency>
- --------------------------------------------------
- [[java-rest-low-usage-maven-gradle]]
- ==== Gradle configuration
- Here is how you can configure the dependency using gradle as a dependency manager.
- Add the following to your `build.gradle` file:
- ["source","groovy",subs="attributes"]
- --------------------------------------------------
- dependencies {
- compile 'org.elasticsearch.client:elasticsearch-rest-client:{version}'
- }
- --------------------------------------------------
- [[java-rest-low-usage-dependencies]]
- === Dependencies
- The low-level Java REST client internally uses the
- https://hc.apache.org/httpcomponents-asyncclient-4.1.x/[Apache Http Async Client]
- to send http requests. It depends on the following artifacts, namely the async
- http client and its own transitive dependencies:
- - org.apache.httpcomponents:httpasyncclient
- - org.apache.httpcomponents:httpcore-nio
- - org.apache.httpcomponents:httpclient
- - org.apache.httpcomponents:httpcore
- - commons-codec:commons-codec
- - commons-logging:commons-logging
- [[java-rest-low-usage-shading]]
- === Shading
- In order to avoid version conflicts, the dependencies can be shaded and packaged
- within the client in a single JAR file (sometimes called an "uber JAR" or "fat
- JAR"). Shading a dependency consists of taking its content (resources files and
- Java class files) and renaming some of its packages before putting them in the
- same JAR file as the low-level Java REST client. Shading a JAR can be
- accomplished by 3rd-party plugins for Gradle and Maven.
- Be advised that shading a JAR also has implications. Shading the Commons Logging
- layer, for instance, means that 3rd-party logging backends need to be shaded as
- well.
- [[java-rest-low-usage-shading-maven]]
- ==== Maven configuration
- Here is a configuration using the Maven
- https://maven.apache.org/plugins/maven-shade-plugin/index.html[Shade]
- plugin. Add the following to your `pom.xml` file:
- ["source","xml",subs="attributes"]
- --------------------------------------------------
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-shade-plugin</artifactId>
- <version>3.1.0</version>
- <executions>
- <execution>
- <phase>package</phase>
- <goals><goal>shade</goal></goals>
- <configuration>
- <relocations>
- <relocation>
- <pattern>org.apache.http</pattern>
- <shadedPattern>hidden.org.apache.http</shadedPattern>
- </relocation>
- <relocation>
- <pattern>org.apache.logging</pattern>
- <shadedPattern>hidden.org.apache.logging</shadedPattern>
- </relocation>
- <relocation>
- <pattern>org.apache.commons.codec</pattern>
- <shadedPattern>hidden.org.apache.commons.codec</shadedPattern>
- </relocation>
- <relocation>
- <pattern>org.apache.commons.logging</pattern>
- <shadedPattern>hidden.org.apache.commons.logging</shadedPattern>
- </relocation>
- </relocations>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- --------------------------------------------------
- [[java-rest-low-usage-shading-gradle]]
- ==== Gradle configuration
- Here is a configuration using the Gradle
- https://github.com/johnrengelman/shadow[ShadowJar] plugin. Add the following to
- your `build.gradle` file:
- ["source","groovy",subs="attributes"]
- --------------------------------------------------
- shadowJar {
- relocate 'org.apache.http', 'hidden.org.apache.http'
- relocate 'org.apache.logging', 'hidden.org.apache.logging'
- relocate 'org.apache.commons.codec', 'hidden.org.apache.commons.codec'
- relocate 'org.apache.commons.logging', 'hidden.org.apache.commons.logging'
- }
- --------------------------------------------------
- [[java-rest-low-usage-initialization]]
- === Initialization
- A `RestClient` instance can be built through the corresponding
- `RestClientBuilder` class, created via `RestClient#builder(HttpHost...)`
- static method. The only required argument is one or more hosts that the
- client will communicate with, provided as instances of
- https://hc.apache.org/httpcomponents-core-4.4.x/current/httpcore/apidocs/org/apache/http/HttpHost.html[HttpHost]
- as follows:
- ["source","java",subs="attributes,callouts,macros"]
- --------------------------------------------------
- include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-init]
- --------------------------------------------------
- The `RestClient` class is thread-safe and ideally has the same lifecycle as
- the application that uses it. It is important that it gets closed when no
- longer needed so that all the resources used by it get properly released,
- as well as the underlying http client instance and its threads:
- ["source","java",subs="attributes,callouts,macros"]
- --------------------------------------------------
- include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-close]
- --------------------------------------------------
- `RestClientBuilder` also allows to optionally set the following configuration
- parameters while building the `RestClient` instance:
- ["source","java",subs="attributes,callouts,macros"]
- --------------------------------------------------
- include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-init-default-headers]
- --------------------------------------------------
- <1> Set the default headers that need to be sent with each request, to
- prevent having to specify them with each single request
- ["source","java",subs="attributes,callouts,macros"]
- --------------------------------------------------
- include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-init-failure-listener]
- --------------------------------------------------
- <1> Set a listener that gets notified every time a node fails, in case actions
- need to be taken. Used internally when sniffing on failure is enabled.
- ["source","java",subs="attributes,callouts,macros"]
- --------------------------------------------------
- include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-init-node-selector]
- --------------------------------------------------
- <1> Set the node selector to be used to filter the nodes the client will send
- requests to among the ones that are set to the client itself. This is useful
- for instance to prevent sending requests to dedicated master nodes when
- sniffing is enabled. By default the client sends requests to every configured
- node.
- ["source","java",subs="attributes,callouts,macros"]
- --------------------------------------------------
- include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-init-request-config-callback]
- --------------------------------------------------
- <1> Set a callback that allows to modify the default request configuration
- (e.g. request timeouts, authentication, or anything that the
- https://hc.apache.org/httpcomponents-client-4.5.x/current/httpclient/apidocs/org/apache/http/client/config/RequestConfig.Builder.html[`org.apache.http.client.config.RequestConfig.Builder`]
- allows to set)
- ["source","java",subs="attributes,callouts,macros"]
- --------------------------------------------------
- include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-init-client-config-callback]
- --------------------------------------------------
- <1> Set a callback that allows to modify the http client configuration
- (e.g. encrypted communication over ssl, or anything that the
- https://hc.apache.org/httpcomponents-asyncclient-4.1.x/current/httpasyncclient/apidocs/org/apache/http/impl/nio/client/HttpAsyncClientBuilder.html[`org.apache.http.impl.nio.client.HttpAsyncClientBuilder`]
- allows to set)
- [[java-rest-low-usage-requests]]
- === Performing requests
- Once the `RestClient` has been created, requests can be sent by calling either
- `performRequest` or `performRequestAsync`. `performRequest` is synchronous and
- will block the calling thread and return the `Response` when the request is
- successful or throw an exception if it fails. `performRequestAsync` is
- asynchronous and accepts a `ResponseListener` argument that it calls with a
- `Response` when the request is successful or with an `Exception` if it fails.
- This is synchronous:
- ["source","java",subs="attributes,callouts,macros"]
- --------------------------------------------------
- include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-sync]
- --------------------------------------------------
- <1> The HTTP method (`GET`, `POST`, `HEAD`, etc)
- <2> The endpoint on the server
- And this is asynchronous:
- ["source","java",subs="attributes,callouts,macros"]
- --------------------------------------------------
- include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-async]
- --------------------------------------------------
- <1> The HTTP method (`GET`, `POST`, `HEAD`, etc)
- <2> The endpoint on the server
- <3> Handle the response
- <4> Handle the failure
- You can add request parameters to the request object:
- ["source","java",subs="attributes,callouts,macros"]
- --------------------------------------------------
- include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-parameters]
- --------------------------------------------------
- You can set the body of the request to any `HttpEntity`:
- ["source","java",subs="attributes,callouts,macros"]
- --------------------------------------------------
- include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-body]
- --------------------------------------------------
- IMPORTANT: The `ContentType` specified for the `HttpEntity` is important
- because it will be used to set the `Content-Type` header so that Elasticsearch
- can properly parse the content.
- You can also set it to a `String` which will default to
- a `ContentType` of `application/json`.
- ["source","java",subs="attributes,callouts,macros"]
- --------------------------------------------------
- include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-body-shorter]
- --------------------------------------------------
- [[java-rest-low-usage-request-options]]
- ==== RequestOptions
- The `RequestOptions` class holds parts of the request that should be shared
- between many requests in the same application. You can make a singleton
- instance and share it between all requests:
- ["source","java",subs="attributes,callouts,macros"]
- --------------------------------------------------
- include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-options-singleton]
- --------------------------------------------------
- <1> Add any headers needed by all requests.
- <2> Customize the response consumer.
- `addHeader` is for headers that are required for authorization or to work with
- a proxy in front of Elasticsearch. There is no need to set the `Content-Type`
- header because the client will automatically set that from the `HttpEntity`
- attached to the request.
- You can set the `NodeSelector` which controls which nodes will receive
- requests. `NodeSelector.SKIP_DEDICATED_MASTERS` is a good choice.
- You can also customize the response consumer used to buffer the asynchronous
- responses. The default consumer will buffer up to 100MB of response on the
- JVM heap. If the response is larger then the request will fail. You could,
- for example, lower the maximum size which might be useful if you are running
- in a heap constrained environment like the example above.
- Once you've created the singleton you can use it when making requests:
- ["source","java",subs="attributes,callouts,macros"]
- --------------------------------------------------
- include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-options-set-singleton]
- --------------------------------------------------
- You can also customize these options on a per request basis. For example, this
- adds an extra header:
- ["source","java",subs="attributes,callouts,macros"]
- --------------------------------------------------
- include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-options-customize-header]
- --------------------------------------------------
- ==== Multiple parallel asynchronous actions
- The client is quite happy to execute many actions in parallel. The following
- example indexes many documents in parallel. In a real world scenario you'd
- probably want to use the `_bulk` API instead, but the example is illustrative.
- ["source","java",subs="attributes,callouts,macros"]
- --------------------------------------------------
- include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-async-example]
- --------------------------------------------------
- <1> Process the returned response
- <2> Handle the returned exception, due to communication error or a response
- with status code that indicates an error
- ==== Cancelling asynchronous requests
- The `performRequestAsync` method returns a `Cancellable` that exposes a single
- public method called `cancel`. Such method can be called to cancel the on-going
- request. Cancelling a request will result in aborting the http request through
- the underlying http client. On the server side, this does not automatically
- translate to the execution of that request being cancelled, which needs to be
- specifically implemented in the API itself.
- The use of the `Cancellable` instance is optional and you can safely ignore this
- if you don't need it. A typical usecase for this would be using this together with
- frameworks like Rx Java or the Kotlin's `suspendCancellableCoRoutine`. Cancelling
- no longer needed requests is a good way to avoid putting unnecessary
- load on Elasticsearch.
- ["source","java",subs="attributes,callouts,macros"]
- --------------------------------------------------
- include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-async-cancel]
- --------------------------------------------------
- <1> Process the returned response, in case it was ready before the request got cancelled
- <2> Handle the returned exception, which will most likely be a `CancellationException` as the request got cancelled
- [[java-rest-low-usage-responses]]
- === Reading responses
- The `Response` object, either returned by the synchronous `performRequest` methods or
- received as an argument in `ResponseListener#onSuccess(Response)`, wraps the
- response object returned by the http client and exposes some additional information.
- ["source","java",subs="attributes,callouts,macros"]
- --------------------------------------------------
- include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-response2]
- --------------------------------------------------
- <1> Information about the performed request
- <2> The host that returned the response
- <3> The response status line, from which you can for instance retrieve the status code
- <4> The response headers, which can also be retrieved by name though `getHeader(String)`
- <5> The response body enclosed in an https://hc.apache.org/httpcomponents-core-4.4.x/current/httpcore/apidocs/org/apache/http/HttpEntity.html[`org.apache.http.HttpEntity`]
- object
- When performing a request, an exception is thrown (or received as an argument
- in `ResponseListener#onFailure(Exception)` in the following scenarios:
- `IOException`:: communication problem (e.g. SocketTimeoutException)
- `ResponseException`:: a response was returned, but its status code indicated
- an error (not `2xx`). A `ResponseException` originates from a valid
- http response, hence it exposes its corresponding `Response` object which gives
- access to the returned response.
- NOTE: A `ResponseException` is **not** thrown for `HEAD` requests that return
- a `404` status code because it is an expected `HEAD` response that simply
- denotes that the resource is not found. All other HTTP methods (e.g., `GET`)
- throw a `ResponseException` for `404` responses unless the `ignore` parameter
- contains `404`. `ignore` is a special client parameter that doesn't get sent
- to Elasticsearch and contains a comma separated list of error status codes.
- It allows to control whether some error status code should be treated as an
- expected response rather than as an exception. This is useful for instance
- with the get api as it can return `404` when the document is missing, in which
- case the response body will not contain an error but rather the usual get api
- response, just without the document as it was not found.
- Note that the low-level client doesn't expose any helper for json marshalling
- and un-marshalling. Users are free to use the library that they prefer for that
- purpose.
- The underlying Apache Async Http Client ships with different
- https://hc.apache.org/httpcomponents-core-4.4.x/current/httpcore/apidocs/org/apache/http/HttpEntity.html[`org.apache.http.HttpEntity`]
- implementations that allow to provide the request body in different formats
- (stream, byte array, string etc.). As for reading the response body, the
- `HttpEntity#getContent` method comes handy which returns an `InputStream`
- reading from the previously buffered response body. As an alternative, it is
- possible to provide a custom
- https://hc.apache.org/httpcomponents-core-4.4.x/current/httpcore-nio/apidocs/org/apache/http/nio/protocol/HttpAsyncResponseConsumer.html[`org.apache.http.nio.protocol.HttpAsyncResponseConsumer`]
- that controls how bytes are read and buffered.
- [[java-rest-low-usage-logging]]
- === Logging
- The Java REST client uses the same logging library that the Apache Async Http
- Client uses: https://commons.apache.org/proper/commons-logging/[Apache Commons Logging],
- which comes with support for a number of popular logging implementations. The
- java packages to enable logging for are `org.elasticsearch.client` for the
- client itself and `org.elasticsearch.client.sniffer` for the sniffer.
- The request tracer logging can also be enabled to log every request and
- corresponding response in curl format. That comes handy when debugging, for
- instance in case a request needs to be manually executed to check whether it
- still yields the same response as it did. Enable trace logging for the `tracer`
- package to have such log lines printed out. Do note that this type of logging is
- expensive and should not be enabled at all times in production environments,
- but rather temporarily used only when needed.
- ==== Logback
- ===== Trace Logs
- In order to enable trace logs for logback, we have to use https://www.slf4j.org/legacy.html#jclOverSLF4J[jcl-over-slf4j bridging module].
- 1. Add the following to your Gradle setting:
- [source,groovy]
- dependencies {
- implementation('org.slf4j:slf4j-api:1.8.0-beta2')
- implementation('ch.qos.logback:logback-classic:1.3.0-alpha4')
- implementation('org.slf4j:jcl-over-slf4j:1.8.0-beta2')
- }
- 2. Exclude `commons-logging.jar`:
- [source,groovy]
- dependencies {
- configurations.all {
- exclude group: "commons-logging", module: "commons-logging"
- }
- }
- 3. Add a tracer logger in Logback configuration:
- [source,xml]
- <logger name="tracer" level="TRACE" additivity="false">
- <appender-ref ref="your_appender_block_name" />
- </logger>
- ===== RestClient Debug Logs
- To enable debug logs for `RestClient` class, add the following to your Logback configuration:
- [source,xml]
- <logger name="org.elasticsearch.client.RestClient" level="DEBUG" additivity="false">
- <appender-ref ref="your_appender_block_name" />
- </logger>
|