Browse Source

[DOCS] Rewrite low-level REST client docs and verify snippets compile (#25559)

Using the infra that we now have in place, we can convert the low-level REST client docs so that they extract code snippets from real Java classes. This way we make sure that all the snippets properly compile. Compared to the high level REST client docs, in this case we don't run the tests themselves, as that would require depending on test-framework which requires java 8 while the low-level REST client is compatible with java 7. I think that compiling snippets is enough for now.
Luca Cavanna 8 years ago
parent
commit
26bc900058

+ 337 - 0
client/rest/src/test/java/org/elasticsearch/client/documentation/RestClientDocumentation.java

@@ -0,0 +1,337 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.client.documentation;
+
+import org.apache.http.Header;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHost;
+import org.apache.http.RequestLine;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.entity.ContentType;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
+import org.apache.http.impl.nio.reactor.IOReactorConfig;
+import org.apache.http.message.BasicHeader;
+import org.apache.http.nio.entity.NStringEntity;
+import org.apache.http.util.EntityUtils;
+import org.elasticsearch.client.HttpAsyncResponseConsumerFactory;
+import org.elasticsearch.client.Response;
+import org.elasticsearch.client.ResponseListener;
+import org.elasticsearch.client.RestClient;
+import org.elasticsearch.client.RestClientBuilder;
+
+import javax.net.ssl.SSLContext;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * This class is used to generate the Java low-level REST client documentation.
+ * You need to wrap your code between two tags like:
+ * // tag::example[]
+ * // end::example[]
+ *
+ * Where example is your tag name.
+ *
+ * Then in the documentation, you can extract what is between tag and end tags with
+ * ["source","java",subs="attributes,callouts,macros"]
+ * --------------------------------------------------
+ * include-tagged::{doc-tests}/RestClientDocumentation.java[example]
+ * --------------------------------------------------
+ *
+ * Note that this is not a test class as we are only interested in testing that docs snippets compile. We don't want
+ * to send requests to a node and we don't even have the tools to do it.
+ */
+@SuppressWarnings("unused")
+public class RestClientDocumentation {
+
+    @SuppressWarnings("unused")
+    public void testUsage() throws IOException, InterruptedException {
+
+        //tag::rest-client-init
+        RestClient restClient = RestClient.builder(
+                new HttpHost("localhost", 9200, "http"),
+                new HttpHost("localhost", 9201, "http")).build();
+        //end::rest-client-init
+
+        //tag::rest-client-close
+        restClient.close();
+        //end::rest-client-close
+
+        {
+            //tag::rest-client-init-default-headers
+            RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "http"));
+            Header[] defaultHeaders = new Header[]{new BasicHeader("header", "value")};
+            builder.setDefaultHeaders(defaultHeaders); // <1>
+            //end::rest-client-init-default-headers
+        }
+        {
+            //tag::rest-client-init-max-retry-timeout
+            RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "http"));
+            builder.setMaxRetryTimeoutMillis(10000); // <1>
+            //end::rest-client-init-max-retry-timeout
+        }
+        {
+            //tag::rest-client-init-failure-listener
+            RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "http"));
+            builder.setFailureListener(new RestClient.FailureListener() {
+                @Override
+                public void onFailure(HttpHost host) {
+                    // <1>
+                }
+            });
+            //end::rest-client-init-failure-listener
+        }
+        {
+            //tag::rest-client-init-request-config-callback
+            RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "http"));
+            builder.setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() {
+                @Override
+                public RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder requestConfigBuilder) {
+                    return requestConfigBuilder.setSocketTimeout(10000); // <1>
+                }
+            });
+            //end::rest-client-init-request-config-callback
+        }
+        {
+            //tag::rest-client-init-client-config-callback
+            RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "http"));
+            builder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
+                @Override
+                public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
+                    return httpClientBuilder.setProxy(new HttpHost("proxy", 9000, "http"));  // <1>
+                }
+            });
+            //end::rest-client-init-client-config-callback
+        }
+
+        {
+            //tag::rest-client-verb-endpoint
+            Response response = restClient.performRequest("GET", "/"); // <1>
+            //end::rest-client-verb-endpoint
+        }
+        {
+            //tag::rest-client-headers
+            Response response = restClient.performRequest("GET", "/", new BasicHeader("header", "value"));
+            //end::rest-client-headers
+        }
+        {
+            //tag::rest-client-verb-endpoint-params
+            Map<String, String> params = Collections.singletonMap("pretty", "true");
+            Response response = restClient.performRequest("GET", "/", params); // <1>
+            //end::rest-client-verb-endpoint-params
+        }
+        {
+            //tag::rest-client-verb-endpoint-params-body
+            Map<String, String> params = Collections.emptyMap();
+            String jsonString = "{" +
+                        "\"user\":\"kimchy\"," +
+                        "\"postDate\":\"2013-01-30\"," +
+                        "\"message\":\"trying out Elasticsearch\"" +
+                    "}";
+            HttpEntity entity = new NStringEntity(jsonString, ContentType.APPLICATION_JSON);
+            Response response = restClient.performRequest("PUT", "/posts/doc/1", params, entity); // <1>
+            //end::rest-client-verb-endpoint-params-body
+        }
+        {
+            //tag::rest-client-response-consumer
+            Map<String, String> params = Collections.emptyMap();
+            HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory consumerFactory =
+                    new HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory(30 * 1024 * 1024);
+            Response response = restClient.performRequest("GET", "/posts/_search", params, null, consumerFactory); // <1>
+            //end::rest-client-response-consumer
+        }
+        {
+            //tag::rest-client-verb-endpoint-async
+            ResponseListener responseListener = new ResponseListener() {
+                @Override
+                public void onSuccess(Response response) {
+                    // <1>
+                }
+
+                @Override
+                public void onFailure(Exception exception) {
+                    // <2>
+                }
+            };
+            restClient.performRequestAsync("GET", "/", responseListener); // <3>
+            //end::rest-client-verb-endpoint-async
+
+            //tag::rest-client-headers-async
+            Header[] headers = {
+                    new BasicHeader("header1", "value1"),
+                    new BasicHeader("header2", "value2")
+            };
+            restClient.performRequestAsync("GET", "/", responseListener, headers);
+            //end::rest-client-headers-async
+
+            //tag::rest-client-verb-endpoint-params-async
+            Map<String, String> params = Collections.singletonMap("pretty", "true");
+            restClient.performRequestAsync("GET", "/", params, responseListener); // <1>
+            //end::rest-client-verb-endpoint-params-async
+
+            //tag::rest-client-verb-endpoint-params-body-async
+            String jsonString = "{" +
+                    "\"user\":\"kimchy\"," +
+                    "\"postDate\":\"2013-01-30\"," +
+                    "\"message\":\"trying out Elasticsearch\"" +
+                    "}";
+            HttpEntity entity = new NStringEntity(jsonString, ContentType.APPLICATION_JSON);
+            restClient.performRequestAsync("PUT", "/posts/doc/1", params, entity, responseListener); // <1>
+            //end::rest-client-verb-endpoint-params-body-async
+
+            //tag::rest-client-response-consumer-async
+            HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory consumerFactory =
+                    new HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory(30 * 1024 * 1024);
+            restClient.performRequestAsync("GET", "/posts/_search", params, null, consumerFactory, responseListener); // <1>
+            //end::rest-client-response-consumer-async
+        }
+        {
+            //tag::rest-client-response2
+            Response response = restClient.performRequest("GET", "/");
+            RequestLine requestLine = response.getRequestLine(); // <1>
+            HttpHost host = response.getHost(); // <2>
+            int statusCode = response.getStatusLine().getStatusCode(); // <3>
+            Header[] headers = response.getHeaders(); // <4>
+            String responseBody = EntityUtils.toString(response.getEntity()); // <5>
+            //end::rest-client-response2
+        }
+        {
+            HttpEntity[] documents = new HttpEntity[10];
+            //tag::rest-client-async-example
+            final CountDownLatch latch = new CountDownLatch(documents.length);
+            for (int i = 0; i < documents.length; i++) {
+                restClient.performRequestAsync(
+                        "PUT",
+                        "/posts/doc/" + i,
+                        Collections.<String, String>emptyMap(),
+                        //let's assume that the documents are stored in an HttpEntity array
+                        documents[i],
+                        new ResponseListener() {
+                            @Override
+                            public void onSuccess(Response response) {
+                                // <1>
+                                latch.countDown();
+                            }
+
+                            @Override
+                            public void onFailure(Exception exception) {
+                                // <2>
+                                latch.countDown();
+                            }
+                        }
+                );
+            }
+            latch.await();
+            //end::rest-client-async-example
+        }
+
+    }
+
+    @SuppressWarnings("unused")
+    public void testCommonConfiguration() throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException {
+        {
+            //tag::rest-client-config-timeouts
+            RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200))
+                    .setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() {
+                        @Override
+                        public RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder requestConfigBuilder) {
+                            return requestConfigBuilder.setConnectTimeout(5000)
+                                    .setSocketTimeout(60000);
+                        }
+                    })
+                    .setMaxRetryTimeoutMillis(60000);
+            //end::rest-client-config-timeouts
+        }
+        {
+            //tag::rest-client-config-threads
+            RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200))
+                    .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
+                        @Override
+                        public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
+                            return httpClientBuilder.setDefaultIOReactorConfig(
+                                    IOReactorConfig.custom().setIoThreadCount(1).build());
+                        }
+                    });
+            //end::rest-client-config-threads
+        }
+        {
+            //tag::rest-client-config-basic-auth
+            final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+            credentialsProvider.setCredentials(AuthScope.ANY,
+                    new UsernamePasswordCredentials("user", "password"));
+
+            RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200))
+                    .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
+                        @Override
+                        public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
+                            return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
+                        }
+                    });
+            //end::rest-client-config-basic-auth
+        }
+        {
+            //tag::rest-client-config-disable-preemptive-auth
+            final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+            credentialsProvider.setCredentials(AuthScope.ANY,
+                    new UsernamePasswordCredentials("user", "password"));
+
+            RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200))
+                    .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
+                        @Override
+                        public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
+                            httpClientBuilder.disableAuthCaching(); // <1>
+                            return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
+                        }
+                    });
+            //end::rest-client-config-disable-preemptive-auth
+        }
+        {
+            Path keyStorePath = Paths.get("");
+            String keyStorePass = "";
+            final SSLContext sslContext = null;
+            //tag::rest-client-config-encrypted-communication
+            KeyStore keystore = KeyStore.getInstance("jks");
+            try (InputStream is = Files.newInputStream(keyStorePath)) {
+                keystore.load(is, keyStorePass.toCharArray());
+            }
+            RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200))
+                    .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
+                        @Override
+                        public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
+                            return httpClientBuilder.setSSLContext(sslContext);
+                        }
+                    });
+            //end::rest-client-config-encrypted-communication
+        }
+    }
+}

