Browse Source

Remove groovy scripting language (#21607)

* Scripting: Remove groovy scripting language

Groovy was deprecated in 5.0. This change removes it, along with the
legacy default language infrastructure in scripting.
Ryan Ernst 9 years ago
parent
commit
6940b2b8c7
40 changed files with 40 additions and 2022 deletions
  1. 0 9
      core/src/main/java/org/elasticsearch/index/query/QueryRewriteContext.java
  2. 0 28
      core/src/main/java/org/elasticsearch/script/ScriptSettings.java
  3. 1 1
      core/src/test/java/org/elasticsearch/index/query/QueryDSLDocumentationTests.java
  4. 0 64
      core/src/test/java/org/elasticsearch/index/query/QueryRewriteContextTests.java
  5. 2 2
      core/src/test/java/org/elasticsearch/script/ScriptServiceTests.java
  6. 0 33
      core/src/test/java/org/elasticsearch/script/ScriptSettingsTests.java
  7. 0 15
      docs/java-api/aggregations/metrics/scripted-metric-aggregation.asciidoc
  8. 0 1
      docs/reference/getting-started.asciidoc
  9. 3 0
      docs/reference/migration/migrate_6_0.asciidoc
  10. 7 0
      docs/reference/migration/migrate_6_0/scripting.asciidoc
  11. 0 6
      docs/reference/modules/scripting.asciidoc
  12. 4 4
      docs/reference/modules/scripting/fields.asciidoc
  13. 0 150
      docs/reference/modules/scripting/groovy.asciidoc
  14. 1 1
      docs/reference/modules/scripting/native.asciidoc
  15. 7 41
      docs/reference/modules/scripting/security.asciidoc
  16. 11 11
      docs/reference/modules/scripting/using.asciidoc
  17. 0 77
      modules/lang-groovy/build.gradle
  18. 0 1
      modules/lang-groovy/licenses/groovy-2.4.6-indy.jar.sha1
  19. 0 15
      modules/lang-groovy/licenses/groovy-LICENSE.txt
  20. 0 5
      modules/lang-groovy/licenses/groovy-NOTICE.txt
  21. 0 35
      modules/lang-groovy/src/main/java/org/elasticsearch/script/groovy/GroovyPlugin.java
  22. 0 384
      modules/lang-groovy/src/main/java/org/elasticsearch/script/groovy/GroovyScriptEngineService.java
  23. 0 59
      modules/lang-groovy/src/main/plugin-metadata/plugin-security.policy
  24. 0 164
      modules/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovyIndexedScriptTests.java
  25. 0 156
      modules/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovyScriptTests.java
  26. 0 177
      modules/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovySecurityTests.java
  27. 0 42
      modules/lang-groovy/src/test/java/org/elasticsearch/script/groovy/LangGroovyClientYamlTestSuiteIT.java
  28. 0 13
      modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/10_basic.yaml
  29. 0 87
      modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/15_update.yaml
  30. 0 73
      modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/16_update2.yaml
  31. 0 69
      modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/25_script_upsert.yaml
  32. 0 72
      modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/30_compile_limit.yaml
  33. 0 48
      modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/90_missing.yaml
  34. 1 1
      modules/percolator/src/main/java/org/elasticsearch/percolator/PercolateQueryBuilder.java
  35. 0 173
      modules/percolator/src/test/java/org/elasticsearch/percolator/PercolatorBackwardsCompatibilityTests.java
  36. 1 1
      modules/reindex/src/test/java/org/elasticsearch/index/reindex/SimpleExecutableScript.java
  37. 1 1
      qa/evil-tests/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java
  38. 1 1
      rest-api-spec/src/main/resources/rest-api-spec/api/update.json
  39. 0 1
      settings.gradle
  40. 0 1
      test/framework/src/main/java/org/elasticsearch/test/rest/yaml/Features.java

+ 0 - 9
core/src/main/java/org/elasticsearch/index/query/QueryRewriteContext.java

@@ -113,15 +113,6 @@ public class QueryRewriteContext implements ParseFieldMatcherSupplier {
         return new QueryParseContext(indicesQueriesRegistry, parser, indexSettings.getParseFieldMatcher());
     }
 
-    /**
-     * Returns a new {@link QueryParseContext} like {@link #newParseContext(XContentParser)} with the only diffence, that
-     * the default script language will default to what has been set in the 'script.legacy.default_lang' setting.
-     */
-    public QueryParseContext newParseContextWithLegacyScriptLanguage(XContentParser parser) {
-        String defaultScriptLanguage = ScriptSettings.getLegacyDefaultLang(indexSettings.getNodeSettings());
-        return new QueryParseContext(defaultScriptLanguage, indicesQueriesRegistry, parser, indexSettings.getParseFieldMatcher());
-    }
-
     public long nowInMillis() {
         return nowInMillis.getAsLong();
     }

+ 0 - 28
core/src/main/java/org/elasticsearch/script/ScriptSettings.java

@@ -32,17 +32,6 @@ import java.util.function.Function;
 
 public class ScriptSettings {
 
-    static final String LEGACY_DEFAULT_LANG = "groovy";
-
-    /**
-     * The default script language to use for scripts that are stored in documents that have no script lang set explicitly.
-     * This setting is legacy setting and only applies for indices created on ES versions prior to version 5.0
-     *
-     * This constant will be removed in the next major release.
-     */
-    @Deprecated
-    public static final String LEGACY_SCRIPT_SETTING = "script.legacy.default_lang";
-
     private static final Map<ScriptType, Setting<Boolean>> SCRIPT_TYPE_SETTING_MAP;
 
     static {
@@ -58,7 +47,6 @@ public class ScriptSettings {
 
     private final Map<ScriptContext, Setting<Boolean>> scriptContextSettingMap;
     private final List<Setting<Boolean>> scriptLanguageSettings;
-    private final Setting<String> defaultLegacyScriptLanguageSetting;
 
     public ScriptSettings(ScriptEngineRegistry scriptEngineRegistry, ScriptContextRegistry scriptContextRegistry) {
         Map<ScriptContext, Setting<Boolean>> scriptContextSettingMap = contextSettings(scriptContextRegistry);
@@ -66,13 +54,6 @@ public class ScriptSettings {
 
         List<Setting<Boolean>> scriptLanguageSettings = languageSettings(SCRIPT_TYPE_SETTING_MAP, scriptContextSettingMap, scriptEngineRegistry, scriptContextRegistry);
         this.scriptLanguageSettings = Collections.unmodifiableList(scriptLanguageSettings);
-
-        this.defaultLegacyScriptLanguageSetting = new Setting<>(LEGACY_SCRIPT_SETTING, LEGACY_DEFAULT_LANG, setting -> {
-            if (!LEGACY_DEFAULT_LANG.equals(setting) && !scriptEngineRegistry.getRegisteredLanguages().containsKey(setting)) {
-                throw new IllegalArgumentException("unregistered default language [" + setting + "]");
-            }
-            return setting;
-        }, Property.NodeScope);
     }
 
     private static Map<ScriptContext, Setting<Boolean>> contextSettings(ScriptContextRegistry scriptContextRegistry) {
@@ -169,19 +150,10 @@ public class ScriptSettings {
         settings.addAll(SCRIPT_TYPE_SETTING_MAP.values());
         settings.addAll(scriptContextSettingMap.values());
         settings.addAll(scriptLanguageSettings);
-        settings.add(defaultLegacyScriptLanguageSetting);
         return settings;
     }
 
     public Iterable<Setting<Boolean>> getScriptLanguageSettings() {
         return scriptLanguageSettings;
     }
-
-    public Setting<String> getDefaultLegacyScriptLanguageSetting() {
-        return defaultLegacyScriptLanguageSetting;
-    }
-
-    public static String getLegacyDefaultLang(Settings settings) {
-        return settings.get(LEGACY_SCRIPT_SETTING, ScriptSettings.LEGACY_DEFAULT_LANG);
-    }
 }

+ 1 - 1
core/src/test/java/org/elasticsearch/index/query/QueryDSLDocumentationTests.java

@@ -297,7 +297,7 @@ public class QueryDSLDocumentationTests extends ESTestCase {
         parameters.put("param1", 5);
         scriptQuery(
                 new Script(
-                    ScriptType.FILE, "groovy", "mygroovyscript",
+                    ScriptType.FILE, "coollang", "myscript",
                     parameters)
             );
 

+ 0 - 64
core/src/test/java/org/elasticsearch/index/query/QueryRewriteContextTests.java

@@ -1,64 +0,0 @@
-/*
- * 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.index.query;
-
-import org.elasticsearch.Version;
-import org.elasticsearch.cluster.metadata.IndexMetaData;
-import org.elasticsearch.common.bytes.BytesArray;
-import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.common.xcontent.XContentHelper;
-import org.elasticsearch.common.xcontent.XContentParser;
-import org.elasticsearch.index.IndexSettings;
-import org.elasticsearch.indices.query.IndicesQueriesRegistry;
-import org.elasticsearch.script.ScriptSettings;
-import org.elasticsearch.search.SearchModule;
-import org.elasticsearch.test.ESTestCase;
-
-import static java.util.Collections.emptyList;
-
-public class QueryRewriteContextTests extends ESTestCase {
-
-    public void testNewParseContextWithLegacyScriptLanguage() throws Exception {
-        String defaultLegacyScriptLanguage = randomAsciiOfLength(4);
-        IndexMetaData.Builder indexMetadata = new IndexMetaData.Builder("index");
-        indexMetadata.settings(Settings.builder().put("index.version.created", Version.CURRENT)
-                .put("index.number_of_shards", 1)
-                .put("index.number_of_replicas", 1)
-        );
-        final long nowInMills = randomPositiveLong();
-        IndicesQueriesRegistry indicesQueriesRegistry = new SearchModule(Settings.EMPTY, false, emptyList()).getQueryParserRegistry();
-        IndexSettings indexSettings = new IndexSettings(indexMetadata.build(),
-                Settings.builder().put(ScriptSettings.LEGACY_SCRIPT_SETTING, defaultLegacyScriptLanguage).build());
-        QueryRewriteContext queryRewriteContext =
-                new QueryRewriteContext(indexSettings, null, null, indicesQueriesRegistry, null, null, null, () -> nowInMills);
-
-        // verify that the default script language in the query parse context is equal to defaultLegacyScriptLanguage variable:
-        QueryParseContext queryParseContext =
-                queryRewriteContext.newParseContextWithLegacyScriptLanguage(XContentHelper.createParser(new BytesArray("{}")));
-        assertEquals(defaultLegacyScriptLanguage, queryParseContext.getDefaultScriptLanguage());
-
-        // verify that the script query's script language is equal to defaultLegacyScriptLanguage variable:
-        XContentParser parser = XContentHelper.createParser(new BytesArray("{\"script\" : {\"script\": \"return true\"}}"));
-        queryParseContext = queryRewriteContext.newParseContextWithLegacyScriptLanguage(parser);
-        ScriptQueryBuilder queryBuilder = (ScriptQueryBuilder) queryParseContext.parseInnerQueryBuilder().get();
-        assertEquals(defaultLegacyScriptLanguage, queryBuilder.script().getLang());
-    }
-
-}

+ 2 - 2
core/src/test/java/org/elasticsearch/script/ScriptServiceTests.java

@@ -221,7 +221,7 @@ public class ScriptServiceTests extends ESTestCase {
             builder.put("script.file", "true");
         }
         buildScriptService(builder.build());
-        createFileScripts("groovy", "mustache", "dtest");
+        createFileScripts("mustache", "dtest");
 
         for (ScriptContext scriptContext : scriptContexts) {
             // only file scripts are accepted by default
@@ -292,7 +292,7 @@ public class ScriptServiceTests extends ESTestCase {
         }
 
         buildScriptService(builder.build());
-        createFileScripts("groovy", "expression", "mustache", "dtest");
+        createFileScripts("expression", "mustache", "dtest");
 
         for (ScriptType scriptType : ScriptType.values()) {
             //make sure file scripts have a different name than inline ones.

+ 0 - 33
core/src/test/java/org/elasticsearch/script/ScriptSettingsTests.java

@@ -34,39 +34,6 @@ import static org.hamcrest.Matchers.equalTo;
 
 public class ScriptSettingsTests extends ESTestCase {
 
-    public void testDefaultLegacyLanguageIsPainless() {
-        ScriptEngineRegistry scriptEngineRegistry =
-                new ScriptEngineRegistry(Collections.singletonList(new CustomScriptEngineService()));
-        ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(Collections.emptyList());
-        ScriptSettings scriptSettings = new ScriptSettings(scriptEngineRegistry, scriptContextRegistry);
-        assertThat(scriptSettings.getDefaultLegacyScriptLanguageSetting().get(Settings.EMPTY),
-                equalTo(ScriptSettings.LEGACY_DEFAULT_LANG));
-    }
-
-    public void testCustomLegacyDefaultLanguage() {
-        ScriptEngineRegistry scriptEngineRegistry =
-            new ScriptEngineRegistry(Collections.singletonList(new CustomScriptEngineService()));
-        ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(Collections.emptyList());
-        ScriptSettings scriptSettings = new ScriptSettings(scriptEngineRegistry, scriptContextRegistry);
-        String defaultLanguage = CustomScriptEngineService.NAME;
-        Settings settings = Settings.builder().put(ScriptSettings.LEGACY_SCRIPT_SETTING, defaultLanguage).build();
-        assertThat(scriptSettings.getDefaultLegacyScriptLanguageSetting().get(settings), equalTo(defaultLanguage));
-    }
-
-    public void testInvalidLegacyDefaultLanguage() {
-        ScriptEngineRegistry scriptEngineRegistry =
-            new ScriptEngineRegistry(Collections.singletonList(new CustomScriptEngineService()));
-        ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(Collections.emptyList());
-        ScriptSettings scriptSettings = new ScriptSettings(scriptEngineRegistry, scriptContextRegistry);
-        Settings settings = Settings.builder().put(ScriptSettings.LEGACY_SCRIPT_SETTING, "C++").build();
-        try {
-            scriptSettings.getDefaultLegacyScriptLanguageSetting().get(settings);
-            fail("should have seen unregistered default language");
-        } catch (IllegalArgumentException e) {
-            assertThat(e.getMessage(), containsString("unregistered default language [C++]"));
-        }
-    }
-
     public void testSettingsAreProperlyPropogated() {
         ScriptEngineRegistry scriptEngineRegistry =
             new ScriptEngineRegistry(Collections.singletonList(new CustomScriptEngineService()));

+ 0 - 15
docs/java-api/aggregations/metrics/scripted-metric-aggregation.asciidoc

@@ -5,21 +5,6 @@ Here is how you can use
 {ref}/search-aggregations-metrics-scripted-metric-aggregation.html[Scripted Metric Aggregation]
 with Java API.
 
-Don't forget to add Groovy in your classpath if you want to run Groovy scripts in an embedded data node
-(for unit tests for example).
-For example, with Maven, add this dependency to your `pom.xml` file:
-
-[source,xml]
---------------------------------------------------
-<dependency>
-    <groupId>org.codehaus.groovy</groupId>
-    <artifactId>groovy-all</artifactId>
-    <version>2.3.2</version>
-    <classifier>indy</classifier>
-</dependency>
---------------------------------------------------
-
-
 ===== Prepare aggregation request
 
 Here is an example on how to create the aggregation request:

+ 0 - 1
docs/reference/getting-started.asciidoc

@@ -153,7 +153,6 @@ If everything goes well, you should see a bunch of messages that look like below
 [2016-09-16T14:17:51,967][INFO ][o.e.p.PluginsService     ] [6-bjhwl] loaded module [aggs-matrix-stats]
 [2016-09-16T14:17:51,967][INFO ][o.e.p.PluginsService     ] [6-bjhwl] loaded module [ingest-common]
 [2016-09-16T14:17:51,967][INFO ][o.e.p.PluginsService     ] [6-bjhwl] loaded module [lang-expression]
-[2016-09-16T14:17:51,967][INFO ][o.e.p.PluginsService     ] [6-bjhwl] loaded module [lang-groovy]
 [2016-09-16T14:17:51,967][INFO ][o.e.p.PluginsService     ] [6-bjhwl] loaded module [lang-mustache]
 [2016-09-16T14:17:51,967][INFO ][o.e.p.PluginsService     ] [6-bjhwl] loaded module [lang-painless]
 [2016-09-16T14:17:51,967][INFO ][o.e.p.PluginsService     ] [6-bjhwl] loaded module [percolator]

+ 3 - 0
docs/reference/migration/migrate_6_0.asciidoc

@@ -33,6 +33,7 @@ way to reindex old indices is to use the `reindex` API.
 * <<breaking_60_settings_changes>>
 * <<breaking_60_plugins_changes>>
 * <<breaking_60_indices_changes>>
+* <<breaking_60_scripting_changes>>
 
 include::migrate_6_0/cat.asciidoc[]
 
@@ -51,3 +52,5 @@ include::migrate_6_0/settings.asciidoc[]
 include::migrate_6_0/plugins.asciidoc[]
 
 include::migrate_6_0/indices.asciidoc[]
+
+include::migrate_6_0/scripting.asciidoc[]

+ 7 - 0
docs/reference/migration/migrate_6_0/scripting.asciidoc

@@ -0,0 +1,7 @@
+[[breaking_60_scripting_changes]]
+=== Scripting changes
+
+==== Groovy language removed
+
+The groovy scripting language was deprecated in elasticsearch 5.0 and is now removed.
+Use painless instead.

+ 0 - 6
docs/reference/modules/scripting.asciidoc

@@ -26,10 +26,6 @@ and give the most flexibility.
     |yes
     |built-in
 
-|<<modules-scripting-groovy, `groovy`>>
-    |<<modules-scripting-security, no>>
-    |built-in
-
 |=======================================================================
 
 [float]
@@ -79,8 +75,6 @@ include::scripting/fields.asciidoc[]
 
 include::scripting/security.asciidoc[]
 
-include::scripting/groovy.asciidoc[]
-
 include::scripting/painless.asciidoc[]
 
 include::scripting/painless-syntax.asciidoc[]

+ 4 - 4
docs/reference/modules/scripting/fields.asciidoc

@@ -198,14 +198,14 @@ GET my_index/_search
   "script_fields": {
     "source": {
       "script": {
-        "lang": "groovy",
-        "inline": "_source.title + ' ' + _source.first_name + ' ' + _source.last_name" <2>
+        "lang": "painless",
+        "inline": "params._source.title + ' ' + params._source.first_name + ' ' + params._source.last_name" <2>
       }
     },
     "stored_fields": {
       "script": {
-        "lang": "groovy",
-        "inline": "_fields['first_name'].value + ' ' + _fields['last_name'].value"
+        "lang": "painless",
+        "inline": "params._fields['first_name'].value + ' ' + params._fields['last_name'].value"
       }
     }
   }

+ 0 - 150
docs/reference/modules/scripting/groovy.asciidoc

@@ -1,150 +0,0 @@
-[[modules-scripting-groovy]]
-=== Groovy Scripting Language
-
-deprecated[5.0.0,Groovy will be replaced by the new scripting language <<modules-scripting-painless, `Painless`>>]
-
-Groovy is available in Elasticsearch by default.  Although
-limited by the <<java-security-manager,Java Security Manager>>, it is not a
-sandboxed language and only `file` scripts may be used by default.
-
-Enabling `inline` or `stored` Groovy scripting is a security risk and should
-only be considered if your Elasticsearch cluster is protected from the outside
-world. Even a simple `while (true) { }` loop could behave as a denial-of-
-service attack on your cluster.
-
-See <<modules-scripting-security, Scripting and Security>> for details
-on security issues with scripts, including how to customize class
-whitelisting.
-
-[float]
-=== Doc value properties and methods
-
-Doc values in Groovy support the following properties and methods (depending
-on the underlying field type):
-
-`doc['field_name'].value`::
-    The native value of the field. For example, if its a short type, it will be short.
-
-`doc['field_name'].values`::
-    The native array values of the field. For example, if its a short type,
-     it will be short[]. Remember, a field can have several values within a
-     single doc. Returns an empty array if the field has no values.
-
-`doc['field_name'].empty`::
-    A boolean indicating if the field has no values within the doc.
-
-`doc['field_name'].lat`::
-    The latitude of a geo point type, or `null`.
-
-`doc['field_name'].lon`::
-    The longitude of a geo point type, or `null`.
-
-`doc['field_name'].lats`::
-    The latitudes of a geo point type, or an empty array.
-
-`doc['field_name'].lons`::
-    The longitudes of a geo point type, or an empty array.
-
-`doc['field_name'].arcDistance(lat, lon)`::
-    The `arc` distance (in meters) of this geo point field from the provided lat/lon.
-
-`doc['field_name'].arcDistanceWithDefault(lat, lon, default)`::
-    The `arc` distance (in meters) of this geo point field from the provided lat/lon with a default value
-    for empty fields.
-
-`doc['field_name'].planeDistance(lat, lon)`::
-    The `plane` distance (in meters) of this geo point field from the provided lat/lon.
-
-`doc['field_name'].planeDistanceWithDefault(lat, lon, default)`::
-    The `plane` distance (in meters) of this geo point field from the provided lat/lon with a default value
-    for empty fields.
-
-`doc['field_name'].geohashDistance(geohash)`::
-    The `arc` distance (in meters) of this geo point field from the provided geohash.
-
-`doc['field_name'].geohashDistanceWithDefault(geohash, default)`::
-    The `arc` distance (in meters) of this geo point field from the provided geohash with a default value
-    for empty fields.
-
-
-[float]
-=== Groovy Built In Functions
-
-There are several built in functions that can be used within scripts.
-They include:
-
-[cols="<,<",options="header",]
-|=======================================================================
-|Function |Description
-|`sin(a)` |Returns the trigonometric sine of an angle.
-
-|`cos(a)` |Returns the trigonometric cosine of an angle.
-
-|`tan(a)` |Returns the trigonometric tangent of an angle.
-
-|`asin(a)` |Returns the arc sine of a value.
-
-|`acos(a)` |Returns the arc cosine of a value.
-
-|`atan(a)` |Returns the arc tangent of a value.
-
-|`toRadians(angdeg)` |Converts an angle measured in degrees to an
-approximately equivalent angle measured in radians
-
-|`toDegrees(angrad)` |Converts an angle measured in radians to an
-approximately equivalent angle measured in degrees.
-
-|`exp(a)` |Returns Euler's number _e_ raised to the power of value.
-
-|`log(a)` |Returns the natural logarithm (base _e_) of a value.
-
-|`log10(a)` |Returns the base 10 logarithm of a value.
-
-|`sqrt(a)` |Returns the correctly rounded positive square root of a
-value.
-
-|`cbrt(a)` |Returns the cube root of a double value.
-
-|`IEEEremainder(f1, f2)` |Computes the remainder operation on two
-arguments as prescribed by the IEEE 754 standard.
-
-|`ceil(a)` |Returns the smallest (closest to negative infinity) value
-that is greater than or equal to the argument and is equal to a
-mathematical integer.
-
-|`floor(a)` |Returns the largest (closest to positive infinity) value
-that is less than or equal to the argument and is equal to a
-mathematical integer.
-
-|`rint(a)` |Returns the value that is closest in value to the argument
-and is equal to a mathematical integer.
-
-|`atan2(y, x)` |Returns the angle _theta_ from the conversion of
-rectangular coordinates (_x_, _y_) to polar coordinates (r,_theta_).
-
-|`pow(a, b)` |Returns the value of the first argument raised to the
-power of the second argument.
-
-|`round(a)` |Returns the closest _int_ to the argument.
-
-|`random()` |Returns a random _double_ value.
-
-|`abs(a)` |Returns the absolute value of a value.
-
-|`max(a, b)` |Returns the greater of two values.
-
-|`min(a, b)` |Returns the smaller of two values.
-
-|`ulp(d)` |Returns the size of an ulp of the argument.
-
-|`signum(d)` |Returns the signum function of the argument.
-
-|`sinh(x)` |Returns the hyperbolic sine of a value.
-
-|`cosh(x)` |Returns the hyperbolic cosine of a value.
-
-|`tanh(x)` |Returns the hyperbolic tangent of a value.
-
-|`hypot(x, y)` |Returns sqrt(_x2_ + _y2_) without intermediate overflow
-or underflow.
-|=======================================================================

+ 1 - 1
docs/reference/modules/scripting/native.asciidoc

@@ -1,7 +1,7 @@
 [[modules-scripting-native]]
 === Native (Java) Scripts
 
-Sometimes `groovy` and <<modules-scripting-expression, expression>> aren't enough. For those times you can
+Sometimes `painless` and <<modules-scripting-expression, expression>> aren't enough. For those times you can
 implement a native script.
 
 The best way to implement a native script is to write a plugin and install it.

+ 7 - 41
docs/reference/modules/scripting/security.asciidoc

@@ -14,16 +14,16 @@ to run scripts on your box or not, and apply the appropriate safety measures.
 === Enabling dynamic scripting
 
 The `script.*` settings allow for <<security-script-fine,fine-grained>>
-control of which script languages (e.g `groovy`, `painless`) are allowed to
+control of which script languages (e.g `painless`) are allowed to
 run in which context ( e.g. `search`, `aggs`, `update`), and where the script
 source is allowed to come from (i.e. `inline`, `stored`, `file`).
 
 For instance, the following setting enables `stored` `update` scripts for
-`groovy`:
+`painless`:
 
 [source,yaml]
 ----------------
-script.engine.groovy.inline.update: true
+script.engine.painless.inline.update: true
 ----------------
 
 Less fine-grained settings exist which allow you to enable or disable scripts
@@ -128,9 +128,9 @@ script.inline: false <1>
 script.stored: false <1>
 script.file:   false <1>
 
-script.engine.groovy.inline:          true <2>
-script.engine.groovy.stored.search:   true <3>
-script.engine.groovy.stored.aggs:     true <3>
+script.engine.painless.inline:          true <2>
+script.engine.painless.stored.search:   true <3>
+script.engine.painless.stored.aggs:     true <3>
 
 script.engine.mustache.stored.search: true <4>
 -----------------------------------
@@ -184,7 +184,7 @@ will return the following exception:
 {
   "reason": {
     "type": "script_exception",
-    "reason": "failed to run inline script [use(java.math.BigInteger); new BigInteger(1)] using lang [groovy]",
+    "reason": "failed to run inline script [use(java.math.BigInteger); new BigInteger(1)] using lang [painless]",
     "caused_by": {
       "type": "no_class_def_found_error",
       "reason": "java/math/BigInteger",
@@ -197,30 +197,6 @@ will return the following exception:
 }
 ------------------------------
 
-However, classloader issues may also result in more difficult to interpret
-exceptions.  For instance, this script:
-
-[source,groovy]
-------------------------------
-use(groovy.time.TimeCategory); new Date(123456789).format('HH')
-------------------------------
-
-Returns the following exception:
-
-[source,js]
-------------------------------
-{
-  "reason": {
-    "type": "script_exception",
-    "reason": "failed to run inline script [use(groovy.time.TimeCategory); new Date(123456789).format('HH')] using lang [groovy]",
-    "caused_by": {
-      "type": "missing_property_exception",
-      "reason": "No such property: groovy for class: 8d45f5c1a07a1ab5dda953234863e283a7586240"
-    }
-  }
-}
-------------------------------
-
 [float]
 == Dealing with Java Security Manager issues
 
@@ -262,16 +238,6 @@ grant {
 };
 ----------------------------------
 
-Here is an example of how to enable the `groovy.time.TimeCategory` class:
-
-[source,js]
-----------------------------------
-grant {
-    permission org.elasticsearch.script.ClassPermission "java.lang.Class";
-    permission org.elasticsearch.script.ClassPermission "groovy.time.TimeCategory";
-};
-----------------------------------
-
 [TIP]
 ======================================
 

+ 11 - 11
docs/reference/modules/scripting/using.asciidoc

@@ -48,7 +48,7 @@ GET my_index/_search
 
 `lang`::
 
-    Specifies the language the script is written in.  Defaults to `groovy` but
+    Specifies the language the script is written in.  Defaults to `painless` but
     may be set to any of languages listed in <<modules-scripting>>. The
     default language may be changed in the `elasticsearch.yml` config file by
     setting `script.default_lang` to the appropriate language.
@@ -63,7 +63,7 @@ GET my_index/_search
     directory (see <<modules-scripting-file-scripts, File Scripts>>).
 +
 While languages like `expression` and `painless` can be used out of the box as
-inline or stored scripts, other languages like `groovy` can only be
+inline or stored scripts, other languages can only be
 specified as `file` unless you first adjust the default
 <<modules-scripting-security,scripting security settings>>.
 
@@ -134,7 +134,7 @@ the following example creates a Groovy script called `calculate-score`:
 
 [source,sh]
 --------------------------------------------------
-cat "log(_score * 2) + my_modifier" > config/scripts/calculate-score.groovy
+cat "Math.log(_score * 2) + my_modifier" > config/scripts/calculate-score.painless
 --------------------------------------------------
 
 This script can be used as follows:
@@ -146,7 +146,7 @@ GET my_index/_search
   "query": {
     "script": {
       "script": {
-        "lang":   "groovy", <1>
+        "lang":   "painless", <1>
         "file":   "calculate-score", <2>
         "params": {
           "my_modifier": 2
@@ -161,7 +161,7 @@ GET my_index/_search
 
 The `script` directory may contain sub-directories, in which case the
 hierarchy of directories is flattened and concatenated with underscores.  A
-script in `group1/group2/my_script.groovy` should use `group1_group2_myscript`
+script in `group1/group2/my_script.painless` should use `group1_group2_myscript`
 as the `file` name.
 
 
@@ -190,14 +190,14 @@ Scripts may be stored in and retrieved from the cluster state using the
 <1> The `lang` represents the script language.
 <2> The `id` is a unique identifier or script name.
 
-This example stores a Groovy script called `calculate-score` in the cluster
+This example stores a Painless script called `calculate-score` in the cluster
 state:
 
 [source,js]
 -----------------------------------
-POST _scripts/groovy/calculate-score
+POST _scripts/painless/calculate-score
 {
-  "script": "log(_score * 2) + my_modifier"
+  "script": "Math.log(_score * 2) + params.my_modifier"
 }
 -----------------------------------
 // CONSOLE
@@ -206,7 +206,7 @@ This same script can be retrieved with:
 
 [source,js]
 -----------------------------------
-GET _scripts/groovy/calculate-score
+GET _scripts/painless/calculate-score
 -----------------------------------
 // CONSOLE
 // TEST[continued]
@@ -220,7 +220,7 @@ GET _search
   "query": {
     "script": {
       "script": {
-        "lang": "groovy",
+        "lang": "painless",
         "stored": "calculate-score",
         "params": {
           "my_modifier": 2
@@ -237,7 +237,7 @@ And deleted with:
 
 [source,js]
 -----------------------------------
-DELETE _scripts/groovy/calculate-score
+DELETE _scripts/painless/calculate-score
 -----------------------------------
 // CONSOLE
 // TEST[continued]

+ 0 - 77
modules/lang-groovy/build.gradle

@@ -1,77 +0,0 @@
-/*
- * 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.
- */
-
-esplugin {
-  description 'Groovy scripting integration for Elasticsearch'
-  classname 'org.elasticsearch.script.groovy.GroovyPlugin'
-}
-
-dependencies {
-  compile 'org.codehaus.groovy:groovy:2.4.6:indy'
-}
-
-integTest {
-  cluster {
-    setting 'script.inline', 'true'
-    setting 'script.stored', 'true'
-    setting 'script.max_compilations_per_minute', '1000'
-  }
-}
-
-thirdPartyAudit.excludes = [
-  // classes are missing, we bring in a minimal groovy dist
-  // for example we do not need ivy, scripts arent allowed to download code
-  'com.thoughtworks.xstream.XStream', 
-  'groovyjarjarasm.asm.util.Textifiable', 
-  // commons-cli is referenced by groovy, even though they supposedly
-  // jarjar it. Since we don't use the cli, we don't need the dep.
-  'org.apache.commons.cli.CommandLine',
-  'org.apache.commons.cli.CommandLineParser',
-  'org.apache.commons.cli.GnuParser',
-  'org.apache.commons.cli.HelpFormatter',
-  'org.apache.commons.cli.Option',
-  'org.apache.commons.cli.OptionBuilder',
-  'org.apache.commons.cli.Options',
-  'org.apache.commons.cli.Parser',
-  'org.apache.commons.cli.PosixParser',
-  'org.apache.ivy.Ivy', 
-  'org.apache.ivy.core.event.IvyListener', 
-  'org.apache.ivy.core.event.download.PrepareDownloadEvent', 
-  'org.apache.ivy.core.event.resolve.StartResolveEvent', 
-  'org.apache.ivy.core.module.descriptor.Configuration', 
-  'org.apache.ivy.core.module.descriptor.DefaultDependencyArtifactDescriptor', 
-  'org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor', 
-  'org.apache.ivy.core.module.descriptor.DefaultExcludeRule', 
-  'org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor', 
-  'org.apache.ivy.core.module.id.ArtifactId', 
-  'org.apache.ivy.core.module.id.ModuleId', 
-  'org.apache.ivy.core.module.id.ModuleRevisionId', 
-  'org.apache.ivy.core.report.ResolveReport', 
-  'org.apache.ivy.core.resolve.ResolveOptions', 
-  'org.apache.ivy.core.settings.IvySettings', 
-  'org.apache.ivy.plugins.matcher.ExactPatternMatcher', 
-  'org.apache.ivy.plugins.matcher.PatternMatcher', 
-  'org.apache.ivy.plugins.resolver.IBiblioResolver', 
-  'org.apache.ivy.util.DefaultMessageLogger', 
-  'org.apache.ivy.util.Message', 
-  'org.fusesource.jansi.Ansi$Attribute', 
-  'org.fusesource.jansi.Ansi$Color', 
-  'org.fusesource.jansi.Ansi', 
-  'org.fusesource.jansi.AnsiRenderWriter',
-]

+ 0 - 1
modules/lang-groovy/licenses/groovy-2.4.6-indy.jar.sha1

@@ -1 +0,0 @@
-af78e80fab591a6dcf2d6ccb8bf34d1e888291be

+ 0 - 15
modules/lang-groovy/licenses/groovy-LICENSE.txt

@@ -1,15 +0,0 @@
-/*
- * Licensed 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.
- *
- */
- 

+ 0 - 5
modules/lang-groovy/licenses/groovy-NOTICE.txt

@@ -1,5 +0,0 @@
-Apache Groovy
-Copyright 2003-2016 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).

+ 0 - 35
modules/lang-groovy/src/main/java/org/elasticsearch/script/groovy/GroovyPlugin.java

@@ -1,35 +0,0 @@
-/*
- * 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.script.groovy;
-
-import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.plugins.Plugin;
-import org.elasticsearch.plugins.ScriptPlugin;
-import org.elasticsearch.script.ScriptEngineRegistry;
-import org.elasticsearch.script.ScriptEngineService;
-import org.elasticsearch.script.ScriptModule;
-
-public class GroovyPlugin extends Plugin implements ScriptPlugin {
-
-    @Override
-    public ScriptEngineService getScriptEngineService(Settings settings) {
-        return new GroovyScriptEngineService(settings);
-    }
-}

+ 0 - 384
modules/lang-groovy/src/main/java/org/elasticsearch/script/groovy/GroovyScriptEngineService.java

@@ -1,384 +0,0 @@
-/*
- * 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.script.groovy;
-
-import groovy.lang.Binding;
-import groovy.lang.GroovyClassLoader;
-import groovy.lang.GroovyCodeSource;
-import groovy.lang.Script;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.message.ParameterizedMessage;
-import org.apache.logging.log4j.util.Supplier;
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.Scorer;
-import org.codehaus.groovy.GroovyBugError;
-import org.codehaus.groovy.ast.ClassCodeExpressionTransformer;
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.expr.ConstantExpression;
-import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.classgen.GeneratorContext;
-import org.codehaus.groovy.control.CompilationFailedException;
-import org.codehaus.groovy.control.CompilePhase;
-import org.codehaus.groovy.control.CompilerConfiguration;
-import org.codehaus.groovy.control.MultipleCompilationErrorsException;
-import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.control.customizers.CompilationCustomizer;
-import org.codehaus.groovy.control.customizers.ImportCustomizer;
-import org.codehaus.groovy.control.messages.Message;
-import org.elasticsearch.SpecialPermission;
-import org.elasticsearch.bootstrap.BootstrapInfo;
-import org.elasticsearch.common.Nullable;
-import org.elasticsearch.common.component.AbstractComponent;
-import org.elasticsearch.common.hash.MessageDigests;
-import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.script.ClassPermission;
-import org.elasticsearch.script.CompiledScript;
-import org.elasticsearch.script.ExecutableScript;
-import org.elasticsearch.script.LeafSearchScript;
-import org.elasticsearch.script.ScoreAccessor;
-import org.elasticsearch.script.ScriptEngineService;
-import org.elasticsearch.script.ScriptException;
-import org.elasticsearch.script.SearchScript;
-import org.elasticsearch.search.lookup.LeafSearchLookup;
-import org.elasticsearch.search.lookup.SearchLookup;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.math.BigDecimal;
-import java.nio.charset.StandardCharsets;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static java.util.Collections.emptyList;
-
-/**
- * Provides the infrastructure for Groovy as a scripting language for Elasticsearch
- */
-public class GroovyScriptEngineService extends AbstractComponent implements ScriptEngineService {
-
-    /**
-     * The name of the scripting engine/language.
-     */
-    public static final String NAME = "groovy";
-
-    /**
-     * The name of the Groovy compiler setting to use associated with activating <code>invokedynamic</code> support.
-     */
-    public static final String GROOVY_INDY_SETTING_NAME = "indy";
-
-    /**
-     * Classloader used as a parent classloader for all Groovy scripts
-     */
-    private final ClassLoader loader;
-
-    public GroovyScriptEngineService(Settings settings) {
-        super(settings);
-
-        deprecationLogger.deprecated("[groovy] scripts are deprecated, use [painless] scripts instead");
-
-        // Creates the classloader here in order to isolate Groovy-land code
-        final SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(new SpecialPermission());
-        }
-        this.loader = AccessController.doPrivileged((PrivilegedAction<ClassLoader>) () -> {
-            // snapshot our context (which has permissions for classes), since the script has none
-            AccessControlContext context = AccessController.getContext();
-            return new ClassLoader(getClass().getClassLoader()) {
-                @Override
-                protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
-                    if (sm != null) {
-                        try {
-                            context.checkPermission(new ClassPermission(name));
-                        } catch (SecurityException e) {
-                            throw new ClassNotFoundException(name, e);
-                        }
-                    }
-                    return super.loadClass(name, resolve);
-                }
-            };
-        });
-    }
-
-    @Override
-    public void close() throws IOException {
-        // Nothing to do here
-    }
-
-    @Override
-    public String getType() {
-        return NAME;
-    }
-
-    @Override
-    public String getExtension() {
-        return NAME;
-    }
-
-    @Override
-    public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
-        // Create the script class name
-        String className = MessageDigests.toHexString(MessageDigests.sha1().digest(scriptSource.getBytes(StandardCharsets.UTF_8)));
-
-        final SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(new SpecialPermission());
-        }
-        return AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
-            try {
-                GroovyCodeSource codeSource = new GroovyCodeSource(scriptSource, className, BootstrapInfo.UNTRUSTED_CODEBASE);
-                codeSource.setCachable(false);
-
-                CompilerConfiguration configuration = new CompilerConfiguration()
-                        .addCompilationCustomizers(new ImportCustomizer().addStarImports("org.joda.time").addStaticStars("java.lang.Math"))
-                        .addCompilationCustomizers(new GroovyBigDecimalTransformer(CompilePhase.CONVERSION));
-
-                // always enable invokeDynamic, not the crazy softreference-based stuff
-                configuration.getOptimizationOptions().put(GROOVY_INDY_SETTING_NAME, true);
-
-                GroovyClassLoader groovyClassLoader = new GroovyClassLoader(loader, configuration);
-                return groovyClassLoader.parseClass(codeSource);
-            } catch (Exception e) {
-                if (logger.isTraceEnabled()) {
-                    logger.trace("Exception compiling Groovy script:", e);
-                }
-                throw convertToScriptException("Error compiling script " + className, scriptSource, e);
-            }
-        });
-    }
-
-    /**
-     * Return a script object with the given vars from the compiled script object
-     */
-    @SuppressWarnings("unchecked")
-    private Script createScript(Object compiledScript, Map<String, Object> vars) throws ReflectiveOperationException {
-        Class<?> scriptClass = (Class<?>) compiledScript;
-        Script scriptObject = (Script) scriptClass.getConstructor().newInstance();
-        Binding binding = new Binding();
-        binding.getVariables().putAll(vars);
-        scriptObject.setBinding(binding);
-        return scriptObject;
-    }
-
-    @Override
-    public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> vars) {
-        deprecationLogger.deprecated("[groovy] scripts are deprecated, use [painless] scripts instead");
-
-        try {
-            Map<String, Object> allVars = new HashMap<>();
-            if (vars != null) {
-                allVars.putAll(vars);
-            }
-            return new GroovyScript(compiledScript, createScript(compiledScript.compiled(), allVars), this.logger);
-        } catch (ReflectiveOperationException e) {
-            throw convertToScriptException("Failed to build executable script", compiledScript.name(), e);
-        }
-    }
-
-    @Override
-    public SearchScript search(final CompiledScript compiledScript, final SearchLookup lookup, @Nullable final Map<String, Object> vars) {
-        deprecationLogger.deprecated("[groovy] scripts are deprecated, use [painless] scripts instead");
-
-        return new SearchScript() {
-
-            @Override
-            public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
-                final LeafSearchLookup leafLookup = lookup.getLeafSearchLookup(context);
-                Map<String, Object> allVars = new HashMap<>();
-                allVars.putAll(leafLookup.asMap());
-                if (vars != null) {
-                    allVars.putAll(vars);
-                }
-                Script scriptObject;
-                try {
-                    scriptObject = createScript(compiledScript.compiled(), allVars);
-                } catch (ReflectiveOperationException e) {
-                    throw convertToScriptException("Failed to build search script", compiledScript.name(), e);
-                }
-                return new GroovyScript(compiledScript, scriptObject, leafLookup, logger);
-            }
-
-            @Override
-            public boolean needsScores() {
-                // TODO: can we reliably know if a groovy script makes use of _score
-                return true;
-            }
-        };
-    }
-
-    /**
-     * Converts a {@link Throwable} to a {@link ScriptException}
-     */
-    private ScriptException convertToScriptException(String message, String source, Throwable cause) {
-        List<String> stack = new ArrayList<>();
-        if (cause instanceof MultipleCompilationErrorsException) {
-            @SuppressWarnings({"unchecked"})
-            List<Message> errors = (List<Message>) ((MultipleCompilationErrorsException) cause).getErrorCollector().getErrors();
-            for (Message error : errors) {
-                try (StringWriter writer = new StringWriter()) {
-                    error.write(new PrintWriter(writer));
-                    stack.add(writer.toString());
-                } catch (IOException e1) {
-                    logger.error("failed to write compilation error message to the stack", e1);
-                }
-            }
-        } else if (cause instanceof CompilationFailedException) {
-            CompilationFailedException error = (CompilationFailedException) cause;
-            stack.add(error.getMessage());
-        }
-        throw new ScriptException(message, cause, stack, source, NAME);
-    }
-
-    public static final class GroovyScript implements ExecutableScript, LeafSearchScript {
-
-        private final CompiledScript compiledScript;
-        private final Script script;
-        private final LeafSearchLookup lookup;
-        private final Map<String, Object> variables;
-        private final Logger logger;
-
-        public GroovyScript(CompiledScript compiledScript, Script script, Logger logger) {
-            this(compiledScript, script, null, logger);
-        }
-
-        @SuppressWarnings("unchecked")
-        public GroovyScript(CompiledScript compiledScript, Script script, @Nullable LeafSearchLookup lookup, Logger logger) {
-            this.compiledScript = compiledScript;
-            this.script = script;
-            this.lookup = lookup;
-            this.logger = logger;
-            this.variables = script.getBinding().getVariables();
-        }
-
-        @Override
-        public void setScorer(Scorer scorer) {
-            this.variables.put("_score", new ScoreAccessor(scorer));
-        }
-
-        @Override
-        public void setDocument(int doc) {
-            if (lookup != null) {
-                lookup.setDocument(doc);
-            }
-        }
-
-        @Override
-        public void setNextVar(String name, Object value) {
-            variables.put(name, value);
-        }
-
-        @Override
-        public void setSource(Map<String, Object> source) {
-            if (lookup != null) {
-                lookup.source().setSource(source);
-            }
-        }
-
-        @Override
-        public Object run() {
-            try {
-                // NOTE: we truncate the stack because IndyInterface has security issue (needs getClassLoader)
-                // we don't do a security check just as a tradeoff, it cannot really escalate to anything.
-                return AccessController.doPrivileged((PrivilegedAction<Object>) script::run);
-            } catch (final AssertionError ae) {
-                if (ae instanceof GroovyBugError) {
-                    // we encountered a bug in Groovy; we wrap this so it does not go to the uncaught exception handler and tear us down
-                    final String message =  "encountered bug in Groovy while executing script [" + compiledScript.name() + "]";
-                    throw new ScriptException(message, ae, Collections.emptyList(), compiledScript.toString(), compiledScript.lang());
-                }
-                // Groovy asserts are not java asserts, and cannot be disabled, so we do a best-effort trying to determine if this is a
-                // Groovy assert (in which case we wrap it and throw), or a real Java assert, in which case we rethrow it as-is, likely
-                // resulting in the uncaughtExceptionHandler handling it.
-                final StackTraceElement[] elements = ae.getStackTrace();
-                if (elements.length > 0 && "org.codehaus.groovy.runtime.InvokerHelper".equals(elements[0].getClassName())) {
-                    logger.debug((Supplier<?>) () -> new ParameterizedMessage("failed to run {}", compiledScript), ae);
-                    throw new ScriptException("error evaluating " + compiledScript.name(), ae, emptyList(), "", compiledScript.lang());
-                }
-                throw ae;
-            } catch (Exception | NoClassDefFoundError e) {
-                logger.trace((Supplier<?>) () -> new ParameterizedMessage("failed to run {}", compiledScript), e);
-                throw new ScriptException("error evaluating " + compiledScript.name(), e, emptyList(), "", compiledScript.lang());
-            }
-        }
-
-        @Override
-        public long runAsLong() {
-            return ((Number) run()).longValue();
-        }
-
-        @Override
-        public double runAsDouble() {
-            return ((Number) run()).doubleValue();
-        }
-    }
-
-    /**
-     * A compilation customizer that is used to transform a number like 1.23,
-     * which would normally be a BigDecimal, into a double value.
-     */
-    private class GroovyBigDecimalTransformer extends CompilationCustomizer {
-
-        private GroovyBigDecimalTransformer(CompilePhase phase) {
-            super(phase);
-        }
-
-        @Override
-        public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
-            new BigDecimalExpressionTransformer(source).visitClass(classNode);
-        }
-    }
-
-    /**
-     * Groovy expression transformer that converts BigDecimals to doubles
-     */
-    private class BigDecimalExpressionTransformer extends ClassCodeExpressionTransformer {
-
-        private final SourceUnit source;
-
-        private BigDecimalExpressionTransformer(SourceUnit source) {
-            this.source = source;
-        }
-
-        @Override
-        protected SourceUnit getSourceUnit() {
-            return this.source;
-        }
-
-        @Override
-        public Expression transform(Expression expr) {
-            Expression newExpr = expr;
-            if (expr instanceof ConstantExpression) {
-                ConstantExpression constExpr = (ConstantExpression) expr;
-                Object val = constExpr.getValue();
-                if (val != null && val instanceof BigDecimal) {
-                    newExpr = new ConstantExpression(((BigDecimal) val).doubleValue());
-                }
-            }
-            return super.transform(newExpr);
-        }
-    }
-}

