{"action":"created","comment":{"url":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments/65892012","id":65892012,"diff_hunk":"@@ -0,0 +1,476 @@\n+/*\n+ * Licensed to Elasticsearch under one or more contributor\n+ * license agreements. See the NOTICE file distributed with\n+ * this work for additional information regarding copyright\n+ * ownership. Elasticsearch licenses this file to you under\n+ * the Apache License, Version 2.0 (the \"License\"); you may\n+ * not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ *    http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing,\n+ * software distributed under the License is distributed on an\n+ * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n+ * KIND, either express or implied.  See the License for the\n+ * specific language governing permissions and limitations\n+ * under the License.\n+ */\n+package org.elasticsearch.client;\n+\n+import org.apache.commons.logging.Log;\n+import org.apache.commons.logging.LogFactory;\n+import org.apache.http.Consts;\n+import org.apache.http.Header;\n+import org.apache.http.HttpEntity;\n+import org.apache.http.HttpHost;\n+import org.apache.http.HttpRequest;\n+import org.apache.http.client.ClientProtocolException;\n+import org.apache.http.client.config.RequestConfig;\n+import org.apache.http.client.methods.CloseableHttpResponse;\n+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;\n+import org.apache.http.client.methods.HttpHead;\n+import org.apache.http.client.methods.HttpOptions;\n+import org.apache.http.client.methods.HttpPatch;\n+import org.apache.http.client.methods.HttpPost;\n+import org.apache.http.client.methods.HttpPut;\n+import org.apache.http.client.methods.HttpRequestBase;\n+import org.apache.http.client.methods.HttpTrace;\n+import org.apache.http.client.utils.URIBuilder;\n+import org.apache.http.config.Registry;\n+import org.apache.http.conn.socket.ConnectionSocketFactory;\n+import org.apache.http.entity.ContentType;\n+import org.apache.http.impl.client.CloseableHttpClient;\n+import org.apache.http.impl.client.HttpClientBuilder;\n+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;\n+import org.apache.http.util.EntityUtils;\n+\n+import java.io.Closeable;\n+import java.io.IOException;\n+import java.net.URI;\n+import java.net.URISyntaxException;\n+import java.util.ArrayList;\n+import java.util.Collections;\n+import java.util.Comparator;\n+import java.util.HashSet;\n+import java.util.Iterator;\n+import java.util.List;\n+import java.util.Locale;\n+import java.util.Map;\n+import java.util.Objects;\n+import java.util.Set;\n+import java.util.concurrent.ConcurrentHashMap;\n+import java.util.concurrent.ConcurrentMap;\n+import java.util.concurrent.TimeUnit;\n+import java.util.concurrent.atomic.AtomicInteger;\n+\n+/**\n+ * Client that connects to an elasticsearch cluster through http.\n+ * Must be created using {@link Builder}, which allows to set all the different options or just rely on defaults.\n+ * The hosts that are part of the cluster need to be provided at creation time, but can also be replaced later\n+ * by calling {@link #setHosts(HttpHost...)}.\n+ * The method {@link #performRequest(String, String, Map, HttpEntity, Header...)} allows to send a request to the cluster. When\n+ * sending a request, a host gets selected out of the provided ones in a round-robin fashion. Failing hosts are marked dead and\n+ * retried after a certain amount of time (minimum 1 minute, maximum 30 minutes), depending on how many times they previously\n+ * failed (the more failures, the later they will be retried). In case of failures all of the alive nodes (or dead nodes that\n+ * deserve a retry) are retried till one responds or none of them does, in which case an {@link IOException} will be thrown.\n+ *\n+ * Requests can be traced by enabling trace logging for \"tracer\". The trace logger outputs requests and responses in curl format.\n+ */\n+public final class RestClient implements Closeable {\n+\n+    private static final Log logger = LogFactory.getLog(RestClient.class);\n+    public static ContentType JSON_CONTENT_TYPE = ContentType.create(\"application/json\", Consts.UTF_8);\n+\n+    private final CloseableHttpClient client;\n+    //we don't rely on default headers supported by HttpClient as those cannot be replaced, plus it would get hairy\n+    //when we create the HttpClient instance on our own as there would be two different ways to set the default headers.\n+    private final Header[] defaultHeaders;\n+    private final long maxRetryTimeout;\n+    private final AtomicInteger lastHostIndex = new AtomicInteger(0);\n+    private volatile Set<HttpHost> hosts;\n+    private final ConcurrentMap<HttpHost, DeadHostState> blacklist = new ConcurrentHashMap<>();\n+    private volatile FailureListener failureListener = new FailureListener();\n+\n+    private RestClient(CloseableHttpClient client, long maxRetryTimeout, Header[] defaultHeaders, HttpHost[] hosts) {\n+        this.client = client;\n+        this.maxRetryTimeout = maxRetryTimeout;\n+        this.defaultHeaders = defaultHeaders;\n+        setHosts(hosts);\n+    }\n+\n+    /**\n+     * Replaces the hosts that the client communicates with.\n+     * @see HttpHost\n+     */\n+    public synchronized void setHosts(HttpHost... hosts) {\n+        if (hosts == null || hosts.length == 0) {\n+            throw new IllegalArgumentException(\"hosts must not be null nor empty\");\n+        }\n+        Set<HttpHost> httpHosts = new HashSet<>();\n+        for (HttpHost host : hosts) {\n+            Objects.requireNonNull(host, \"host cannot be null\");\n+            httpHosts.add(host);\n+        }\n+        this.hosts = Collections.unmodifiableSet(httpHosts);\n+        this.blacklist.clear();\n+    }\n+\n+    /**\n+     * Sends a request to the elasticsearch cluster that the current client points to.\n+     * Selects a host out of the provided ones in a round-robin fashion. Failing hosts are marked dead and retried after a certain\n+     * amount of time (minimum 1 minute, maximum 30 minutes), depending on how many times they previously failed (the more failures,\n+     * the later they will be retried). In case of failures all of the alive nodes (or dead nodes that deserve a retry) are retried\n+     * till one responds or none of them does, in which case an {@link IOException} will be thrown.\n+     *\n+     * @param method the http method\n+     * @param endpoint the path of the request (without host and port)","path":"client/src/main/java/org/elasticsearch/client/RestClient.java","position":127,"original_position":127,"commit_id":"2cf04c08772ab7ca3ea5fd65d7c5878e3852d9e8","original_commit_id":"05e26a46d736ff5caf6e6d6394e674828283e3d7","user":{"login":"javanna","id":832460,"avatar_url":"https://avatars.githubusercontent.com/u/832460?v=3","gravatar_id":"","url":"https://api.github.com/users/javanna","html_url":"https://github.com/javanna","followers_url":"https://api.github.com/users/javanna/followers","following_url":"https://api.github.com/users/javanna/following{/other_user}","gists_url":"https://api.github.com/users/javanna/gists{/gist_id}","starred_url":"https://api.github.com/users/javanna/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/javanna/subscriptions","organizations_url":"https://api.github.com/users/javanna/orgs","repos_url":"https://api.github.com/users/javanna/repos","events_url":"https://api.github.com/users/javanna/events{/privacy}","received_events_url":"https://api.github.com/users/javanna/received_events","type":"User","site_admin":false},"body":"yes this is what the low level client is about, no builders for requests, only raw performRequest method. We will later add api-specific clases to do things like `client.index(index, type, id, body)`. Still not sure what the body will look like, might still be quite raw to leave room for external serialization libraries etc.","created_at":"2016-06-06T13:48:02Z","updated_at":"2016-06-06T13:48:02Z","html_url":"https://github.com/elastic/elasticsearch/pull/18735#discussion_r65892012","pull_request_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/18735","_links":{"self":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments/65892012"},"html":{"href":"https://github.com/elastic/elasticsearch/pull/18735#discussion_r65892012"},"pull_request":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/18735"}}},"pull_request":{"url":"https://api.github.com/repos/elastic/elasticsearch/pulls/18735","id":72583387,"html_url":"https://github.com/elastic/elasticsearch/pull/18735","diff_url":"https://github.com/elastic/elasticsearch/pull/18735.diff","patch_url":"https://github.com/elastic/elasticsearch/pull/18735.patch","issue_url":"https://api.github.com/repos/elastic/elasticsearch/issues/18735","number":18735,"state":"open","locked":false,"title":"Low level Rest Client","user":{"login":"javanna","id":832460,"avatar_url":"https://avatars.githubusercontent.com/u/832460?v=3","gravatar_id":"","url":"https://api.github.com/users/javanna","html_url":"https://github.com/javanna","followers_url":"https://api.github.com/users/javanna/followers","following_url":"https://api.github.com/users/javanna/following{/other_user}","gists_url":"https://api.github.com/users/javanna/gists{/gist_id}","starred_url":"https://api.github.com/users/javanna/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/javanna/subscriptions","organizations_url":"https://api.github.com/users/javanna/orgs","repos_url":"https://api.github.com/users/javanna/repos","events_url":"https://api.github.com/users/javanna/events{/privacy}","received_events_url":"https://api.github.com/users/javanna/received_events","type":"User","site_admin":false},"body":"The low level RestClient can be created by simply providing the hosts that it should point to: `RestClient.builder().setHosts(new HttpHost(\"localhost\", 9200).build()`. \r\nIt also allows to provide a `CloseableHttpClient` instance to be used, otherwise one with default settings is going to be created. \r\nIt exposes a `performRequest` method, that accepts all the needed arguments to send an http request: method, endpoint, parameters, body, and headers.\r\nIt supports trace logging like all other language clients, to log each request and response in curl format.\r\n\r\n`client` is a new gradle submodule that depends on apache http client and only a few other transitive deps. \r\n`client-sniffer` is an additional gradle submodule that depends on `client` and jackson, as it's able to parse the nodes info api response and inject hosts into an existing RestClient instance. Sniffer comes also with a listener that gets notified on failure and can optionally sniff hosts on failure.\r\n\r\nBoth new modules are java 7 compatible and get compiled with source 1.7 & target 1.7.\r\n\r\nThis PR also makes our Rest tests use the new RestClient, and it also replaces any usage of apache http client in tests with the new low level RestClient.\r\n\r\nWhat's left, which can probably be worked on after this PR gets in:\r\n- write some more tests, especially around custom http clients, concurrency and sniffing task.\r\n- javadocs should be ok but we need some docs page on how to use it and configuration for common scenarios like ssl, proxy, basic auth etc. (although we can refer to apache http client documentation)\r\n- make naming conventions check work (#18730)\r\n- forbidden-apis for test classes is currently disabled, find a way to make excludes work so that we can re-enable it\r\n- check if anything is missing to publish jar once we release\r\n- client-sniffer requires license and SHA for client dependency, not sure that's correct\r\n- add async variant of performRequest method\r\n\r\nCloses #7743","created_at":"2016-06-03T23:29:37Z","updated_at":"2016-06-06T13:48:02Z","closed_at":null,"merged_at":null,"merge_commit_sha":"099b81ae310f63301d102d4340a4c3f552e0bcc9","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/18735/commits","review_comments_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/18735/comments","review_comment_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments{/number}","comments_url":"https://api.github.com/repos/elastic/elasticsearch/issues/18735/comments","statuses_url":"https://api.github.com/repos/elastic/elasticsearch/statuses/2cf04c08772ab7ca3ea5fd65d7c5878e3852d9e8","head":{"label":"javanna:feature/http_client","ref":"feature/http_client","sha":"2cf04c08772ab7ca3ea5fd65d7c5878e3852d9e8","user":{"login":"javanna","id":832460,"avatar_url":"https://avatars.githubusercontent.com/u/832460?v=3","gravatar_id":"","url":"https://api.github.com/users/javanna","html_url":"https://github.com/javanna","followers_url":"https://api.github.com/users/javanna/followers","following_url":"https://api.github.com/users/javanna/following{/other_user}","gists_url":"https://api.github.com/users/javanna/gists{/gist_id}","starred_url":"https://api.github.com/users/javanna/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/javanna/subscriptions","organizations_url":"https://api.github.com/users/javanna/orgs","repos_url":"https://api.github.com/users/javanna/repos","events_url":"https://api.github.com/users/javanna/events{/privacy}","received_events_url":"https://api.github.com/users/javanna/received_events","type":"User","site_admin":false},"repo":{"id":6652220,"name":"elasticsearch","full_name":"javanna/elasticsearch","owner":{"login":"javanna","id":832460,"avatar_url":"https://avatars.githubusercontent.com/u/832460?v=3","gravatar_id":"","url":"https://api.github.com/users/javanna","html_url":"https://github.com/javanna","followers_url":"https://api.github.com/users/javanna/followers","following_url":"https://api.github.com/users/javanna/following{/other_user}","gists_url":"https://api.github.com/users/javanna/gists{/gist_id}","starred_url":"https://api.github.com/users/javanna/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/javanna/subscriptions","organizations_url":"https://api.github.com/users/javanna/orgs","repos_url":"https://api.github.com/users/javanna/repos","events_url":"https://api.github.com/users/javanna/events{/privacy}","received_events_url":"https://api.github.com/users/javanna/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/javanna/elasticsearch","description":"Open Source, Distributed, RESTful Search Engine","fork":true,"url":"https://api.github.com/repos/javanna/elasticsearch","forks_url":"https://api.github.com/repos/javanna/elasticsearch/forks","keys_url":"https://api.github.com/repos/javanna/elasticsearch/keys{/key_id}","collaborators_url":"https://api.github.com/repos/javanna/elasticsearch/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/javanna/elasticsearch/teams","hooks_url":"https://api.github.com/repos/javanna/elasticsearch/hooks","issue_events_url":"https://api.github.com/repos/javanna/elasticsearch/issues/events{/number}","events_url":"https://api.github.com/repos/javanna/elasticsearch/events","assignees_url":"https://api.github.com/repos/javanna/elasticsearch/assignees{/user}","branches_url":"https://api.github.com/repos/javanna/elasticsearch/branches{/branch}","tags_url":"https://api.github.com/repos/javanna/elasticsearch/tags","blobs_url":"https://api.github.com/repos/javanna/elasticsearch/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/javanna/elasticsearch/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/javanna/elasticsearch/git/refs{/sha}","trees_url":"https://api.github.com/repos/javanna/elasticsearch/git/trees{/sha}","statuses_url":"https://api.github.com/repos/javanna/elasticsearch/statuses/{sha}","languages_url":"https://api.github.com/repos/javanna/elasticsearch/languages","stargazers_url":"https://api.github.com/repos/javanna/elasticsearch/stargazers","contributors_url":"https://api.github.com/repos/javanna/elasticsearch/contributors","subscribers_url":"https://api.github.com/repos/javanna/elasticsearch/subscribers","subscription_url":"https://api.github.com/repos/javanna/elasticsearch/subscription","commits_url":"https://api.github.com/repos/javanna/elasticsearch/commits{/sha}","git_commits_url":"https://api.github.com/repos/javanna/elasticsearch/git/commits{/sha}","comments_url":"https://api.github.com/repos/javanna/elasticsearch/comments{/number}","issue_comment_url":"https://api.github.com/repos/javanna/elasticsearch/issues/comments{/number}","contents_url":"https://api.github.com/repos/javanna/elasticsearch/contents/{+path}","compare_url":"https://api.github.com/repos/javanna/elasticsearch/compare/{base}...{head}","merges_url":"https://api.github.com/repos/javanna/elasticsearch/merges","archive_url":"https://api.github.com/repos/javanna/elasticsearch/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/javanna/elasticsearch/downloads","issues_url":"https://api.github.com/repos/javanna/elasticsearch/issues{/number}","pulls_url":"https://api.github.com/repos/javanna/elasticsearch/pulls{/number}","milestones_url":"https://api.github.com/repos/javanna/elasticsearch/milestones{/number}","notifications_url":"https://api.github.com/repos/javanna/elasticsearch/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/javanna/elasticsearch/labels{/name}","releases_url":"https://api.github.com/repos/javanna/elasticsearch/releases{/id}","deployments_url":"https://api.github.com/repos/javanna/elasticsearch/deployments","created_at":"2012-11-12T11:11:09Z","updated_at":"2015-04-30T08:59:29Z","pushed_at":"2016-06-06T13:44:29Z","git_url":"git://github.com/javanna/elasticsearch.git","ssh_url":"git@github.com:javanna/elasticsearch.git","clone_url":"https://github.com/javanna/elasticsearch.git","svn_url":"https://github.com/javanna/elasticsearch","homepage":"http://elasticsearch.org","size":216728,"stargazers_count":1,"watchers_count":1,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"elastic:master","ref":"master","sha":"619b8831f98ef030df7e125cb426939c05062a6c","user":{"login":"elastic","id":6764390,"avatar_url":"https://avatars.githubusercontent.com/u/6764390?v=3","gravatar_id":"","url":"https://api.github.com/users/elastic","html_url":"https://github.com/elastic","followers_url":"https://api.github.com/users/elastic/followers","following_url":"https://api.github.com/users/elastic/following{/other_user}","gists_url":"https://api.github.com/users/elastic/gists{/gist_id}","starred_url":"https://api.github.com/users/elastic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elastic/subscriptions","organizations_url":"https://api.github.com/users/elastic/orgs","repos_url":"https://api.github.com/users/elastic/repos","events_url":"https://api.github.com/users/elastic/events{/privacy}","received_events_url":"https://api.github.com/users/elastic/received_events","type":"Organization","site_admin":false},"repo":{"id":507775,"name":"elasticsearch","full_name":"elastic/elasticsearch","owner":{"login":"elastic","id":6764390,"avatar_url":"https://avatars.githubusercontent.com/u/6764390?v=3","gravatar_id":"","url":"https://api.github.com/users/elastic","html_url":"https://github.com/elastic","followers_url":"https://api.github.com/users/elastic/followers","following_url":"https://api.github.com/users/elastic/following{/other_user}","gists_url":"https://api.github.com/users/elastic/gists{/gist_id}","starred_url":"https://api.github.com/users/elastic/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/elastic/subscriptions","organizations_url":"https://api.github.com/users/elastic/orgs","repos_url":"https://api.github.com/users/elastic/repos","events_url":"https://api.github.com/users/elastic/events{/privacy}","received_events_url":"https://api.github.com/users/elastic/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/elastic/elasticsearch","description":"Open Source, Distributed, RESTful Search Engine","fork":false,"url":"https://api.github.com/repos/elastic/elasticsearch","forks_url":"https://api.github.com/repos/elastic/elasticsearch/forks","keys_url":"https://api.github.com/repos/elastic/elasticsearch/keys{/key_id}","collaborators_url":"https://api.github.com/repos/elastic/elasticsearch/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/elastic/elasticsearch/teams","hooks_url":"https://api.github.com/repos/elastic/elasticsearch/hooks","issue_events_url":"https://api.github.com/repos/elastic/elasticsearch/issues/events{/number}","events_url":"https://api.github.com/repos/elastic/elasticsearch/events","assignees_url":"https://api.github.com/repos/elastic/elasticsearch/assignees{/user}","branches_url":"https://api.github.com/repos/elastic/elasticsearch/branches{/branch}","tags_url":"https://api.github.com/repos/elastic/elasticsearch/tags","blobs_url":"https://api.github.com/repos/elastic/elasticsearch/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/elastic/elasticsearch/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/elastic/elasticsearch/git/refs{/sha}","trees_url":"https://api.github.com/repos/elastic/elasticsearch/git/trees{/sha}","statuses_url":"https://api.github.com/repos/elastic/elasticsearch/statuses/{sha}","languages_url":"https://api.github.com/repos/elastic/elasticsearch/languages","stargazers_url":"https://api.github.com/repos/elastic/elasticsearch/stargazers","contributors_url":"https://api.github.com/repos/elastic/elasticsearch/contributors","subscribers_url":"https://api.github.com/repos/elastic/elasticsearch/subscribers","subscription_url":"https://api.github.com/repos/elastic/elasticsearch/subscription","commits_url":"https://api.github.com/repos/elastic/elasticsearch/commits{/sha}","git_commits_url":"https://api.github.com/repos/elastic/elasticsearch/git/commits{/sha}","comments_url":"https://api.github.com/repos/elastic/elasticsearch/comments{/number}","issue_comment_url":"https://api.github.com/repos/elastic/elasticsearch/issues/comments{/number}","contents_url":"https://api.github.com/repos/elastic/elasticsearch/contents/{+path}","compare_url":"https://api.github.com/repos/elastic/elasticsearch/compare/{base}...{head}","merges_url":"https://api.github.com/repos/elastic/elasticsearch/merges","archive_url":"https://api.github.com/repos/elastic/elasticsearch/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/elastic/elasticsearch/downloads","issues_url":"https://api.github.com/repos/elastic/elasticsearch/issues{/number}","pulls_url":"https://api.github.com/repos/elastic/elasticsearch/pulls{/number}","milestones_url":"https://api.github.com/repos/elastic/elasticsearch/milestones{/number}","notifications_url":"https://api.github.com/repos/elastic/elasticsearch/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/elastic/elasticsearch/labels{/name}","releases_url":"https://api.github.com/repos/elastic/elasticsearch/releases{/id}","deployments_url":"https://api.github.com/repos/elastic/elasticsearch/deployments","created_at":"2010-02-08T13:20:56Z","updated_at":"2016-06-06T12:17:15Z","pushed_at":"2016-06-06T13:46:38Z","git_url":"git://github.com/elastic/elasticsearch.git","ssh_url":"git@github.com:elastic/elasticsearch.git","clone_url":"https://github.com/elastic/elasticsearch.git","svn_url":"https://github.com/elastic/elasticsearch","homepage":"https://www.elastic.co/products/elasticsearch","size":322062,"stargazers_count":16828,"watchers_count":16828,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":5685,"mirror_url":null,"open_issues_count":1072,"forks":5685,"open_issues":1072,"watchers":16828,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/18735"},"html":{"href":"https://github.com/elastic/elasticsearch/pull/18735"},"issue":{"href":"https://api.github.com/repos/elastic/elasticsearch/issues/18735"},"comments":{"href":"https://api.github.com/repos/elastic/elasticsearch/issues/18735/comments"},"review_comments":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/18735/comments"},"review_comment":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/18735/commits"},"statuses":{"href":"https://api.github.com/repos/elastic/elasticsearch/statuses/2cf04c08772ab7ca3ea5fd65d7c5878e3852d9e8"}}}}
{"actor":{"display_login":"javanna"}}