+ 131 - 0
client/sniffer/src/test/java/org/elasticsearch/client/sniff/documentation/SnifferDocumentation.java

@@ -0,0 +1,131 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.client.sniff.documentation;
+
+import org.apache.http.HttpHost;
+import org.elasticsearch.client.RestClient;
+import org.elasticsearch.client.sniff.ElasticsearchHostsSniffer;
+import org.elasticsearch.client.sniff.HostsSniffer;
+import org.elasticsearch.client.sniff.SniffOnFailureListener;
+import org.elasticsearch.client.sniff.Sniffer;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This class is used to generate the Java low-level REST client documentation.
+ * You need to wrap your code between two tags like:
+ * // tag::example[]
+ * // end::example[]
+ *
+ * Where example is your tag name.
+ *
+ * Then in the documentation, you can extract what is between tag and end tags with
+ * ["source","java",subs="attributes,callouts,macros"]
+ * --------------------------------------------------
+ * include-tagged::{doc-tests}/SnifferDocumentation.java[example]
+ * --------------------------------------------------
+ *
+ * Note that this is not a test class as we are only interested in testing that docs snippets compile. We don't want
+ * to send requests to a node and we don't even have the tools to do it.
+ */
+@SuppressWarnings("unused")
+public class SnifferDocumentation {
+
+    @SuppressWarnings("unused")
+    public void testUsage() throws IOException {
+        {
+            //tag::sniffer-init
+            RestClient restClient = RestClient.builder(
+                    new HttpHost("localhost", 9200, "http"))
+                    .build();
+            Sniffer sniffer = Sniffer.builder(restClient).build();
+            //end::sniffer-init
+
+            //tag::sniffer-close
+            sniffer.close();
+            restClient.close();
+            //end::sniffer-close
+        }
+        {
+            //tag::sniffer-interval
+            RestClient restClient = RestClient.builder(
+                    new HttpHost("localhost", 9200, "http"))
+                    .build();
+            Sniffer sniffer = Sniffer.builder(restClient)
+                    .setSniffIntervalMillis(60000).build();
+            //end::sniffer-interval
+        }
+        {
+            //tag::sniff-on-failure
+            SniffOnFailureListener sniffOnFailureListener = new SniffOnFailureListener();
+            RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200))
+                    .setFailureListener(sniffOnFailureListener) // <1>
+                    .build();
+            Sniffer sniffer = Sniffer.builder(restClient)
+                    .setSniffAfterFailureDelayMillis(30000) // <2>
+                    .build();
+            sniffOnFailureListener.setSniffer(sniffer); // <3>
+            //end::sniff-on-failure
+        }
+        {
+            //tag::sniffer-https
+            RestClient restClient = RestClient.builder(
+                    new HttpHost("localhost", 9200, "http"))
+                    .build();
+            HostsSniffer hostsSniffer = new ElasticsearchHostsSniffer(
+                    restClient,
+                    ElasticsearchHostsSniffer.DEFAULT_SNIFF_REQUEST_TIMEOUT,
+                    ElasticsearchHostsSniffer.Scheme.HTTPS);
+            Sniffer sniffer = Sniffer.builder(restClient)
+                    .setHostsSniffer(hostsSniffer).build();
+            //end::sniffer-https
+        }
+        {
+            //tag::sniff-request-timeout
+            RestClient restClient = RestClient.builder(
+                    new HttpHost("localhost", 9200, "http"))
+                    .build();
+            HostsSniffer hostsSniffer = new ElasticsearchHostsSniffer(
+                    restClient,
+                    TimeUnit.SECONDS.toMillis(5),
+                    ElasticsearchHostsSniffer.Scheme.HTTP);
+            Sniffer sniffer = Sniffer.builder(restClient)
+                    .setHostsSniffer(hostsSniffer).build();
+            //end::sniff-request-timeout
+        }
+        {
+            //tag::custom-hosts-sniffer
+            RestClient restClient = RestClient.builder(
+                    new HttpHost("localhost", 9200, "http"))
+                    .build();
+            HostsSniffer hostsSniffer = new HostsSniffer() {
+                @Override
+                public List<HttpHost> sniffHosts() throws IOException {
+                    return null; // <1>
+                }
+            };
+            Sniffer sniffer = Sniffer.builder(restClient)
+                    .setHostsSniffer(hostsSniffer).build();
+            //end::custom-hosts-sniffer
+        }
+    }
+}