+ 0 - 59
modules/lang-groovy/src/main/plugin-metadata/plugin-security.policy

@@ -1,59 +0,0 @@
-/*
- * 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.
- */
-
-grant {
-  // needed to generate runtime classes
-  permission java.lang.RuntimePermission "createClassLoader";
-  // needed by IndyInterface
-  permission java.lang.RuntimePermission "getClassLoader";
-  // needed by groovy engine
-  permission java.lang.RuntimePermission "accessDeclaredMembers";
-  permission java.lang.RuntimePermission "accessClassInPackage.sun.reflect";
-  permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.reflect";
-  // Allow executing groovy scripts with codesource of /untrusted
-  permission groovy.security.GroovyCodeSourcePermission "/untrusted";
-
-  // Standard set of classes
-  permission org.elasticsearch.script.ClassPermission "<<STANDARD>>";
-  // groovy runtime (TODO: clean these up if possible)
-  permission org.elasticsearch.script.ClassPermission "groovy.grape.GrabAnnotationTransformation";
-  permission org.elasticsearch.script.ClassPermission "groovy.lang.Binding";
-  permission org.elasticsearch.script.ClassPermission "groovy.lang.GroovyObject";
-  permission org.elasticsearch.script.ClassPermission "groovy.lang.GString";
-  permission org.elasticsearch.script.ClassPermission "groovy.lang.Script";
-  permission org.elasticsearch.script.ClassPermission "groovy.util.GroovyCollections";
-  permission org.elasticsearch.script.ClassPermission "org.codehaus.groovy.ast.builder.AstBuilderTransformation";
-  permission org.elasticsearch.script.ClassPermission "org.codehaus.groovy.reflection.ClassInfo";
-  permission org.elasticsearch.script.ClassPermission "org.codehaus.groovy.runtime.GStringImpl";
-  permission org.elasticsearch.script.ClassPermission "org.codehaus.groovy.runtime.powerassert.ValueRecorder";
-  permission org.elasticsearch.script.ClassPermission "org.codehaus.groovy.runtime.powerassert.AssertionRenderer";
-  permission org.elasticsearch.script.ClassPermission "org.codehaus.groovy.runtime.ScriptBytecodeAdapter";
-  permission org.elasticsearch.script.ClassPermission "org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation";
-  permission org.elasticsearch.script.ClassPermission "org.codehaus.groovy.vmplugin.v7.IndyInterface";
-  permission org.elasticsearch.script.ClassPermission "sun.reflect.ConstructorAccessorImpl";
-  permission org.elasticsearch.script.ClassPermission "sun.reflect.MethodAccessorImpl";
-  permission org.elasticsearch.script.ClassPermission "jdk.internal.reflect.ConstructorAccessorImpl";
-  permission org.elasticsearch.script.ClassPermission "jdk.internal.reflect.MethodAccessorImpl";
-
-  permission org.elasticsearch.script.ClassPermission "groovy.lang.Closure";
-  permission org.elasticsearch.script.ClassPermission "org.codehaus.groovy.runtime.GeneratedClosure";
-  permission org.elasticsearch.script.ClassPermission "groovy.lang.MetaClass";
-  permission org.elasticsearch.script.ClassPermission "groovy.lang.Range";
-  permission org.elasticsearch.script.ClassPermission "groovy.lang.Reference";
-};

