{"action":"created","comment":{"url":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments/87308210","pull_request_review_id":7926084,"id":87308210,"diff_hunk":"@@ -19,281 +19,590 @@\n \n package org.elasticsearch.script;\n \n-import org.elasticsearch.ElasticsearchParseException;\n-import org.elasticsearch.common.Nullable;\n+import org.elasticsearch.Version;\n import org.elasticsearch.common.ParseField;\n import org.elasticsearch.common.ParseFieldMatcher;\n-import org.elasticsearch.common.ParsingException;\n+import org.elasticsearch.common.ParseFieldMatcherSupplier;\n import org.elasticsearch.common.bytes.BytesArray;\n import org.elasticsearch.common.io.stream.StreamInput;\n import org.elasticsearch.common.io.stream.StreamOutput;\n import org.elasticsearch.common.io.stream.Writeable;\n+import org.elasticsearch.common.xcontent.ObjectParser;\n+import org.elasticsearch.common.xcontent.ObjectParser.ValueType;\n import org.elasticsearch.common.xcontent.ToXContent;\n import org.elasticsearch.common.xcontent.XContentBuilder;\n import org.elasticsearch.common.xcontent.XContentFactory;\n import org.elasticsearch.common.xcontent.XContentParser;\n+import org.elasticsearch.common.xcontent.XContentParser.Token;\n import org.elasticsearch.common.xcontent.XContentType;\n import org.elasticsearch.index.query.QueryParseContext;\n \n import java.io.IOException;\n+import java.io.UncheckedIOException;\n+import java.util.Collections;\n+import java.util.HashMap;\n import java.util.Map;\n import java.util.Objects;\n \n /**\n- * Script holds all the parameters necessary to compile or find in cache and then execute a script.\n+ * Script represents used-defined input that can be used to\n+ * compile and execute a script from the {@link ScriptService}\n+ * based on the {@link ScriptType}.\n  */\n public final class Script implements ToXContent, Writeable {\n \n+    /**\n+     * The name of the of the default scripting language.\n+     */\n     public static final String DEFAULT_SCRIPT_LANG = \"painless\";\n \n-    private String script;\n-    private ScriptType type;\n-    @Nullable private String lang;\n-    @Nullable private Map<String, Object> params;\n-    @Nullable private XContentType contentType;\n+    /**\n+     * The name of the default template language.\n+     */\n+    public static final String DEFAULT_TEMPLATE_LANG = \"mustache\";\n \n     /**\n-     * Constructor for simple inline script. The script will have no lang or params set.\n-     *\n-     * @param script The inline script to execute.\n+     * The default {@link ScriptType}.\n      */\n-    public Script(String script) {\n-        this(script, ScriptType.INLINE, null, null);\n-    }\n+    public static final ScriptType DEFAULT_SCRIPT_TYPE = ScriptType.INLINE;\n \n-    public Script(String script, ScriptType type, String lang, @Nullable Map<String, ?> params) {\n-        this(script, type, lang, params, null);\n-    }\n+    /**\n+     * Compiler option for {@link XContentType} used for templates.\n+     */\n+    public static final String CONTENT_TYPE_OPTION = \"content_type\";\n \n     /**\n-     * Constructor for Script.\n-     *\n-     * @param script        The cache key of the script to be compiled/executed. For inline scripts this is the actual\n-     *                      script source code. For indexed scripts this is the id used in the request. For on file\n-     *                      scripts this is the file name.\n-     * @param type          The type of script -- dynamic, stored, or file.\n-     * @param lang          The language of the script to be compiled/executed.\n-     * @param params        The map of parameters the script will be executed with.\n-     * @param contentType   The {@link XContentType} of the script. Only relevant for inline scripts that have not been\n-     *                      defined as a plain string, but as json or yaml content. This class needs this information\n-     *                      when serializing the script back to xcontent.\n+     * Standard {@link ParseField} for outer level of script queries.\n+     */\n+    public static final ParseField SCRIPT_PARSE_FIELD = new ParseField(\"script\");\n+\n+    /**\n+     * Standard {@link ParseField} for lang on the inner level.\n+     */\n+    public static final ParseField LANG_PARSE_FIELD = new ParseField(\"lang\");\n+\n+    /**\n+     * Standard {@link ParseField} for options on the inner level.\n+     */\n+    public static final ParseField OPTIONS_PARSE_FIELD = new ParseField(\"options\");\n+\n+    /**\n+     * Standard {@link ParseField} for params on the inner level.\n+     */\n+    public static final ParseField PARAMS_PARSE_FIELD = new ParseField(\"params\");\n+\n+    /**\n+     * Helper class used by {@link ObjectParser} to store mutable {@link Script} variables and then\n+     * construct an immutable {@link Script} object based on parsed XContent.\n      */\n-    @SuppressWarnings(\"unchecked\")\n-    public Script(String script, ScriptType type, String lang, @Nullable Map<String, ?> params,\n-                  @Nullable XContentType  contentType) {\n-        if (contentType != null && type != ScriptType.INLINE) {\n-            throw new IllegalArgumentException(\"The parameter contentType only makes sense for inline scripts\");\n+    private static final class Builder {\n+        private ScriptType type;\n+        private String lang;\n+        private String idOrCode;\n+        private Map<String, String> options;\n+        private Map<String, Object> params;\n+\n+        private Builder() {\n+            // This cannot default to an empty map because options are potentially added at multiple points.\n+            this.options = new HashMap<>();\n+            this.params = Collections.emptyMap();\n         }\n-        this.script = Objects.requireNonNull(script);\n-        this.type = Objects.requireNonNull(type);\n-        this.lang = lang == null ? DEFAULT_SCRIPT_LANG : lang;\n-        this.params = (Map<String, Object>) params;\n-        this.contentType = contentType;\n-    }\n \n-    public Script(StreamInput in) throws IOException {\n-        script = in.readString();\n-        if (in.readBoolean()) {\n-            type = ScriptType.readFrom(in);\n+        /**\n+         * Since inline scripts can accept code rather than just an id, they must also be able\n+         * to handle template parsing, hence the need for custom parsing code.  Templates can\n+         * consist of either an {@link String} or a JSON object.  If a JSON object is discovered\n+         * then the content type option must also be saved as a compiler option.\n+         */\n+        private void setInline(XContentParser parser) {\n+            try {\n+                if (type != null) {\n+                    throwOnlyOneOfType();\n+                }\n+\n+                type = ScriptType.INLINE;\n+\n+                if (parser.currentToken() == Token.START_OBJECT) {\n+                    XContentBuilder builder = XContentFactory.contentBuilder(parser.contentType());\n+                    idOrCode = builder.copyCurrentStructure(parser).bytes().utf8ToString();\n+                    options.put(CONTENT_TYPE_OPTION, parser.contentType().mediaType());\n+                } else {\n+                    idOrCode = parser.text();\n+                }\n+            } catch (IOException exception) {\n+                throw new UncheckedIOException(exception);\n+            }\n         }\n-        lang = in.readOptionalString();\n-        params = in.readMap();\n-        if (in.readBoolean()) {\n-            contentType = XContentType.readFrom(in);\n+\n+        /**\n+         * Set both the id and the type of the stored script.\n+         */\n+        private void setStored(String idOrCode) {\n+            if (type != null) {\n+                throwOnlyOneOfType();\n+            }\n+\n+            type = ScriptType.STORED;\n+            this.idOrCode = idOrCode;\n         }\n-    }\n \n-    @Override\n-    public void writeTo(StreamOutput out) throws IOException {\n-        out.writeString(script);\n-        boolean hasType = type != null;\n-        out.writeBoolean(hasType);\n-        if (hasType) {\n-            type.writeTo(out);\n+        /**\n+         * Set both the id and the type of the file script.\n+         */\n+        private void setFile(String idOrCode) {\n+            if (type != null) {\n+                throwOnlyOneOfType();\n+            }\n+\n+            type = ScriptType.FILE;\n+            this.idOrCode = idOrCode;\n+        }\n+\n+        /**\n+         * Helper method to throw an exception if more than one type of {@link Script} is specified.\n+         */\n+        private void throwOnlyOneOfType() {\n+            throw new IllegalArgumentException(\"must only use one of [\" +\n+                ScriptType.INLINE.getParseField().getPreferredName() + \" + , \" +\n+                ScriptType.STORED.getParseField().getPreferredName() + \" + , \" +\n+                ScriptType.FILE.getParseField().getPreferredName() + \"]\" +\n+                \" when specifying a script\");\n+        }\n+\n+        private void setLang(String lang) {\n+            this.lang = lang;\n+        }\n+\n+        /**\n+         * Options may have already been added if an inline template was specified.\n+         * Appends the user-defined compiler options with the internal compiler options.\n+         */\n+        private void setOptions(Map<String, String> options) {\n+            this.options.putAll(options);\n+        }\n+\n+        private void setParams(Map<String, Object> params) {\n+            this.params = params;\n         }\n-        out.writeOptionalString(lang);\n-        out.writeMap(params);\n-        boolean hasContentType = contentType != null;\n-        out.writeBoolean(hasContentType);\n-        if (hasContentType) {\n-            XContentType.writeTo(contentType, out);\n+\n+        /**\n+         * Validates the parameters and creates an {@link Script}.\n+         * @param lang The default lang is not a compile-time constant and must be provided\n+         *             at run-time this way in case a legacy default language is used from\n+         *             previously stored queries.\n+         */\n+        private Script build(String lang) {","path":"core/src/main/java/org/elasticsearch/script/Script.java","position":238,"original_position":238,"commit_id":"f3d25d5ed55bb39acf24c4490411186ff7221100","original_commit_id":"f3d25d5ed55bb39acf24c4490411186ff7221100","user":{"login":"nik9000","id":215970,"avatar_url":"https://avatars.githubusercontent.com/u/215970?v=3","gravatar_id":"","url":"https://api.github.com/users/nik9000","html_url":"https://github.com/nik9000","followers_url":"https://api.github.com/users/nik9000/followers","following_url":"https://api.github.com/users/nik9000/following{/other_user}","gists_url":"https://api.github.com/users/nik9000/gists{/gist_id}","starred_url":"https://api.github.com/users/nik9000/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nik9000/subscriptions","organizations_url":"https://api.github.com/users/nik9000/orgs","repos_url":"https://api.github.com/users/nik9000/repos","events_url":"https://api.github.com/users/nik9000/events{/privacy}","received_events_url":"https://api.github.com/users/nik9000/received_events","type":"User","site_admin":false},"body":"I think s/lang/defaultLang/","created_at":"2016-11-10T00:31:01Z","updated_at":"2016-11-10T01:02:55Z","html_url":"https://github.com/elastic/elasticsearch/pull/21321#discussion_r87308210","pull_request_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/21321","_links":{"self":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments/87308210"},"html":{"href":"https://github.com/elastic/elasticsearch/pull/21321#discussion_r87308210"},"pull_request":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/21321"}}},"pull_request":{"url":"https://api.github.com/repos/elastic/elasticsearch/pulls/21321","id":92250238,"html_url":"https://github.com/elastic/elasticsearch/pull/21321","diff_url":"https://github.com/elastic/elasticsearch/pull/21321.diff","patch_url":"https://github.com/elastic/elasticsearch/pull/21321.patch","issue_url":"https://api.github.com/repos/elastic/elasticsearch/issues/21321","number":21321,"state":"open","locked":false,"title":"Clean up Script","user":{"login":"jdconrad","id":2126764,"avatar_url":"https://avatars.githubusercontent.com/u/2126764?v=3","gravatar_id":"","url":"https://api.github.com/users/jdconrad","html_url":"https://github.com/jdconrad","followers_url":"https://api.github.com/users/jdconrad/followers","following_url":"https://api.github.com/users/jdconrad/following{/other_user}","gists_url":"https://api.github.com/users/jdconrad/gists{/gist_id}","starred_url":"https://api.github.com/users/jdconrad/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jdconrad/subscriptions","organizations_url":"https://api.github.com/users/jdconrad/orgs","repos_url":"https://api.github.com/users/jdconrad/repos","events_url":"https://api.github.com/users/jdconrad/events{/privacy}","received_events_url":"https://api.github.com/users/jdconrad/received_events","type":"User","site_admin":false},"body":"As the title says.  \r\n\r\nFirst of all, this change looks huge, but it's not.  The only real changes have been made to the Script class itself.  All other changes have been made (mostly through Intellij refactoring) to a change in the Script constructor API to try to clean it up a bit.  Unfortunately, this affects a lot of classes, but the only change will be the arguments being passed in.\r\n\r\nTwo other changes to be aware of:\r\n1. Instead of having XContentType be a variable, made the change to an options Map instead for compiler options.  This makes way more sense given the way options can be passed in at compile time.  This opens up the ability to have user-defined compiler options potentially added in the future.  XContentType simply becomes one of the options.\r\n2. Enforces that all member variables of the script are non-null.  Before null and default value were synonymous for the same thing which could lead to confusion.  There is no reason to not enforce the default values at least, as it can clean up ambiguities passed into the engines where they have to check for null and apply default values themselves.","created_at":"2016-11-03T22:08:02Z","updated_at":"2016-11-10T01:02:55Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7e05104be84d01039f6ad4bc23c7afb8bfc2f4b7","assignee":{"login":"s1monw","id":973334,"avatar_url":"https://avatars.githubusercontent.com/u/973334?v=3","gravatar_id":"","url":"https://api.github.com/users/s1monw","html_url":"https://github.com/s1monw","followers_url":"https://api.github.com/users/s1monw/followers","following_url":"https://api.github.com/users/s1monw/following{/other_user}","gists_url":"https://api.github.com/users/s1monw/gists{/gist_id}","starred_url":"https://api.github.com/users/s1monw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/s1monw/subscriptions","organizations_url":"https://api.github.com/users/s1monw/orgs","repos_url":"https://api.github.com/users/s1monw/repos","events_url":"https://api.github.com/users/s1monw/events{/privacy}","received_events_url":"https://api.github.com/users/s1monw/received_events","type":"User","site_admin":false},"assignees":[{"login":"s1monw","id":973334,"avatar_url":"https://avatars.githubusercontent.com/u/973334?v=3","gravatar_id":"","url":"https://api.github.com/users/s1monw","html_url":"https://github.com/s1monw","followers_url":"https://api.github.com/users/s1monw/followers","following_url":"https://api.github.com/users/s1monw/following{/other_user}","gists_url":"https://api.github.com/users/s1monw/gists{/gist_id}","starred_url":"https://api.github.com/users/s1monw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/s1monw/subscriptions","organizations_url":"https://api.github.com/users/s1monw/orgs","repos_url":"https://api.github.com/users/s1monw/repos","events_url":"https://api.github.com/users/s1monw/events{/privacy}","received_events_url":"https://api.github.com/users/s1monw/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/21321/commits","review_comments_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/21321/comments","review_comment_url":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments{/number}","comments_url":"https://api.github.com/repos/elastic/elasticsearch/issues/21321/comments","statuses_url":"https://api.github.com/repos/elastic/elasticsearch/statuses/f3d25d5ed55bb39acf24c4490411186ff7221100","head":{"label":"jdconrad:compile","ref":"compile","sha":"f3d25d5ed55bb39acf24c4490411186ff7221100","user":{"login":"jdconrad","id":2126764,"avatar_url":"https://avatars.githubusercontent.com/u/2126764?v=3","gravatar_id":"","url":"https://api.github.com/users/jdconrad","html_url":"https://github.com/jdconrad","followers_url":"https://api.github.com/users/jdconrad/followers","following_url":"https://api.github.com/users/jdconrad/following{/other_user}","gists_url":"https://api.github.com/users/jdconrad/gists{/gist_id}","starred_url":"https://api.github.com/users/jdconrad/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jdconrad/subscriptions","organizations_url":"https://api.github.com/users/jdconrad/orgs","repos_url":"https://api.github.com/users/jdconrad/repos","events_url":"https://api.github.com/users/jdconrad/events{/privacy}","received_events_url":"https://api.github.com/users/jdconrad/received_events","type":"User","site_admin":false},"repo":{"id":33491776,"name":"elasticsearch","full_name":"jdconrad/elasticsearch","owner":{"login":"jdconrad","id":2126764,"avatar_url":"https://avatars.githubusercontent.com/u/2126764?v=3","gravatar_id":"","url":"https://api.github.com/users/jdconrad","html_url":"https://github.com/jdconrad","followers_url":"https://api.github.com/users/jdconrad/followers","following_url":"https://api.github.com/users/jdconrad/following{/other_user}","gists_url":"https://api.github.com/users/jdconrad/gists{/gist_id}","starred_url":"https://api.github.com/users/jdconrad/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jdconrad/subscriptions","organizations_url":"https://api.github.com/users/jdconrad/orgs","repos_url":"https://api.github.com/users/jdconrad/repos","events_url":"https://api.github.com/users/jdconrad/events{/privacy}","received_events_url":"https://api.github.com/users/jdconrad/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jdconrad/elasticsearch","description":"Open Source, Distributed, RESTful Search Engine","fork":true,"url":"https://api.github.com/repos/jdconrad/elasticsearch","forks_url":"https://api.github.com/repos/jdconrad/elasticsearch/forks","keys_url":"https://api.github.com/repos/jdconrad/elasticsearch/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jdconrad/elasticsearch/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jdconrad/elasticsearch/teams","hooks_url":"https://api.github.com/repos/jdconrad/elasticsearch/hooks","issue_events_url":"https://api.github.com/repos/jdconrad/elasticsearch/issues/events{/number}","events_url":"https://api.github.com/repos/jdconrad/elasticsearch/events","assignees_url":"https://api.github.com/repos/jdconrad/elasticsearch/assignees{/user}","branches_url":"https://api.github.com/repos/jdconrad/elasticsearch/branches{/branch}","tags_url":"https://api.github.com/repos/jdconrad/elasticsearch/tags","blobs_url":"https://api.github.com/repos/jdconrad/elasticsearch/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jdconrad/elasticsearch/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jdconrad/elasticsearch/git/refs{/sha}","trees_url":"https://api.github.com/repos/jdconrad/elasticsearch/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jdconrad/elasticsearch/statuses/{sha}","languages_url":"https://api.github.com/repos/jdconrad/elasticsearch/languages","stargazers_url":"https://api.github.com/repos/jdconrad/elasticsearch/stargazers","contributors_url":"https://api.github.com/repos/jdconrad/elasticsearch/contributors","subscribers_url":"https://api.github.com/repos/jdconrad/elasticsearch/subscribers","subscription_url":"https://api.github.com/repos/jdconrad/elasticsearch/subscription","commits_url":"https://api.github.com/repos/jdconrad/elasticsearch/commits{/sha}","git_commits_url":"https://api.github.com/repos/jdconrad/elasticsearch/git/commits{/sha}","comments_url":"https://api.github.com/repos/jdconrad/elasticsearch/comments{/number}","issue_comment_url":"https://api.github.com/repos/jdconrad/elasticsearch/issues/comments{/number}","contents_url":"https://api.github.com/repos/jdconrad/elasticsearch/contents/{+path}","compare_url":"https://api.github.com/repos/jdconrad/elasticsearch/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jdconrad/elasticsearch/merges","archive_url":"https://api.github.com/repos/jdconrad/elasticsearch/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jdconrad/elasticsearch/downloads","issues_url":"https://api.github.com/repos/jdconrad/elasticsearch/issues{/number}","pulls_url":"https://api.github.com/repos/jdconrad/elasticsearch/pulls{/number}","milestones_url":"https://api.github.com/repos/jdconrad/elasticsearch/milestones{/number}","notifications_url":"https://api.github.com/repos/jdconrad/elasticsearch/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jdconrad/elasticsearch/labels{/name}","releases_url":"https://api.github.com/repos/jdconrad/elasticsearch/releases{/id}","deployments_url":"https://api.github.com/repos/jdconrad/elasticsearch/deployments","created_at":"2015-04-06T16:19:42Z","updated_at":"2016-01-19T17:54:08Z","pushed_at":"2016-11-08T23:21:15Z","git_url":"git://github.com/jdconrad/elasticsearch.git","ssh_url":"git@github.com:jdconrad/elasticsearch.git","clone_url":"https://github.com/jdconrad/elasticsearch.git","svn_url":"https://github.com/jdconrad/elasticsearch","homepage":"http://elasticsearch.org","size":225662,"stargazers_count":0,"watchers_count":0,"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":0,"default_branch":"master"}},"base":{"label":"elastic:master","ref":"master","sha":"68bed9cd3be61d1e226a2876d3650ba67e6e1fe4","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-11-09T23:48:03Z","pushed_at":"2016-11-10T00:39:58Z","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":369161,"stargazers_count":19251,"watchers_count":19251,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":6577,"mirror_url":null,"open_issues_count":1170,"forks":6577,"open_issues":1170,"watchers":19251,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/21321"},"html":{"href":"https://github.com/elastic/elasticsearch/pull/21321"},"issue":{"href":"https://api.github.com/repos/elastic/elasticsearch/issues/21321"},"comments":{"href":"https://api.github.com/repos/elastic/elasticsearch/issues/21321/comments"},"review_comments":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/21321/comments"},"review_comment":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/elastic/elasticsearch/pulls/21321/commits"},"statuses":{"href":"https://api.github.com/repos/elastic/elasticsearch/statuses/f3d25d5ed55bb39acf24c4490411186ff7221100"}}}}
{"actor":{"display_login":"nik9000"}}