+ 19 - 70
docs/java-rest/low-level/configuration.asciidoc

@@ -1,12 +1,12 @@
 == Common configuration
 
-The `RestClientBuilder` supports providing both a `RequestConfigCallback` and
-an `HttpClientConfigCallback` which allow for any customization that the Apache
-Async Http Client exposes. Those callbacks make it possible to modify some
-specific behaviour of the client without overriding every other default
-configuration that the `RestClient` is initialized with. This section
-describes some common scenarios that require additional configuration for the
-low-level Java REST Client.
+As explained in <<java-rest-low-usage-initialization>>, the `RestClientBuilder`
+supports providing both a `RequestConfigCallback` and an `HttpClientConfigCallback`
+which allow for any customization that the Apache Async Http Client exposes.
+Those callbacks make it possible to modify some specific behaviour of the client
+without overriding every other default configuration that the `RestClient`
+is initialized with. This section describes some common scenarios that require
+additional configuration for the low-level Java REST Client.
 
 === Timeouts
 
@@ -20,18 +20,9 @@ connect timeout (defaults to 1 second) and the socket timeout (defaults to 30
 seconds). Also we adjust the max retry timeout accordingly (defaults to 30
 seconds too).
 
-[source,java]
+["source","java",subs="attributes,callouts,macros"]
 --------------------------------------------------
-RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200))
-        .setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() {
-            @Override
-            public RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder requestConfigBuilder) {
-                return requestConfigBuilder.setConnectTimeout(5000)
-                        .setSocketTimeout(60000);
-            }
-        })
-        .setMaxRetryTimeoutMillis(60000)
-        .build();
+include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-config-timeouts]
 --------------------------------------------------
 
 === Number of threads
@@ -42,17 +33,9 @@ of locally detected processors (depending on what
 `Runtime.getRuntime().availableProcessors()` returns). The number of threads
 can be modified as follows:
 
-[source,java]
+["source","java",subs="attributes,callouts,macros"]
 --------------------------------------------------
-RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200))
-        .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
-            @Override
-            public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
-                return httpClientBuilder.setDefaultIOReactorConfig(
-                        IOReactorConfig.custom().setIoThreadCount(1).build());
-            }
-        })
-        .build();
+include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-config-threads]
 --------------------------------------------------
 
 === Basic authentication
@@ -65,44 +48,21 @@ https://hc.apache.org/httpcomponents-asyncclient-dev/httpasyncclient/apidocs/org
 modified and then returned. In the following example we set a default
 credentials provider that requires basic authentication.
 
-[source,java]
+["source","java",subs="attributes,callouts,macros"]
 --------------------------------------------------
-final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
-credentialsProvider.setCredentials(AuthScope.ANY,
-        new UsernamePasswordCredentials("user", "password"));
-
-RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200))
-        .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
-            @Override
-            public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
-                return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
-            }
-        })
-        .build();
+include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-config-basic-auth]
 --------------------------------------------------
 