+ 0 - 164
modules/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovyIndexedScriptTests.java

@@ -1,164 +0,0 @@
-/*
- * 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.script.groovy;
-
-import org.elasticsearch.ExceptionsHelper;
-import org.elasticsearch.action.index.IndexRequestBuilder;
-import org.elasticsearch.action.search.SearchResponse;
-import org.elasticsearch.common.bytes.BytesArray;
-import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.index.query.QueryBuilders;
-import org.elasticsearch.plugins.Plugin;
-import org.elasticsearch.script.Script;
-import org.elasticsearch.script.ScriptType;
-import org.elasticsearch.search.SearchHit;
-import org.elasticsearch.search.aggregations.AggregationBuilders;
-import org.elasticsearch.search.builder.SearchSourceBuilder;
-import org.elasticsearch.test.ESIntegTestCase;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutionException;
-
-import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
-import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.notNullValue;
-
-public class GroovyIndexedScriptTests extends ESIntegTestCase {
-    @Override
-    protected Collection<Class<? extends Plugin>> nodePlugins() {
-        return Collections.singleton(GroovyPlugin.class);
-    }
-
-    @Override
-    protected Settings nodeSettings(int nodeOrdinal) {
-        Settings.Builder builder = Settings.builder().put(super.nodeSettings(nodeOrdinal));
-        builder.put("script.engine.groovy.stored.update", "false");
-        builder.put("script.engine.groovy.stored.search", "true");
-        builder.put("script.engine.groovy.stored.aggs", "true");
-        builder.put("script.engine.groovy.inline.aggs", "false");
-        return builder.build();
-    }
-
-    public void testFieldIndexedScript()  throws ExecutionException, InterruptedException {
-        client().admin().cluster().preparePutStoredScript()
-                .setId("script1")
-                .setScriptLang(GroovyScriptEngineService.NAME)
-                .setSource(new BytesArray("{ \"script\" : \"2\"}"))
-                .get();
-        client().admin().cluster().preparePutStoredScript()
-                .setId("script2")
-                .setScriptLang(GroovyScriptEngineService.NAME)
-                .setSource(new BytesArray("{ \"script\" : \"factor * 2\"}"))
-                .get();
-
-        List<IndexRequestBuilder> builders = new ArrayList<>();
-        builders.add(client().prepareIndex("test", "scriptTest", "1").setSource("{\"theField\":\"foo\"}"));
-        builders.add(client().prepareIndex("test", "scriptTest", "2").setSource("{\"theField\":\"foo 2\"}"));
-        builders.add(client().prepareIndex("test", "scriptTest", "3").setSource("{\"theField\":\"foo 3\"}"));
-        builders.add(client().prepareIndex("test", "scriptTest", "4").setSource("{\"theField\":\"foo 4\"}"));
-        builders.add(client().prepareIndex("test", "scriptTest", "5").setSource("{\"theField\":\"bar\"}"));
-
-        indexRandom(true, builders);
-        Map<String, Object> script2Params = new HashMap<>();
-        script2Params.put("factor", 3);
-        SearchResponse searchResponse = client()
-                .prepareSearch()
-                .setSource(
-                        new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).size(1)
-                                .scriptField("test1",
-                                    new Script(ScriptType.STORED, GroovyScriptEngineService.NAME, "script1", Collections.emptyMap()))
-                                .scriptField("test2",
-                                    new Script(ScriptType.STORED, GroovyScriptEngineService.NAME, "script2", script2Params)))
-                .setIndices("test").setTypes("scriptTest").get();
-        assertHitCount(searchResponse, 5);
-        assertTrue(searchResponse.getHits().hits().length == 1);
-        SearchHit sh = searchResponse.getHits().getAt(0);
-        assertThat(sh.field("test1").getValue(), equalTo(2));
-        assertThat(sh.field("test2").getValue(), equalTo(6));
-    }
-
-    // Relates to #10397
-    public void testUpdateScripts() {
-        createIndex("test_index");
-        ensureGreen("test_index");
-        client().prepareIndex("test_index", "test_type", "1").setSource("{\"foo\":\"bar\"}").get();
-        flush("test_index");
-
-        int iterations = randomIntBetween(2, 11);
-        for (int i = 1; i < iterations; i++) {
-            assertAcked(client().admin().cluster().preparePutStoredScript()
-                    .setScriptLang(GroovyScriptEngineService.NAME)
-                    .setId("script1")
-                    .setSource(new BytesArray("{\"script\":\"" + i + "\"}")));
-            SearchResponse searchResponse = client()
-                    .prepareSearch()
-                    .setSource(
-                            new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).scriptField("test_field",
-                                    new Script(ScriptType.STORED, GroovyScriptEngineService.NAME, "script1", Collections.emptyMap())))
-                                            .setIndices("test_index")
-                    .setTypes("test_type").get();
-            assertHitCount(searchResponse, 1);
-            SearchHit sh = searchResponse.getHits().getAt(0);
-            assertThat(sh.field("test_field").getValue(), equalTo(i));
-        }
-    }
-
-    public void testDisabledUpdateIndexedScriptsOnly() {
-        assertAcked(client().admin().cluster().preparePutStoredScript()
-                .setScriptLang(GroovyScriptEngineService.NAME)
-                .setId("script1")
-                .setSource(new BytesArray("{\"script\":\"2\"}")));
-        client().prepareIndex("test", "scriptTest", "1").setSource("{\"theField\":\"foo\"}").get();
-        try {
-            client().prepareUpdate("test", "scriptTest", "1")
-                    .setScript(new Script(ScriptType.STORED, GroovyScriptEngineService.NAME, "script1", Collections.emptyMap())).get();
-            fail("update script should have been rejected");
-        } catch (Exception e) {
-            assertThat(e.getMessage(), containsString("failed to execute script"));
-            assertThat(ExceptionsHelper.detailedMessage(e),
-                    containsString("scripts of type [stored], operation [update] and lang [groovy] are disabled"));
-        }
-    }
-
-    public void testDisabledAggsDynamicScripts() {
-        //dynamic scripts don't need to be enabled for an indexed script to be indexed and later on executed
-        assertAcked(client().admin().cluster().preparePutStoredScript()
-                .setScriptLang(GroovyScriptEngineService.NAME)
-                .setId("script1")
-                .setSource(new BytesArray("{\"script\":\"2\"}")));
-        client().prepareIndex("test", "scriptTest", "1").setSource("{\"theField\":\"foo\"}").get();
-        refresh();
-        SearchResponse searchResponse = client()
-                .prepareSearch("test")
-                .setSource(
-                        new SearchSourceBuilder().aggregation(AggregationBuilders.terms("test").script(
-                                new Script(ScriptType.STORED, GroovyScriptEngineService.NAME, "script1", Collections.emptyMap())))).get();
-        assertHitCount(searchResponse, 1);
-        assertThat(searchResponse.getAggregations().get("test"), notNullValue());
-    }
-}

+ 0 - 156
modules/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovyScriptTests.java

@@ -1,156 +0,0 @@
-/*
- * 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.script.groovy;
-
-import org.elasticsearch.action.index.IndexRequestBuilder;
-import org.elasticsearch.action.search.SearchPhaseExecutionException;
-import org.elasticsearch.action.search.SearchResponse;
-import org.elasticsearch.common.lucene.search.function.CombineFunction;
-import org.elasticsearch.index.query.QueryBuilders;
-import org.elasticsearch.plugins.Plugin;
-import org.elasticsearch.script.Script;
-import org.elasticsearch.script.ScriptType;
-import org.elasticsearch.search.builder.SearchSourceBuilder;
-import org.elasticsearch.search.sort.ScriptSortBuilder.ScriptSortType;
-import org.elasticsearch.search.sort.SortBuilders;
-import org.elasticsearch.test.ESIntegTestCase;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE;
-import static org.elasticsearch.index.query.QueryBuilders.constantScoreQuery;
-import static org.elasticsearch.index.query.QueryBuilders.functionScoreQuery;
-import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
-import static org.elasticsearch.index.query.QueryBuilders.scriptQuery;
-import static org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders.scriptFunction;
-import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
-import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertOrderedSearchHits;
-import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchHits;
-import static org.hamcrest.Matchers.equalTo;
-
-/**
- * Various tests for Groovy scripting
- */
-// TODO: refactor into unit test or proper rest tests
-public class GroovyScriptTests extends ESIntegTestCase {
-    @Override
-    protected Collection<Class<? extends Plugin>> nodePlugins() {
-        return Collections.singleton(GroovyPlugin.class);
-    }
-
-    public void testGroovyBigDecimalTransformation() {
-        client().prepareIndex("test", "doc", "1").setSource("foo", 5).setRefreshPolicy(IMMEDIATE).get();
-
-        // Test that something that would usually be a BigDecimal is transformed into a Double
-        assertScript("def n = 1.23; assert n instanceof Double; return n;");
-        assertScript("def n = 1.23G; assert n instanceof Double; return n;");
-        assertScript("def n = BigDecimal.ONE; assert n instanceof BigDecimal; return n;");
-    }
-
-    public void assertScript(String scriptString) {
-        Script script = new Script(ScriptType.INLINE, GroovyScriptEngineService.NAME, scriptString, Collections.emptyMap());
-        SearchResponse resp = client().prepareSearch("test")
-                .setSource(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).sort(SortBuilders.
-                        scriptSort(script, ScriptSortType.NUMBER)))
-                .get();
-        assertNoFailures(resp);
-    }
-
-    public void testGroovyExceptionSerialization() throws Exception {
-        List<IndexRequestBuilder> reqs = new ArrayList<>();
-        for (int i = 0; i < randomIntBetween(50, 500); i++) {
-            reqs.add(client().prepareIndex("test", "doc", "" + i).setSource("foo", "bar"));
-        }
-        indexRandom(true, false, reqs);
-        try {
-            client().prepareSearch("test")
-                    .setQuery(
-                            constantScoreQuery(scriptQuery(new Script(ScriptType.INLINE, GroovyScriptEngineService.NAME, "1 == not_found",
-                                Collections.emptyMap())))).get();
-            fail("should have thrown an exception");
-        } catch (SearchPhaseExecutionException e) {
-            assertThat(e.toString()+ "should not contained NotSerializableTransportException",
-                    e.toString().contains("NotSerializableTransportException"), equalTo(false));
-            assertThat(e.toString()+ "should have contained ScriptException",
-                    e.toString().contains("ScriptException"), equalTo(true));
-            assertThat(e.toString()+ "should have contained not_found",
-                    e.toString().contains("No such property: not_found"), equalTo(true));
-        }
-
-        try {
-            client().prepareSearch("test")
-                    .setQuery(constantScoreQuery(scriptQuery(
-                            new Script(ScriptType.INLINE, GroovyScriptEngineService.NAME, "null.foo", Collections.emptyMap())))).get();
-            fail("should have thrown an exception");
-        } catch (SearchPhaseExecutionException e) {
-            assertThat(e.toString() + "should not contained NotSerializableTransportException",
-                    e.toString().contains("NotSerializableTransportException"), equalTo(false));
-            assertThat(e.toString() + "should have contained ScriptException",
-                    e.toString().contains("ScriptException"), equalTo(true));
-            assertThat(e.toString()+ "should have contained a NullPointerException",
-                    e.toString().contains("NullPointerException[Cannot get property 'foo' on null object]"), equalTo(true));
-        }
-    }
-
-    public void testGroovyScriptAccess() {
-        client().prepareIndex("test", "doc", "1").setSource("foo", "quick brow fox jumped over the lazy dog", "bar", 1).get();
-        client().prepareIndex("test", "doc", "2").setSource("foo", "fast jumping spiders", "bar", 2).get();
-        client().prepareIndex("test", "doc", "3").setSource("foo", "dog spiders that can eat a dog", "bar", 3).get();
-        refresh();
-
-        // doc[] access
-        SearchResponse resp = client().prepareSearch("test").setQuery(functionScoreQuery(scriptFunction(
-                new Script(ScriptType.INLINE, GroovyScriptEngineService.NAME, "doc['bar'].value", Collections.emptyMap())))
-                        .boostMode(CombineFunction.REPLACE)).get();
-
-        assertNoFailures(resp);
-        assertOrderedSearchHits(resp, "3", "2", "1");
-    }
-
-    public void testScoreAccess() {
-        client().prepareIndex("test", "doc", "1").setSource("foo", "quick brow fox jumped over the lazy dog", "bar", 1).get();
-        client().prepareIndex("test", "doc", "2").setSource("foo", "fast jumping spiders", "bar", 2).get();
-        client().prepareIndex("test", "doc", "3").setSource("foo", "dog spiders that can eat a dog", "bar", 3).get();
-        refresh();
-
-        // _score can be accessed
-        SearchResponse resp = client().prepareSearch("test").setQuery(functionScoreQuery(matchQuery("foo", "dog"),
-                scriptFunction(new Script(ScriptType.INLINE, GroovyScriptEngineService.NAME, "_score", Collections.emptyMap())))
-            .boostMode(CombineFunction.REPLACE)).get();
-        assertNoFailures(resp);
-        assertSearchHits(resp, "3", "1");
-
-        // _score is comparable
-        // NOTE: it is important to use 0.0 instead of 0 instead Groovy will do an integer comparison
-        // and if the score if between 0 and 1 it will be considered equal to 0 due to the cast
-        resp = client()
-                .prepareSearch("test")
-                .setQuery(
-                        functionScoreQuery(matchQuery("foo", "dog"), scriptFunction(
-                                new Script(ScriptType.INLINE,
-                                    GroovyScriptEngineService.NAME, "_score > 0.0 ? _score : 0", Collections.emptyMap())))
-                                        .boostMode(CombineFunction.REPLACE)).get();
-        assertNoFailures(resp);
-        assertSearchHits(resp, "3", "1");
-    }
-}

