{"action":"created","comment":{"url":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments/231919389","pull_request_review_id":172996045,"id":231919389,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzMTkxOTM4OQ==","diff_hunk":"@@ -0,0 +1,129 @@\n+/*\n+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n+ * or more contributor license agreements. Licensed under the Elastic License;\n+ * you may not use this file except in compliance with the Elastic License.\n+ */\n+package org.elasticsearch.xpack.ml.datafeed;\n+\n+import org.elasticsearch.action.ActionListener;\n+import org.elasticsearch.client.Client;\n+import org.elasticsearch.cluster.ClusterState;\n+import org.elasticsearch.common.xcontent.NamedXContentRegistry;\n+import org.elasticsearch.xpack.core.ml.MlMetadata;\n+import org.elasticsearch.xpack.core.ml.datafeed.DatafeedConfig;\n+import org.elasticsearch.xpack.core.ml.utils.ExceptionsHelper;\n+import org.elasticsearch.xpack.ml.datafeed.persistence.DatafeedConfigProvider;\n+import org.elasticsearch.xpack.ml.job.persistence.ExpandedIdsMatcher;\n+\n+import java.util.ArrayList;\n+import java.util.HashMap;\n+import java.util.List;\n+import java.util.Map;\n+import java.util.Set;\n+import java.util.SortedSet;\n+import java.util.stream.Collectors;\n+\n+/**\n+ * This class abstracts away reading datafeed configuration from either\n+ * the cluster state or index documents.\n+ */\n+public class DatafeedConfigReader {\n+\n+    private final DatafeedConfigProvider datafeedConfigProvider;\n+\n+    public DatafeedConfigReader(Client client, NamedXContentRegistry xContentRegistry) {\n+        this.datafeedConfigProvider = new DatafeedConfigProvider(client, xContentRegistry);\n+    }\n+\n+    public DatafeedConfigReader(DatafeedConfigProvider datafeedConfigProvider) {\n+        this.datafeedConfigProvider = datafeedConfigProvider;\n+    }\n+\n+    /**\n+     * Merges the results of {@link MlMetadata#expandDatafeedIds}\n+     * and {@link DatafeedConfigProvider#expandDatafeedIds(String, boolean, ActionListener)}\n+     */\n+    public void expandDatafeedIds(String expression, boolean allowNoDatafeeds, ClusterState clusterState,\n+                                  ActionListener<SortedSet<String>> listener) {\n+\n+        Set<String> clusterStateDatafeedIds = MlMetadata.getMlMetadata(clusterState).expandDatafeedIds(expression);\n+        ExpandedIdsMatcher requiredMatches = new ExpandedIdsMatcher(expression, allowNoDatafeeds);\n+        requiredMatches.filterMatchedIds(clusterStateDatafeedIds);\n+\n+        datafeedConfigProvider.expandDatafeedIdsWithoutMissingCheck(expression, ActionListener.wrap(\n+                expandedDatafeedIds -> {\n+                    // Check for duplicate Ids\n+                    expandedDatafeedIds.forEach(id -> {\n+                        if (clusterStateDatafeedIds.contains(id)) {\n+                            listener.onFailure(new IllegalStateException(\"Datafeed [\" + id + \"] configuration \" +\n+                                    \"exists in both clusterstate and index\"));\n+                            return;\n+                        }\n+                    });\n+\n+                    requiredMatches.filterMatchedIds(expandedDatafeedIds);\n+\n+                    if (requiredMatches.hasUnmatchedIds()) {\n+                        listener.onFailure(ExceptionsHelper.missingDatafeedException(requiredMatches.unmatchedIdsString()));\n+                    } else {\n+                        expandedDatafeedIds.addAll(clusterStateDatafeedIds);\n+                        listener.onResponse(expandedDatafeedIds);\n+                    }\n+                },\n+               listener::onFailure\n+        ));\n+    }\n+\n+    /**\n+     * Merges the results of {@link MlMetadata#expandDatafeedIds}\n+     * and {@link DatafeedConfigProvider#expandDatafeedConfigs(String, boolean, ActionListener)}\n+     */\n+    public void expandDatafeedConfigs(String expression, boolean allowNoDatafeeds, ClusterState clusterState,\n+                                      ActionListener<List<DatafeedConfig>> listener) {\n+\n+        Map<String, DatafeedConfig> clusterStateConfigs = expandClusterStateDatafeeds(expression, clusterState);\n+\n+        ExpandedIdsMatcher requiredMatches = new ExpandedIdsMatcher(expression, allowNoDatafeeds);\n+        requiredMatches.filterMatchedIds(clusterStateConfigs.keySet());\n+\n+        datafeedConfigProvider.expandDatafeedConfigsWithoutMissingCheck(expression, ActionListener.wrap(\n+                datafeedBuilders -> {\n+                    // Check for duplicate Ids\n+                    datafeedBuilders.forEach(datafeedBuilder -> {\n+                        if (clusterStateConfigs.containsKey(datafeedBuilder.getId())) {\n+                            listener.onFailure(new IllegalStateException(\"Datafeed [\" + datafeedBuilder.getId() + \"] configuration \" +\n+                                    \"exists in both clusterstate and index\"));\n+                            return;\n+                        }\n+                    });\n+\n+                    List<DatafeedConfig> datafeedConfigs = new ArrayList<>();\n+                    for (DatafeedConfig.Builder builder : datafeedBuilders) {\n+                        datafeedConfigs.add(builder.build());\n+                    }\n+\n+                    requiredMatches.filterMatchedIds(datafeedConfigs.stream().map(DatafeedConfig::getId).collect(Collectors.toList()));\n+\n+                    if (requiredMatches.hasUnmatchedIds()) {\n+                        listener.onFailure(ExceptionsHelper.missingDatafeedException(requiredMatches.unmatchedIdsString()));\n+                    } else {\n+                        datafeedConfigs.addAll(clusterStateConfigs.values());\n+                        listener.onResponse(datafeedConfigs);\n+                    }\n+                },\n+                listener::onFailure\n+        ));\n+    }\n+\n+    private Map<String, DatafeedConfig> expandClusterStateDatafeeds(String datafeedExpression, ClusterState clusterState) {\n+\n+        Map<String, DatafeedConfig> configById = new HashMap<>();\n+        MlMetadata mlMetadata = MlMetadata.getMlMetadata(clusterState);\n+        Set<String> expandedDatafeedIds = mlMetadata.expandDatafeedIds(datafeedExpression);\n+\n+        for (String expandedDatafeedId : expandedDatafeedIds) {\n+            configById.put(expandedDatafeedId, mlMetadata.getDatafeed(expandedDatafeedId));\n+        }","path":"x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/datafeed/DatafeedConfigReader.java","position":null,"original_position":126,"commit_id":"aad7e88848cae14de2913a20a2a4f11e753f37e8","original_commit_id":"f6e96fab94f6e0e6653e6926dede39117511ad67","user":{"login":"davidkyle","id":2353640,"node_id":"MDQ6VXNlcjIzNTM2NDA=","avatar_url":"https://avatars1.githubusercontent.com/u/2353640?v=4","gravatar_id":"","url":"https://api.github.com/users/davidkyle","html_url":"https://github.com/davidkyle","followers_url":"https://api.github.com/users/davidkyle/followers","following_url":"https://api.github.com/users/davidkyle/following{/other_user}","gists_url":"https://api.github.com/users/davidkyle/gists{/gist_id}","starred_url":"https://api.github.com/users/davidkyle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davidkyle/subscriptions","organizations_url":"https://api.github.com/users/davidkyle/orgs","repos_url":"https://api.github.com/users/davidkyle/repos","events_url":"https://api.github.com/users/davidkyle/events{/privacy}","received_events_url":"https://api.github.com/users/davidkyle/received_events","type":"User","site_admin":false},"body":"👍 ","created_at":"2018-11-08T14:53:33Z","updated_at":"2018-11-08T14:53:33Z","html_url":"https://github.com/elastic/elasticsearch/pull/35344#discussion_r231919389","pull_request_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/35344","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments/231919389"},"html":{"href":"https://github.com/elastic/elasticsearch/pull/35344#discussion_r231919389"},"pull_request":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/35344"}},"in_reply_to_id":231896424},"pull_request":{"url":"https://api.github.com/repos/elastic/elasticsearch/pulls/35344","id":229099056,"node_id":"MDExOlB1bGxSZXF1ZXN0MjI5MDk5MDU2","html_url":"https://github.com/elastic/elasticsearch/pull/35344","diff_url":"https://github.com/elastic/elasticsearch/pull/35344.diff","patch_url":"https://github.com/elastic/elasticsearch/pull/35344.patch","issue_url":"https://api.github.com/repos/elastic/elasticsearch/issues/35344","number":35344,"state":"open","locked":false,"title":"[ML] Job In Index: Enable GET APIS in mixed state","user":{"login":"davidkyle","id":2353640,"node_id":"MDQ6VXNlcjIzNTM2NDA=","avatar_url":"https://avatars1.githubusercontent.com/u/2353640?v=4","gravatar_id":"","url":"https://api.github.com/users/davidkyle","html_url":"https://github.com/davidkyle","followers_url":"https://api.github.com/users/davidkyle/followers","following_url":"https://api.github.com/users/davidkyle/following{/other_user}","gists_url":"https://api.github.com/users/davidkyle/gists{/gist_id}","starred_url":"https://api.github.com/users/davidkyle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davidkyle/subscriptions","organizations_url":"https://api.github.com/users/davidkyle/orgs","repos_url":"https://api.github.com/users/davidkyle/repos","events_url":"https://api.github.com/users/davidkyle/events{/privacy}","received_events_url":"https://api.github.com/users/davidkyle/received_events","type":"User","site_admin":false},"body":"Jobs left open during an upgrade to 6.6 will not be migrated so this version must support running jobs that are stored in either the cluster state or index documents. New jobs will be stored as documents but old jobs will continue to run from the clusterstate. To achieve this the job and datafeed operations should look in both the clusterstate and the index for the configuration, this is the first change towards that goal and covers reading the configurations. \r\n\r\n- JobManager getJob/expandJob checks both cluster state and index\r\n- Added `DatafeedConfigReader` as a wrapper around DatafeedConfigProvider but checks both cluster state and index for configuration\r\n\r\nAll methods to get the configs go through these 2 classes. \r\n\r\nThis meant I had to change `NameResolver` to not throw on missing jobs as I now collect the clusterstate and index jobs and use `ExpandedIdsMatcher` to check the required job ids, datafeed ids and job groups are present. \r\n\r\nRolling upgrade tests to follow but this is already a large PR\r\n\r\n","created_at":"2018-11-07T16:58:01Z","updated_at":"2018-11-08T14:53:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"547999dc74df8ef95e5ce8ffca4e1853786ce4bd","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":912833043,"node_id":"MDU6TGFiZWw5MTI4MzMwNDM=","url":"https://api.github.com/repos/elastic/elasticsearch/labels/:ml","name":":ml","color":"0e8a16","default":false},{"id":23172,"node_id":"MDU6TGFiZWwyMzE3Mg==","url":"https://api.github.com/repos/elastic/elasticsearch/labels/%3Efeature","name":">feature","color":"006b75","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/35344/commits","review_comments_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/35344/comments","review_comment_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments{/number}","comments_url":"https://api.github.com/repos/elastic/elasticsearch/issues/35344/comments","statuses_url":"https://api.github.com/repos/elastic/elasticsearch/statuses/aad7e88848cae14de2913a20a2a4f11e753f37e8","head":{"label":"davidkyle:enable-apis-in-mixed-state","ref":"enable-apis-in-mixed-state","sha":"aad7e88848cae14de2913a20a2a4f11e753f37e8","user":{"login":"davidkyle","id":2353640,"node_id":"MDQ6VXNlcjIzNTM2NDA=","avatar_url":"https://avatars1.githubusercontent.com/u/2353640?v=4","gravatar_id":"","url":"https://api.github.com/users/davidkyle","html_url":"https://github.com/davidkyle","followers_url":"https://api.github.com/users/davidkyle/followers","following_url":"https://api.github.com/users/davidkyle/following{/other_user}","gists_url":"https://api.github.com/users/davidkyle/gists{/gist_id}","starred_url":"https://api.github.com/users/davidkyle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davidkyle/subscriptions","organizations_url":"https://api.github.com/users/davidkyle/orgs","repos_url":"https://api.github.com/users/davidkyle/repos","events_url":"https://api.github.com/users/davidkyle/events{/privacy}","received_events_url":"https://api.github.com/users/davidkyle/received_events","type":"User","site_admin":false},"repo":{"id":132878508,"node_id":"MDEwOlJlcG9zaXRvcnkxMzI4Nzg1MDg=","name":"elasticsearch","full_name":"davidkyle/elasticsearch","private":false,"owner":{"login":"davidkyle","id":2353640,"node_id":"MDQ6VXNlcjIzNTM2NDA=","avatar_url":"https://avatars1.githubusercontent.com/u/2353640?v=4","gravatar_id":"","url":"https://api.github.com/users/davidkyle","html_url":"https://github.com/davidkyle","followers_url":"https://api.github.com/users/davidkyle/followers","following_url":"https://api.github.com/users/davidkyle/following{/other_user}","gists_url":"https://api.github.com/users/davidkyle/gists{/gist_id}","starred_url":"https://api.github.com/users/davidkyle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davidkyle/subscriptions","organizations_url":"https://api.github.com/users/davidkyle/orgs","repos_url":"https://api.github.com/users/davidkyle/repos","events_url":"https://api.github.com/users/davidkyle/events{/privacy}","received_events_url":"https://api.github.com/users/davidkyle/received_events","type":"User","site_admin":false},"html_url":"https://github.com/davidkyle/elasticsearch","description":"Open Source, Distributed, RESTful Search Engine","fork":true,"url":"https://api.github.com/repos/davidkyle/elasticsearch","forks_url":"https://api.github.com/repos/davidkyle/elasticsearch/forks","keys_url":"https://api.github.com/repos/davidkyle/elasticsearch/keys{/key_id}","collaborators_url":"https://api.github.com/repos/davidkyle/elasticsearch/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/davidkyle/elasticsearch/teams","hooks_url":"https://api.github.com/repos/davidkyle/elasticsearch/hooks","issue_events_url":"https://api.github.com/repos/davidkyle/elasticsearch/issues/events{/number}","events_url":"https://api.github.com/repos/davidkyle/elasticsearch/events","assignees_url":"https://api.github.com/repos/davidkyle/elasticsearch/assignees{/user}","branches_url":"https://api.github.com/repos/davidkyle/elasticsearch/branches{/branch}","tags_url":"https://api.github.com/repos/davidkyle/elasticsearch/tags","blobs_url":"https://api.github.com/repos/davidkyle/elasticsearch/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/davidkyle/elasticsearch/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/davidkyle/elasticsearch/git/refs{/sha}","trees_url":"https://api.github.com/repos/davidkyle/elasticsearch/git/trees{/sha}","statuses_url":"https://api.github.com/repos/davidkyle/elasticsearch/statuses/{sha}","languages_url":"https://api.github.com/repos/davidkyle/elasticsearch/languages","stargazers_url":"https://api.github.com/repos/davidkyle/elasticsearch/stargazers","contributors_url":"https://api.github.com/repos/davidkyle/elasticsearch/contributors","subscribers_url":"https://api.github.com/repos/davidkyle/elasticsearch/subscribers","subscription_url":"https://api.github.com/repos/davidkyle/elasticsearch/subscription","commits_url":"https://api.github.com/repos/davidkyle/elasticsearch/commits{/sha}","git_commits_url":"https://api.github.com/repos/davidkyle/elasticsearch/git/commits{/sha}","comments_url":"https://api.github.com/repos/davidkyle/elasticsearch/comments{/number}","issue_comment_url":"https://api.github.com/repos/davidkyle/elasticsearch/issues/comments{/number}","contents_url":"https://api.github.com/repos/davidkyle/elasticsearch/contents/{+path}","compare_url":"https://api.github.com/repos/davidkyle/elasticsearch/compare/{base}...{head}","merges_url":"https://api.github.com/repos/davidkyle/elasticsearch/merges","archive_url":"https://api.github.com/repos/davidkyle/elasticsearch/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/davidkyle/elasticsearch/downloads","issues_url":"https://api.github.com/repos/davidkyle/elasticsearch/issues{/number}","pulls_url":"https://api.github.com/repos/davidkyle/elasticsearch/pulls{/number}","milestones_url":"https://api.github.com/repos/davidkyle/elasticsearch/milestones{/number}","notifications_url":"https://api.github.com/repos/davidkyle/elasticsearch/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/davidkyle/elasticsearch/labels{/name}","releases_url":"https://api.github.com/repos/davidkyle/elasticsearch/releases{/id}","deployments_url":"https://api.github.com/repos/davidkyle/elasticsearch/deployments","created_at":"2018-05-10T09:27:06Z","updated_at":"2018-05-10T09:27:50Z","pushed_at":"2018-11-08T14:53:18Z","git_url":"git://github.com/davidkyle/elasticsearch.git","ssh_url":"git@github.com:davidkyle/elasticsearch.git","clone_url":"https://github.com/davidkyle/elasticsearch.git","svn_url":"https://github.com/davidkyle/elasticsearch","homepage":"https://www.elastic.co/products/elasticsearch","size":520076,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"elastic:feature-jindex-6x","ref":"feature-jindex-6x","sha":"3a0a5e7a506a341bec9bcaa766cc6a71d40e7ae0","user":{"login":"elastic","id":6764390,"node_id":"MDEyOk9yZ2FuaXphdGlvbjY3NjQzOTA=","avatar_url":"https://avatars0.githubusercontent.com/u/6764390?v=4","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,"node_id":"MDEwOlJlcG9zaXRvcnk1MDc3NzU=","name":"elasticsearch","full_name":"elastic/elasticsearch","private":false,"owner":{"login":"elastic","id":6764390,"node_id":"MDEyOk9yZ2FuaXphdGlvbjY3NjQzOTA=","avatar_url":"https://avatars0.githubusercontent.com/u/6764390?v=4","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},"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":"2018-11-08T14:41:31Z","pushed_at":"2018-11-08T14:53:22Z","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":529588,"stargazers_count":35903,"watchers_count":35903,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":12121,"mirror_url":null,"archived":false,"open_issues_count":1755,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":12121,"open_issues":1755,"watchers":35903,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/35344"},"html":{"href":"https://github.com/elastic/elasticsearch/pull/35344"},"issue":{"href":"https://api.github.com/repos/elastic/elasticsearch/issues/35344"},"comments":{"href":"https://api.github.com/repos/elastic/elasticsearch/issues/35344/comments"},"review_comments":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/35344/comments"},"review_comment":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/35344/commits"},"statuses":{"href":"https://api.github.com/repos/elastic/elasticsearch/statuses/aad7e88848cae14de2913a20a2a4f11e753f37e8"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"davidkyle"}}