-You can disable Preemptive Authentication, which means that every request will be sent without
+Preemptive Authentication can be disabled, which means that every request will be sent without
 authorization headers to see if it is accepted and, upon receiving a HTTP 401 response, it will
 resend the exact same request with the basic authentication header. If you wish to do this, then
 you can do so by disabling it via the `HttpAsyncClientBuilder`:
 
-[source,java]
+["source","java",subs="attributes,callouts,macros"]
 --------------------------------------------------
-final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
-credentialsProvider.setCredentials(AuthScope.ANY,
-        new UsernamePasswordCredentials("user", "password"));
-
-RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200))
-        .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
-            @Override
-            public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
-                // disable preemptive authentication
-                httpClientBuilder.disableAuthCaching();
-                return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
-            }
-        })
-        .build();
+include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-config-disable-preemptive-auth]
 --------------------------------------------------
+<1> Disable preemptive authentication
 
 === Encrypted communication
 
@@ -114,20 +74,9 @@ https://hc.apache.org/httpcomponents-asyncclient-dev/httpasyncclient/apidocs/org
  `setConnectionManager`, in order of precedence from the least important.
  The following is an example:
 
-[source,java]
+["source","java",subs="attributes,callouts,macros"]
 --------------------------------------------------
-KeyStore keystore = KeyStore.getInstance("jks");
-try (InputStream is = Files.newInputStream(keyStorePath)) {
-    keystore.load(is, keyStorePass.toCharArray());
-}
-RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200))
-        .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
-            @Override
-            public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
-                return httpClientBuilder.setSSLContext(sslcontext);
-            }
-        })
-        .build();
+include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-config-encrypted-communication]
 --------------------------------------------------
 
 === Others

+ 4 - 1
docs/java-rest/low-level/index.asciidoc

@@ -24,10 +24,13 @@ The low-level client's features include:
 
 --
 
+:doc-tests: {docdir}/../../client/rest/src/test/java/org/elasticsearch/client/documentation
 include::usage.asciidoc[]
-
 include::configuration.asciidoc[]
 
+:doc-tests: {docdir}/../../client/sniffer/src/test/java/org/elasticsearch/client/sniff/documentation
 include::sniffer.asciidoc[]
 
 include::../license.asciidoc[]
+
+:doc-tests!:

+ 47 - 52
docs/java-rest/low-level/sniffer.asciidoc

@@ -45,16 +45,14 @@ dependencies {
 
 === Usage
 
-Once a `RestClient` instance has been created, 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
+Once a `RestClient` instance has been created as shown in <<java-rest-low-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#setHosts`.
 
-
-
-[source,java]
+["source","java",subs="attributes,callouts,macros"]
 --------------------------------------------------
-Sniffer sniffer = Sniffer.builder(restClient).build();
+include-tagged::{doc-tests}/SnifferDocumentation.java[sniffer-init]
 --------------------------------------------------
 
 It is important to close the `Sniffer` so that its background thread gets
@@ -62,43 +60,17 @@ 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:
 
-[source,java]
---------------------------------------------------
-sniffer.close();
-restClient.close();
---------------------------------------------------
-
-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
-`ElasticsearchHostsSniffer` object has to be manually created and provided
-as follows:
-
-[source,java]
+["source","java",subs="attributes,callouts,macros"]
 --------------------------------------------------
-HostsSniffer hostsSniffer = new ElasticsearchHostsSniffer(restClient,
-        ElasticsearchHostsSniffer.DEFAULT_SNIFF_REQUEST_TIMEOUT,
-        ElasticsearchHostsSniffer.Scheme.HTTPS);
-Sniffer sniffer = Sniffer.builder(restClient)
-        .setHostsSniffer(hostsSniffer).build();
+include-tagged::{doc-tests}/SnifferDocumentation.java[sniffer-close]
 --------------------------------------------------
 
-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
-querystring 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 responsed until then.
-Also, a custom `HostsSniffer` implementation can be provided for advanced
-use-cases that may require fetching the hosts from external sources.
-
 The `Sniffer` updates the nodes by default every 5 minutes. This interval can
 be customized by providing it (in milliseconds) as follows:
 
-[source,java]
+["source","java",subs="attributes,callouts,macros"]
 --------------------------------------------------
-Sniffer sniffer = Sniffer.builder(restClient)
-        .setSniffIntervalMillis(60000).build();
+include-tagged::{doc-tests}/SnifferDocumentation.java[sniffer-interval]
 --------------------------------------------------
 
 It is also possible to enable sniffing on failure, meaning that after each
@@ -109,26 +81,49 @@ be created at first and provided at `RestClient` creation. Also once the
 `SniffOnFailureListener` instance, which will be notified at each failure
 and use the `Sniffer` to perform the additional sniffing round as described.
 
-[source,java]
+["source","java",subs="attributes,callouts,macros"]
 --------------------------------------------------
-SniffOnFailureListener sniffOnFailureListener = new SniffOnFailureListener();
-RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200))
-        .setFailureListener(sniffOnFailureListener).build();
-Sniffer sniffer = Sniffer.builder(restClient).build();
-sniffOnFailureListener.setSniffer(sniffer);
+include-tagged::{doc-tests}/SnifferDocumentation.java[sniff-on-failure]
 --------------------------------------------------