+ 0 - 177
modules/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovySecurityTests.java

@@ -1,177 +0,0 @@
-/*
- * 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.script.groovy;
-
-import groovy.lang.MissingPropertyException;
-import org.apache.lucene.util.Constants;
-import org.codehaus.groovy.control.MultipleCompilationErrorsException;
-import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.script.CompiledScript;
-import org.elasticsearch.script.ScriptException;
-import org.elasticsearch.script.ScriptType;
-import org.elasticsearch.test.ESTestCase;
-
-import java.nio.file.Path;
-import java.security.PrivilegedActionException;
-import java.util.AbstractMap;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Tests for the Groovy security permissions
- */
-public class GroovySecurityTests extends ESTestCase {
-
-    private GroovyScriptEngineService se;
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        se = new GroovyScriptEngineService(Settings.EMPTY);
-        // otherwise will exit your VM and other bad stuff
-        assumeTrue("test requires security manager to be enabled", System.getSecurityManager() != null);
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        se.close();
-        super.tearDown();
-    }
-
-    public void testEvilGroovyScripts() throws Exception {
-        // Plain test
-        assertSuccess("");
-        // field access (via map)
-        assertSuccess("def foo = doc['foo'].value; if (foo == null) { return 5; }");
-        // field access (via list)
-        assertSuccess("def foo = mylist[0]; if (foo == null) { return 5; }");
-        // field access (via array)
-        assertSuccess("def foo = myarray[0]; if (foo == null) { return 5; }");
-        // field access (via object)
-        assertSuccess("def foo = myobject.primitive.toString(); if (foo == null) { return 5; }");
-        assertSuccess("def foo = myobject.object.toString(); if (foo == null) { return 5; }");
-        assertSuccess("def foo = myobject.list[0].primitive.toString(); if (foo == null) { return 5; }");
-        // List
-        assertSuccess("def list = [doc['foo'].value, 3, 4]; def v = list.get(1); list.add(10)");
-        // Ranges
-        assertSuccess("def range = 1..doc['foo'].value; def v = range.get(0)");
-        // Maps
-        assertSuccess("def v = doc['foo'].value; def m = [:]; m.put(\"value\", v)");
-        // Times
-        assertSuccess("def t = Instant.now().getMillis()");
-        // GroovyCollections
-        assertSuccess("def n = [1,2,3]; GroovyCollections.max(n)");
-        // Groovy closures
-        assertSuccess("[1, 2, 3, 4].findAll { it % 2 == 0 }");
-        assertSuccess("def buckets=[ [2, 4, 6, 8], [10, 12, 16, 14], [18, 22, 20, 24] ]; buckets[-3..-1].every { it.every { i -> i % 2 == 0 } }");
-        assertSuccess("def val = \"\"; [1, 2, 3, 4].each { val += it }; val");
-        // Groovy uses reflection to invoke closures. These reflective calls are optimized by the JVM after "sun.reflect.inflationThreshold"
-        // invocations. After the inflation step, access to sun.reflect.MethodAccessorImpl is required from the security manager. This test,
-        // assuming a inflation threshold below 100 (15 is current value on Oracle JVMs), checks that the relevant permission is available.
-        assertSuccess("(1..100).collect{ it + 1 }");
-
-        // Fail cases:
-        assertFailure("pr = Runtime.getRuntime().exec(\"touch /tmp/gotcha\"); pr.waitFor()", MissingPropertyException.class);
-
-        // infamous:
-        assertFailure("java.lang.Math.class.forName(\"java.lang.Runtime\")", PrivilegedActionException.class);
-        // filtered directly by our classloader
-        assertFailure("getClass().getClassLoader().loadClass(\"java.lang.Runtime\").availableProcessors()", PrivilegedActionException.class);
-        // unfortunately, we have access to other classloaders (due to indy mechanism needing getClassLoader permission)
-        // but we can't do much with them directly at least.
-        assertFailure("myobject.getClass().getClassLoader().loadClass(\"java.lang.Runtime\").availableProcessors()", SecurityException.class);
-        assertFailure("d = new DateTime(); d.getClass().getDeclaredMethod(\"year\").setAccessible(true)", SecurityException.class);
-        assertFailure("d = new DateTime(); d.\"${'get' + 'Class'}\"()." +
-                        "\"${'getDeclared' + 'Method'}\"(\"year\").\"${'set' + 'Accessible'}\"(false)", SecurityException.class);
-        assertFailure("Class.forName(\"org.joda.time.DateTime\").getDeclaredMethod(\"year\").setAccessible(true)", MissingPropertyException.class);
-
-        assertFailure("Eval.me('2 + 2')", MissingPropertyException.class);
-        assertFailure("Eval.x(5, 'x + 2')", MissingPropertyException.class);
-
-        assertFailure("d = new Date(); java.lang.reflect.Field f = Date.class.getDeclaredField(\"fastTime\");" +
-                " f.setAccessible(true); f.get(\"fastTime\")", MultipleCompilationErrorsException.class);
-
-        assertFailure("def methodName = 'ex'; Runtime.\"${'get' + 'Runtime'}\"().\"${methodName}ec\"(\"touch /tmp/gotcha2\")", MissingPropertyException.class);
-
-        assertFailure("t = new Thread({ println 3 });", MultipleCompilationErrorsException.class);
-
-        // test a directory we normally have access to, but the groovy script does not.
-        Path dir = createTempDir();
-        // TODO: figure out the necessary escaping for windows paths here :)
-        if (!Constants.WINDOWS) {
-            assertFailure("new File(\"" + dir + "\").exists()", MultipleCompilationErrorsException.class);
-        }
-    }
-
-    public void testGroovyScriptsThatThrowErrors() throws Exception {
-        assertFailure("assert false, \"msg\";", AssertionError.class);
-        assertFailure("def foo=false; assert foo;", AssertionError.class);
-        // Groovy's asserts require org.codehaus.groovy.runtime.InvokerHelper, so they are denied
-        assertFailure("def foo=false; assert foo, \"msg2\";", NoClassDefFoundError.class);
-    }
-
-    public void testGroovyBugError() {
-        // this script throws a GroovyBugError because our security manager permissions prevent Groovy from accessing this private field
-        // and Groovy does not handle it gracefully; this test will likely start failing if the bug is fixed upstream so that a
-        // GroovyBugError no longer surfaces here in which case the script should be replaced with another script that intentionally
-        // surfaces a GroovyBugError
-        assertFailure("[1, 2].size", AssertionError.class);
-    }
-
-    /** runs a script */
-    private void doTest(String script) {
-        Map<String, Object> vars = new HashMap<String, Object>();
-        // we add a "mock document" containing a single field "foo" that returns 4 (abusing a jdk class with a getValue() method)
-        vars.put("doc", Collections.singletonMap("foo", new AbstractMap.SimpleEntry<Object,Integer>(null, 4)));
-        vars.put("mylist", Arrays.asList("foo"));
-        vars.put("myarray", Arrays.asList("foo"));
-        vars.put("myobject", new MyObject());
-
-        se.executable(new CompiledScript(ScriptType.INLINE, "test", "js", se.compile(null, script, Collections.emptyMap())), vars).run();
-    }
-
-    public static class MyObject {
-        public int getPrimitive() { return 0; }
-        public Object getObject() { return "value"; }
-        public List<Object> getList() { return Arrays.asList(new MyObject()); }
-    }
-
-    /** asserts that a script runs without exception */
-    private void assertSuccess(String script) {
-        doTest(script);
-    }
-
-    /** asserts that a script triggers the given exceptionclass */
-    private void assertFailure(String script, Class<? extends Throwable> exceptionClass) {
-        try {
-            doTest(script);
-            fail("did not get expected exception");
-        } catch (ScriptException expected) {
-            Throwable cause = expected.getCause();
-            assertNotNull(cause);
-            if (exceptionClass.isAssignableFrom(cause.getClass()) == false) {
-                throw new AssertionError("unexpected exception: " + cause, expected);
-            }
-        }
-    }
-}

+ 0 - 42
modules/lang-groovy/src/test/java/org/elasticsearch/script/groovy/LangGroovyClientYamlTestSuiteIT.java

@@ -1,42 +0,0 @@
-/*
- * 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.script.groovy;
-
-import com.carrotsearch.randomizedtesting.annotations.Name;
-import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
-
-import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
-import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
-import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
-
-import java.io.IOException;
-
-public class LangGroovyClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
-
-    public LangGroovyClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
-        super(testCandidate);
-    }
-
-    @ParametersFactory
-    public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
-        return ESClientYamlSuiteTestCase.createParameters();
-    }
-}
-

+ 0 - 13
modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/10_basic.yaml

@@ -1,13 +0,0 @@
-# Integration tests for Groovy scripts
-#
-"Groovy loaded":
-    - do:
-        cluster.state: {}
-
-    # Get master node id
-    - set: { master_node: master }
-
-    - do:
-        nodes.info: {}
-
-    - match:  { nodes.$master.modules.0.name: lang-groovy  }

+ 0 - 87
modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/15_update.yaml

@@ -1,87 +0,0 @@
----
-"Update Script":
-
-  - skip:
-      features: groovy_scripting
-
-  - do:
-      index:
-          index:  test_1
-          type:   test
-          id:     1
-          body:
-              foo:    bar
-              count:  1
-
-  - do:
-      update:
-          index:  test_1
-          type:   test
-          id:     1
-          body:
-            script:
-              lang:   groovy
-              inline: "ctx._source.foo = bar"
-              params: { bar: 'xxx' }
-
-  - match: { _index:   test_1 }
-  - match: { _type:    test   }
-  - match: { _id:      "1"    }
-  - match: { _version: 2      }
-
-  - do:
-      get:
-          index:  test_1
-          type:   test
-          id:     1
-
-  - match: { _source.foo:        xxx }
-  - match: { _source.count:      1   }
-
-  - do:
-      update:
-          index:  test_1
-          type:   test
-          id:     1
-          body:
-            script:
-              lang:   groovy
-              inline: "ctx._source.foo = 'yyy'"
-
-  - match: { _index:   test_1 }
-  - match: { _type:    test   }
-  - match: { _id:      "1"    }
-  - match: { _version: 3      }
-
-  - do:
-      get:
-          index:  test_1
-          type:   test
-          id:     1
-
-  - match: { _source.foo:        yyy }
-  - match: { _source.count:      1   }
-
-  - do:
-      catch:      /script_lang not supported \[doesnotexist\]/
-      update:
-          index:  test_1
-          type:   test
-          id:     1
-          body:
-            script:
-              inline: "1"
-              lang:   "doesnotexist"
-              params: { bar: 'xxx' }
-
-  - do:
-      catch:      /script_lang not supported \[doesnotexist\]/
-      update:
-          index:  test_1
-          type:   test
-          id:     1
-          body:
-            script:
-                lang:   doesnotexist
-                inline: "1"
-

+ 0 - 73
modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/16_update2.yaml

@@ -1,73 +0,0 @@
----
-"Indexed script":
-
-  - skip:
-      features: groovy_scripting
-
-  - do:
-      put_script:
-        id: "1"
-        lang: "groovy"
-        body: { "script":  "_score * doc[\"myParent.weight\"].value" }
-  - match: { acknowledged: true }
-
-  - do:
-     get_script:
-       id: "1"
-       lang: "groovy"
-  - match: { found: true }
-  - match: { lang: groovy }
-  - match: { _id: "1" }
-  - match: { "script":  "_score * doc[\"myParent.weight\"].value" }
-
-  - do:
-     catch: missing
-     get_script:
-       id: "2"
-       lang: "groovy"
-  - match: { found: false }
-  - match: { lang: groovy }
-  - match: { _id: "2" }
-  - is_false: script
-
-  - do:
-     delete_script:
-       id: "1"
-       lang: "groovy"
-  - match: { acknowledged: true }
-
-  - do:
-     catch: missing
-     delete_script:
-       id: "non_existing"
-       lang: "groovy"
-
-  - do:
-      catch: request
-      put_script:
-        id: "1"
-        lang: "groovy"
-        body: { "script":  "_score * foo bar + doc[\"myParent.weight\"].value" }
-
-
-  - do:
-      catch: /script_exception,.+Error.compiling.script.*/
-      put_script:
-        id: "1"
-        lang: "groovy"
-        body: { "script":  "_score * foo bar + doc[\"myParent.weight\"].value" }
-
-  - do:
-      catch: request
-      put_script:
-        id: "1"
-        lang: "foobar"
-        body: { "script" :  "_score * doc[\"myParent.weight\"].value" }
-
-  - do:
-      catch: /script_lang.not.supported/
-      put_script:
-        id: "1"
-        lang: "foobar"
-        body: { "script" :  "_score * doc[\"myParent.weight\"].value" }
-