-
-When using sniffing on failure, not only do the nodes get updated after each
+<1> Set the failure listener to the `RestClient` instance
+<2> When sniffing on failure, not only do the nodes get updated after each
 failure, but an additional sniffing round is also scheduled sooner than usual,
 by default one minute after the failure, assuming that things will go back to
-normal and we want  to detect that as soon as possible. Said interval can be
-customized  at `Sniffer` creation time as follows:
+normal and we want to detect that as soon as possible. Said interval can be
+customized  at `Sniffer` creation time through the `setSniffAfterFailureDelayMillis`
+method. Note that this last configuration parameter has no effect in case sniffing
+on failure is not enabled like explained above.
+<3> Set the `Sniffer` instance to the failure listener
 
-[source,java]
+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
+`ElasticsearchHostsSniffer` instance has to be manually created and provided
+as follows:
+
+["source","java",subs="attributes,callouts,macros"]
 --------------------------------------------------
-Sniffer sniffer = Sniffer.builder(restClient)
-        .setSniffAfterFailureDelayMillis(30000).build();
+include-tagged::{doc-tests}/SnifferDocumentation.java[sniffer-https]
 --------------------------------------------------
 
-Note that this last configuration parameter has no effect in case sniffing
-on failure is not enabled like explained above.
+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
+querystring 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.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/SnifferDocumentation.java[sniff-request-timeout]
+--------------------------------------------------
+
+Also, a custom `HostsSniffer` implementation can be provided for advanced
+use-cases that may require fetching the hosts from external sources rather
+than from Elasticsearch:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/SnifferDocumentation.java[custom-hosts-sniffer]
+--------------------------------------------------
+<1> Fetch the hosts from the external source

+ 159 - 169
docs/java-rest/low-level/usage.asciidoc

@@ -71,11 +71,9 @@ client will communicate with, provided as instances of
 https://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/HttpHost.html[HttpHost]
  as follows:
 
-[source,java]
+["source","java",subs="attributes,callouts,macros"]
 --------------------------------------------------
-RestClient restClient = RestClient.builder(
-        new HttpHost("localhost", 9200, "http"),
-        new HttpHost("localhost", 9201, "http")).build();
+include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-init]
 --------------------------------------------------
 
 The `RestClient` class is thread-safe and ideally has the same lifecycle as
@@ -83,29 +81,52 @@ 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]
+["source","java",subs="attributes,callouts,macros"]
 --------------------------------------------------
-restClient.close();
+include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-close]
 --------------------------------------------------
 
 `RestClientBuilder` also allows to optionally set the following configuration
 parameters while building the `RestClient` instance:
 