+ 0 - 69
modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/25_script_upsert.yaml

@@ -1,69 +0,0 @@
----
-"Script upsert":
-
-  - skip:
-      features: groovy_scripting
-
-  - do:
-      update:
-          index:    test_1
-          type:     test
-          id:       1
-          body:
-            script:
-              inline: "ctx._source.foo = bar"
-              params: { bar: 'xxx' }
-              lang: "groovy"
-            upsert: { foo: baz }
-
-  - do:
-      get:
-          index:  test_1
-          type:   test
-          id:     1
-
-  - match:  { _source.foo: baz }
-
-
-  - do:
-      update:
-          index:    test_1
-          type:     test
-          id:       1
-          body:
-            script:
-              inline: "ctx._source.foo = bar"
-              params: { bar: 'xxx' }
-              lang: "groovy"
-            upsert: { foo: baz }
-
-  - do:
-      get:
-          index:  test_1
-          type:   test
-          id:     1
-
-  - match:  { _source.foo: xxx }
-
-  - do:
-      update:
-          index:    test_1
-          type:     test
-          id:       2
-          body:
-            script:
-              inline: "ctx._source.foo = bar"
-              params: { bar: 'xxx' }
-              lang: "groovy"
-            upsert: { foo: baz }
-            scripted_upsert: true
-
-  - do:
-      get:
-          index:  test_1
-          type:   test
-          id:     2
-
-  - match:  { _source.foo: xxx }
-
-

+ 0 - 72
modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/30_compile_limit.yaml

@@ -1,72 +0,0 @@
-setup:
-  - do:
-      indices.create:
-          index:  test
-  - do:
-      index:
-          index:  test
-          type:   test
-          id:     1
-          body:   { foo: bar }
-          refresh: wait_for
-
----
-teardown:
-  - do:
-      cluster.put_settings:
-        body:
-          transient:
-            script.max_compilations_per_minute: null
-
----
-"circuit breaking with too many scripts":
-
-  - do:
-      cluster.put_settings:
-        body:
-          transient:
-            script.max_compilations_per_minute: 1
-
-  - do:
-      search:
-        index: test
-        type:  test
-        body:
-          size: 1
-          script_fields:
-            myfield:
-              script:
-                inline: "\"aoeu\""
-                lang: groovy
-
-  - match: { hits.total: 1 }
-
-  - do:
-      catch: /Too many dynamic script compilations within one minute/
-      search:
-        index: test
-        type:  test
-        body:
-          size: 1
-          script_fields:
-            myfield:
-              script:
-                inline: "\"aoeuaoeu\""
-                lang: groovy
-
----
-"no bad settings":
-
-  - do:
-      catch: /Failed to parse value \[-1\] for setting \[script.max_compilations_per_minute\] must be >= 0/
-      cluster.put_settings:
-        body:
-          transient:
-            script.max_compilations_per_minute: -1
-
-  - do:
-      catch: /Failed to parse value \[99999999999\] for setting \[script.max_compilations_per_minute\]/
-      cluster.put_settings:
-        body:
-          transient:
-            script.max_compilations_per_minute: 99999999999