-`setDefaultHeaders`:: default headers that need to be sent with each request,
-to prevent having to specify them with each single request
-`setMaxRetryTimeoutMillis`:: the timeout that should be honoured in case
-multiple attempts are made for the same request. The default value is 30
-seconds, same as the default socket timeout. In case the socket timeout is
-customized, the maximum retry timeout should be adjusted accordingly
-`setFailureListener`:: 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
-`setRequestConfigCallback`:: callback that allows to modify the default
-request configuration (e.g. request timeouts, authentication, or anything that
-the https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/config/RequestConfig.Builder.html[`org.apache.http.client.config.RequestConfig.Builder`]
+["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-max-retry-timeout]
+--------------------------------------------------
+<1> Set the timeout that should be honoured in case multiple attempts are made
+for the same request. The default value is 30 seconds, same as the default
+socket timeout. In case the socket timeout is customized, the maximum retry
+timeout should be adjusted accordingly
+
+["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-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-ga/httpclient/apidocs/org/apache/http/client/config/RequestConfig.Builder.html[`org.apache.http.client.config.RequestConfig.Builder`]
  allows to set)
-`setHttpClientConfigCallback`:: callback that allows to modify the http client
- configuration (e.g. encrypted communication over ssl, or anything that the
+
+["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
 http://hc.apache.org/httpcomponents-asyncclient-dev/httpasyncclient/apidocs/org/apache/http/impl/nio/client/HttpAsyncClientBuilder.html[`org.apache.http.impl.nio.client.HttpAsyncClientBuilder`]
  allows to set)
 
@@ -115,101 +136,135 @@ http://hc.apache.org/httpcomponents-asyncclient-dev/httpasyncclient/apidocs/org/
 
 Once the `RestClient` has been created, requests can be sent by calling one of
 the available `performRequest` or `performRequestAsync` method variants.
-The `performRequest` methods are synchronous and they return the `Response`
-directly, meaning that the client will block and wait for a response to be returned.
-The `performRequestAsync` variants, which return `void` and accept an extra
-`ResponseListener` as an argument, are executed asynchronously. The provided
-listener will be notified upon completion or failure.
-
-[source,java]
---------------------------------------------------
-// Synchronous variants
-Response performRequest(String method, String endpoint,
-                        Header... headers)
-    throws IOException;
-
-Response performRequest(String method, String endpoint,
-                        Map<String, String> params, Header... headers)
-    throws IOException;
-
-Response performRequest(String method, String endpoint,
-                        Map<String, String> params,
-                        HttpEntity entity,
-                        Header... headers)
-    throws IOException;
-
-Response performRequest(String method, String endpoint,
-                        Map<String, String> params,
-                        HttpEntity entity,
-                        HttpAsyncResponseConsumerFactory responseConsumerFactory,
-                        Header... headers)
-    throws IOException;
-
-// Asynchronous variants
-void performRequestAsync(String method, String endpoint,
-                         ResponseListener responseListener,
-                         Header... headers);
-
-void performRequestAsync(String method, String endpoint,
-                         Map<String, String> params,
-                         ResponseListener responseListener,
-                         Header... headers);
-
-void performRequestAsync(String method, String endpoint,
-                         Map<String, String> params,
-                         HttpEntity entity,
-                         ResponseListener responseListener,
-                         Header... headers);
-
-void performRequestAsync(String method, String endpoint,
-                         Map<String, String> params,
-                         HttpEntity entity,
-                         HttpAsyncResponseConsumerFactory responseConsumerFactory,
-                         ResponseListener responseListener,
-                         Header... headers);
---------------------------------------------------
-
-[[java-rest-low-usage-requests-arguments]]
-==== Request Arguments
-
-The following are the arguments accepted by the different methods:
-
-`method`:: the http method or verb
-`endpoint`:: the request path, which identifies the Elasticsearch API to
-call (e.g. `/_cluster/health`)
-`params`:: the optional parameters to be sent as querystring parameters
-`entity`:: the optional request body enclosed in an
-`org.apache.http.HttpEntity` object
-`responseConsumerFactory`:: the optional factory that is used to create an
-http://hc.apache.org/httpcomponents-core-ga/httpcore-nio/apidocs/org/apache/http/nio/protocol/HttpAsyncResponseConsumer.html[`org.apache.http.nio.protocol.HttpAsyncResponseConsumer`]
- callback instance per request attempt. Controls how the response body gets
- streamed from a non-blocking HTTP connection on the client side. When not
- provided, the default implementation is used which buffers the whole response
- body in heap memory, up to 100 MB
-`responseListener`:: the listener to be notified upon asynchronous
-request success or failure
-`headers`:: optional request headers
+The `performRequest` methods are synchronous and return the `Response` directly,
+meaning that the client will block and wait for a response to be returned.
+The `performRequestAsync` variants return `void` and accept an extra
+`ResponseListener` as an argument instead, meaning that they are executed
+asynchronously. The provided listener will be notified upon request completion
+or failure.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-verb-endpoint]
+--------------------------------------------------
+<1> Send a request by providing only the verb and the endpoint, minimum set
+of required arguments
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-verb-endpoint-params]
+--------------------------------------------------
+<1> Send a request by providing the verb, the endpoint, and some querystring
+parameter
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-verb-endpoint-params-body]
+--------------------------------------------------
+<1> Send a request by providing the verb, the endpoint, optional querystring
+parameters and the request body enclosed in an `org.apache.http.HttpEntity`
+object
+
+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.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-response-consumer]
+--------------------------------------------------
+<1> Send a request by providing the verb, the endpoint, optional querystring
+parameters, optional request body and the optional factory that is used to
+create an http://hc.apache.org/httpcomponents-core-ga/httpcore-nio/apidocs/org/apache/http/nio/protocol/HttpAsyncResponseConsumer.html[`org.apache.http.nio.protocol.HttpAsyncResponseConsumer`]
+callback instance per request attempt. Controls how the response body gets
+streamed from a non-blocking HTTP connection on the client side. When not
+provided, the default implementation is used which buffers the whole response
+body in heap memory, up to 100 MB.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-verb-endpoint-async]
+--------------------------------------------------
+<1> Define what needs to happen when the request is successfully performed
+<2> Define what needs to happen when the request fails, meaning whenever
+there's a connection error or a response with error status code is returned.
+<3> Send an async request by providing only the verb, the endpoint, and the
+response listener to be notified once the request is completed, minimum set
+of required arguments
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-verb-endpoint-params-async]
+--------------------------------------------------
+<1> Send an async request by providing the verb, the endpoint, some querystring
+parameter and the response listener to be notified once the request is completed
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-verb-endpoint-params-body-async]
+--------------------------------------------------
+<1> Send an async request by providing the verb, the endpoint, optional
+querystring parameters, the request body enclosed in an
+`org.apache.http.HttpEntity` object and the response listener to be
+notified once the request is completed
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-response-consumer-async]
+--------------------------------------------------
+<1> Send an async request by providing the verb, the endpoint, optional
+querystring parameters, optional request body and the optional factory that is
+used to create an http://hc.apache.org/httpcomponents-core-ga/httpcore-nio/apidocs/org/apache/http/nio/protocol/HttpAsyncResponseConsumer.html[`org.apache.http.nio.protocol.HttpAsyncResponseConsumer`]
+callback instance per request attempt. Controls how the response body gets
+streamed from a non-blocking HTTP connection on the client side. When not
+provided, the default implementation is used which buffers the whole response
+body in heap memory, up to 100 MB.
+
+The following is a basic example of how async requests can be sent:
+
+["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
+
+Each of the above listed method supports sending headers along with the
+request through a `Header` varargs argument as in the following examples:
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-headers]
+--------------------------------------------------
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/RestClientDocumentation.java[rest-client-headers-async]
+--------------------------------------------------
 
 [[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 the following information:
-
-`getRequestLine`:: information about the performed request
-`getHost`:: the host that returned the response
-`getStatusLine`:: the response status line
-`getHeaders`:: the response headers, which can also be retrieved by name
-though `getHeader(String)`
-`getEntity`:: the response body enclosed in an
-https://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/HttpEntity.html[`org.apache.http.HttpEntity`]
+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-ga/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 etc.)
+`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
@@ -227,37 +282,6 @@ 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.
 
-
-[[java-rest-low-usage-example]]
-=== Example requests
-
-Here are a couple of examples:
-
-[source,java]
---------------------------------------------------
-Response response = restClient.performRequest("GET", "/",
-        Collections.singletonMap("pretty", "true"));
-System.out.println(EntityUtils.toString(response.getEntity()));
-
-//index a document
-HttpEntity entity = new NStringEntity(
-        "{\n" +
-        "    \"user\" : \"kimchy\",\n" +
-        "    \"post_date\" : \"2009-11-15T14:12:12\",\n" +
-        "    \"message\" : \"trying out Elasticsearch\"\n" +
-        "}", ContentType.APPLICATION_JSON);
-
-Response indexResponse = restClient.performRequest(
-        "PUT",
-        "/twitter/tweet/1",
-        Collections.<String, String>emptyMap(),
-        entity);
---------------------------------------------------
-
-IMPORTANT: The `ContentType` that you specify for the `HttpEntity` is important
-because it will be used to set the `Content-Type` header so that Elasticsearch
-can properly parse the content.
-
 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.
@@ -272,40 +296,6 @@ possible to provide a custom
 http://hc.apache.org/httpcomponents-core-ga/httpcore-nio/apidocs/org/apache/http/nio/protocol/HttpAsyncResponseConsumer.html[`org.apache.http.nio.protocol.HttpAsyncResponseConsumer`]
  that controls how bytes are read and buffered.
 
-The following is a basic example of how async requests can be sent:
-
-[source,java]
---------------------------------------------------
-int numRequests = 10;
-final CountDownLatch latch = new CountDownLatch(numRequests);
-
-for (int i = 0; i < numRequests; i++) {
-    restClient.performRequestAsync(
-        "PUT",
-        "/twitter/tweet/" + i,
-        Collections.<String, String>emptyMap(),
-        //assume that the documents are stored in an entities array
-        entities[i],
-        new ResponseListener() {
-            @Override
-            public void onSuccess(Response response) {
-                System.out.println(response);
-                latch.countDown();
-            }
-
-            @Override
-            public void onFailure(Exception exception) {
-                latch.countDown();
-            }
-        }
-    );
-}
-
-//wait for all requests to be completed
-latch.await();
-
---------------------------------------------------
-
 [[java-rest-low-usage-logging]]
 === Logging