+ 0 - 48
modules/lang-groovy/src/test/resources/rest-api-spec/test/lang_groovy/90_missing.yaml

@@ -1,48 +0,0 @@
----
-"Missing document (partial doc)":
-
-  - do:
-      catch:      missing
-      update:
-          index:  test_1
-          type:   test
-          id:     1
-          body:   { doc: { foo: bar } }
-
-  - do:
-      update:
-          index: test_1
-          type:  test
-          id:    1
-          body:  { doc: { foo: bar } }
-          ignore: 404
-
----
-"Missing document (script)":
-
-  - skip:
-      features: groovy_scripting
-
-
-  - do:
-      catch:      missing
-      update:
-          index:  test_1
-          type:   test
-          id:     1
-          body:
-            script:
-              inline: "ctx._source.foo = bar"
-              params: { bar: 'xxx' }
-              lang: "groovy"
-
-  - do:
-      update:
-          index:  test_1
-          type:   test
-          id:     1
-          ignore: 404
-          body:
-            script:
-              inline:       "ctx._source.foo = bar"
-              params:       { bar: 'xxx' }

+ 1 - 1
modules/percolator/src/main/java/org/elasticsearch/percolator/PercolateQueryBuilder.java

@@ -521,7 +521,7 @@ public class PercolateQueryBuilder extends AbstractQueryBuilder<PercolateQueryBu
                             currentFieldName = sourceParser.currentName();
                         } else if (token == XContentParser.Token.START_OBJECT) {
                             if ("query".equals(currentFieldName)) {
-                                QueryParseContext queryParseContext = context.newParseContextWithLegacyScriptLanguage(sourceParser);
+                                QueryParseContext queryParseContext = context.newParseContext(sourceParser);
                                 return parseQuery(context, mapUnmappedFieldsAsString, queryParseContext, sourceParser);
                             } else {
                                 sourceParser.skipChildren();

+ 0 - 173
modules/percolator/src/test/java/org/elasticsearch/percolator/PercolatorBackwardsCompatibilityTests.java

@@ -1,173 +0,0 @@
-/*
- * 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.percolator;
-
-import org.apache.lucene.util.LuceneTestCase;
-import org.apache.lucene.util.TestUtil;
-import org.elasticsearch.Version;
-import org.elasticsearch.action.get.GetResponse;
-import org.elasticsearch.action.search.SearchResponse;
-import org.elasticsearch.cluster.ClusterState;
-import org.elasticsearch.cluster.metadata.MappingMetaData;
-import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.common.xcontent.support.XContentMapValues;
-import org.elasticsearch.env.Environment;
-import org.elasticsearch.plugins.Plugin;
-import org.elasticsearch.script.MockScriptPlugin;
-import org.elasticsearch.search.sort.SortOrder;
-import org.elasticsearch.test.ESIntegTestCase;
-
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.function.Function;
-
-import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
-import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
-import static org.elasticsearch.index.query.QueryBuilders.scriptQuery;
-import static org.elasticsearch.percolator.PercolatorTestUtil.preparePercolate;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.hamcrest.Matchers.nullValue;
-
-@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0, numClientNodes = 0)
-@LuceneTestCase.SuppressFileSystems("ExtrasFS")
-// Can'r run as IT as the test cluster is immutable and this test adds nodes during the test
-public class PercolatorBackwardsCompatibilityTests extends ESIntegTestCase {
-
-    private static final String INDEX_NAME = "percolator_index";
-
-    @Override
-    protected Collection<Class<? extends Plugin>> nodePlugins() {
-        return Arrays.asList(PercolatorPlugin.class, FoolMeScriptLang.class);
-    }
-
-    @Override
-    protected Collection<Class<? extends Plugin>> transportClientPlugins() {
-        return Collections.singleton(PercolatorPlugin.class);
-    }
-
-    public void testOldPercolatorIndex() throws Exception {
-        setupNode();
-
-        // verify cluster state:
-        ClusterState state = client().admin().cluster().prepareState().get().getState();
-        assertThat(state.metaData().indices().size(), equalTo(1));
-        assertThat(state.metaData().indices().get(INDEX_NAME), notNullValue());
-        assertThat(state.metaData().indices().get(INDEX_NAME).getCreationVersion(), equalTo(Version.V_2_0_0));
-        assertThat(state.metaData().indices().get(INDEX_NAME).getUpgradedVersion(), equalTo(Version.CURRENT));
-        assertThat(state.metaData().indices().get(INDEX_NAME).getMappings().size(), equalTo(2));
-        assertThat(state.metaData().indices().get(INDEX_NAME).getMappings().get(".percolator"), notNullValue());
-        // important: verify that the query field in the .percolator mapping is of type object (from 5.x this is of type percolator)
-        MappingMetaData mappingMetaData = state.metaData().indices().get(INDEX_NAME).getMappings().get(".percolator");
-        assertThat(XContentMapValues.extractValue("properties.query.type", mappingMetaData.sourceAsMap()), equalTo("object"));
-        assertThat(state.metaData().indices().get(INDEX_NAME).getMappings().get("message"), notNullValue());
-
-        // verify existing percolator queries:
-        SearchResponse searchResponse = client().prepareSearch(INDEX_NAME)
-            .setTypes(".percolator")
-            .addSort("_uid", SortOrder.ASC)
-            .get();
-        assertThat(searchResponse.getHits().getTotalHits(), equalTo(4L));
-        assertThat(searchResponse.getHits().getAt(0).id(), equalTo("1"));
-        assertThat(searchResponse.getHits().getAt(1).id(), equalTo("2"));
-        assertThat(searchResponse.getHits().getAt(2).id(), equalTo("3"));
-        assertThat(searchResponse.getHits().getAt(3).id(), equalTo("4"));
-        assertThat(XContentMapValues.extractValue("query.script.script.inline",
-                searchResponse.getHits().getAt(3).sourceAsMap()), equalTo("return true"));
-        // we don't upgrade the script definitions so that they include explicitly the lang,
-        // because we read / parse the query at search time.
-        assertThat(XContentMapValues.extractValue("query.script.script.lang",
-                searchResponse.getHits().getAt(3).sourceAsMap()), nullValue());
-
-        // verify percolate response
-        PercolateResponse percolateResponse = preparePercolate(client())
-                .setIndices(INDEX_NAME)
-                .setDocumentType("message")
-                .setPercolateDoc(new PercolateSourceBuilder.DocBuilder().setDoc("{}"))
-                .get();
-
-        assertThat(percolateResponse.getCount(), equalTo(1L));
-        assertThat(percolateResponse.getMatches().length, equalTo(1));
-        assertThat(percolateResponse.getMatches()[0].getId().string(), equalTo("4"));
-
-        percolateResponse = preparePercolate(client())
-            .setIndices(INDEX_NAME)
-            .setDocumentType("message")
-            .setPercolateDoc(new PercolateSourceBuilder.DocBuilder().setDoc("message", "the quick brown fox jumps over the lazy dog"))
-            .get();
-
-        assertThat(percolateResponse.getCount(), equalTo(3L));
-        assertThat(percolateResponse.getMatches().length, equalTo(3));
-        assertThat(percolateResponse.getMatches()[0].getId().string(), equalTo("1"));
-        assertThat(percolateResponse.getMatches()[1].getId().string(), equalTo("2"));
-        assertThat(percolateResponse.getMatches()[2].getId().string(), equalTo("4"));
-
-        // add an extra query and verify the results
-        client().prepareIndex(INDEX_NAME, ".percolator", "5")
-            .setSource(jsonBuilder().startObject().field("query", matchQuery("message", "fox jumps")).endObject())
-            .get();
-        refresh();
-
-        percolateResponse = preparePercolate(client())
-            .setIndices(INDEX_NAME)
-            .setDocumentType("message")
-            .setPercolateDoc(new PercolateSourceBuilder.DocBuilder().setDoc("message", "the quick brown fox jumps over the lazy dog"))
-            .get();
-
-        assertThat(percolateResponse.getCount(), equalTo(4L));
-        assertThat(percolateResponse.getMatches().length, equalTo(4));
-        assertThat(percolateResponse.getMatches()[0].getId().string(), equalTo("1"));
-        assertThat(percolateResponse.getMatches()[1].getId().string(), equalTo("2"));
-        assertThat(percolateResponse.getMatches()[2].getId().string(), equalTo("4"));
-    }
-
-    private void setupNode() throws Exception {
-        Path clusterDir = createTempDir();
-        try (InputStream stream = PercolatorBackwardsCompatibilityTests.class.
-                getResourceAsStream("/indices/percolator/bwc_index_2.0.0.zip")) {
-            TestUtil.unzip(stream, clusterDir);
-        }
-
-        Settings.Builder nodeSettings = Settings.builder()
-            .put(Environment.PATH_DATA_SETTING.getKey(), clusterDir);
-        internalCluster().startNode(nodeSettings.build());
-        ensureGreen(INDEX_NAME);
-    }
-
-    // Fool the script service that this is the groovy script language,
-    // so that we can run a script that has no lang defined implicetely against the legacy language:
-    public static class FoolMeScriptLang extends MockScriptPlugin {
-
-        @Override
-        protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
-            return Collections.singletonMap("return true", (vars) -> true);
-        }
-
-        @Override
-        public String pluginScriptLang() {
-            return "groovy";
-        }
-    }
-
-}

+ 1 - 1
modules/reindex/src/test/java/org/elasticsearch/index/reindex/SimpleExecutableScript.java

@@ -59,7 +59,7 @@ public class SimpleExecutableScript implements ExecutableScript {
                 return new HashMap<>((Map<?, ?>) value);
             }
         }
-        // Others just return the objects plain (groovy, painless)
+        // Others just return the objects plain (painless)
         return value;
     }
 }

+ 1 - 1
qa/evil-tests/src/test/java/org/elasticsearch/plugins/InstallPluginCommandTests.java

@@ -372,7 +372,7 @@ public class InstallPluginCommandTests extends ESTestCase {
     public void testBuiltinModule() throws Exception {
         Tuple<Path, Environment> env = createEnv(fs, temp);
         Path pluginDir = createPluginDir(temp);
-        String pluginZip = createPlugin("lang-groovy", pluginDir);
+        String pluginZip = createPlugin("lang-painless", pluginDir);
         UserException e = expectThrows(UserException.class, () -> installPlugin(pluginZip, env.v1()));
         assertTrue(e.getMessage(), e.getMessage().contains("is a system module"));
         assertInstallCleaned(env.v2());

+ 1 - 1
rest-api-spec/src/main/resources/rest-api-spec/api/update.json

@@ -45,7 +45,7 @@
         },
         "lang": {
           "type": "string",
-          "description": "The script language (default: groovy)"
+          "description": "The script language (default: painless)"
         },
         "parent": {
           "type": "string",

+ 0 - 1
settings.gradle

@@ -24,7 +24,6 @@ List projects = [
   'modules:aggs-matrix-stats',
   'modules:ingest-common',
   'modules:lang-expression',
-  'modules:lang-groovy',
   'modules:lang-mustache',
   'modules:lang-painless',
   'modules:transport-netty4',

+ 0 - 1
test/framework/src/main/java/org/elasticsearch/test/rest/yaml/Features.java

@@ -38,7 +38,6 @@ public final class Features {
     private static final List<String> SUPPORTED = unmodifiableList(Arrays.asList(
             "catch_unauthorized",
             "embedded_stash_key",
-            "groovy_scripting",
             "headers",
             "stash_in_path",
             "warnings",