Browse Source

Merge pull request ESQL-1050 from elastic/main

🤖 ESQL: Merge upstream
elasticsearchmachine 2 years ago
parent
commit
28b4d081cb
43 changed files with 237 additions and 323 deletions
  1. 1 0
      build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/InternalDistributionModuleCheckTaskProvider.java
  2. 0 30
      modules/aggregations/src/yamlRestTest/resources/rest-api-spec/test/aggregations/composite.yml
  3. 1 33
      modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/IngestCommonPlugin.java
  4. 3 0
      modules/lang-painless/src/main/java/org/elasticsearch/painless/action/PainlessExecuteAction.java
  5. 0 1
      plugins/discovery-azure-classic/build.gradle
  6. 0 202
      plugins/discovery-azure-classic/licenses/commons-io-LICENSE.txt
  7. 0 5
      plugins/discovery-azure-classic/licenses/commons-io-NOTICE.txt
  8. 2 1
      rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.sort/10_basic.yml
  9. 5 2
      rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/380_sort_segments_on_timestamp.yml
  10. 1 0
      server/build.gradle
  11. 1 0
      server/src/main/java/module-info.java
  12. 3 0
      server/src/main/java/org/elasticsearch/action/search/RestClosePointInTimeAction.java
  13. 3 0
      server/src/main/java/org/elasticsearch/action/search/RestOpenPointInTimeAction.java
  14. 4 1
      server/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java
  15. 20 2
      server/src/main/java/org/elasticsearch/common/settings/LocallyMountedSecrets.java
  16. 20 4
      server/src/main/java/org/elasticsearch/ingest/IngestService.java
  17. 31 0
      server/src/main/java/org/elasticsearch/ingest/IngestSettings.java
  18. 6 2
      server/src/main/java/org/elasticsearch/ingest/Processor.java
  19. 2 1
      server/src/main/java/org/elasticsearch/node/Node.java
  20. 1 1
      server/src/main/java/org/elasticsearch/rest/action/RestMainAction.java
  21. 3 0
      server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetScriptContextAction.java
  22. 3 0
      server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetScriptLanguageAction.java
  23. 3 0
      server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestNodesHotThreadsAction.java
  24. 3 0
      server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestNodesInfoAction.java
  25. 3 0
      server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestAnalyzeIndexDiskUsageAction.java
  26. 3 0
      server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestDeleteComposableIndexTemplateAction.java
  27. 3 0
      server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetComposableIndexTemplateAction.java
  28. 3 0
      server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestPutComposableIndexTemplateAction.java
  29. 1 1
      server/src/test/java/org/elasticsearch/action/admin/indices/diskusage/IndexDiskUsageAnalyzerTests.java
  30. 2 1
      server/src/test/java/org/elasticsearch/action/ingest/ReservedPipelineActionTests.java
  31. 11 0
      server/src/test/java/org/elasticsearch/common/settings/LocallyMountedSecretsTests.java
  32. 18 6
      server/src/test/java/org/elasticsearch/ingest/IngestServiceTests.java
  33. 2 1
      server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java
  34. 0 4
      test/x-content/build.gradle
  35. 10 1
      x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/action/TransportGetTrainedModelsStatsActionTests.java
  36. 16 0
      x-pack/plugin/redact/build.gradle
  37. 34 0
      x-pack/plugin/redact/src/main/java/org/elasticsearch/xpack/redact/RedactPlugin.java
  38. 3 5
      x-pack/plugin/redact/src/main/java/org/elasticsearch/xpack/redact/RedactProcessor.java
  39. 3 5
      x-pack/plugin/redact/src/test/java/org/elasticsearch/xpack/redact/RedactProcessorFactoryTests.java
  40. 3 5
      x-pack/plugin/redact/src/test/java/org/elasticsearch/xpack/redact/RedactProcessorTests.java
  41. 0 0
      x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/redact/10_redact_processor.yml
  42. 4 6
      x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/spatial/20_cartesian_centroid.yml
  43. 2 3
      x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/spatial/20_geo_centroid.yml

+ 1 - 0
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/InternalDistributionModuleCheckTaskProvider.java

@@ -52,6 +52,7 @@ public class InternalDistributionModuleCheckTaskProvider {
         "org.elasticsearch.base",
         "org.elasticsearch.cli",
         "org.elasticsearch.geo",
+        "org.elasticsearch.grok",
         "org.elasticsearch.logging",
         "org.elasticsearch.lz4",
         "org.elasticsearch.plugin",

+ 0 - 30
modules/aggregations/src/yamlRestTest/resources/rest-api-spec/test/aggregations/composite.yml

@@ -342,36 +342,6 @@ setup:
   - match: { aggregations.test.buckets.2.key.histo: 1000}
   - match: { aggregations.test.buckets.2.doc_count: 1}
 ---
-"Basic numeric histogram legacy multivalue":
-  - skip:
-      version: " 8.4.0 - "
-      reason:  Multivalue Handling changed in 8.4
-  - do:
-      search:
-        rest_total_hits_as_int: true
-        index: test
-        body:
-          aggregations:
-            test:
-              composite:
-                sources: [
-                  "histo": {
-                    "histogram": {
-                      "field": "long",
-                      "interval": 50
-                    }
-                  }
-                ]
-
-  - match: {hits.total: 6}
-  - length: { aggregations.test.buckets: 3 }
-  - match: { aggregations.test.buckets.0.key.histo: 0}
-  - match: { aggregations.test.buckets.0.doc_count: 4}
-  - match: { aggregations.test.buckets.1.key.histo: 100}
-  - match: { aggregations.test.buckets.1.doc_count: 1}
-  - match: { aggregations.test.buckets.2.key.histo: 1000}
-  - match: { aggregations.test.buckets.2.doc_count: 1}
----
 "Basic numeric histogram with missing bucket":
   - skip:
       version: " - 8.3.99"

+ 1 - 33
modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/IngestCommonPlugin.java

@@ -14,11 +14,8 @@ import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
 import org.elasticsearch.cluster.node.DiscoveryNodes;
 import org.elasticsearch.common.settings.ClusterSettings;
 import org.elasticsearch.common.settings.IndexScopedSettings;
-import org.elasticsearch.common.settings.Setting;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.settings.SettingsFilter;
-import org.elasticsearch.core.TimeValue;
-import org.elasticsearch.grok.MatcherWatchdog;
 import org.elasticsearch.ingest.DropProcessor;
 import org.elasticsearch.ingest.PipelineProcessor;
 import org.elasticsearch.ingest.Processor;
@@ -36,22 +33,10 @@ import static java.util.Map.entry;
 
 public class IngestCommonPlugin extends Plugin implements ActionPlugin, IngestPlugin {
 
-    static final Setting<TimeValue> WATCHDOG_INTERVAL = Setting.timeSetting(
-        "ingest.grok.watchdog.interval",
-        TimeValue.timeValueSeconds(1),
-        Setting.Property.NodeScope
-    );
-    static final Setting<TimeValue> WATCHDOG_MAX_EXECUTION_TIME = Setting.timeSetting(
-        "ingest.grok.watchdog.max_execution_time",
-        TimeValue.timeValueSeconds(1),
-        Setting.Property.NodeScope
-    );
-
     public IngestCommonPlugin() {}
 
     @Override
     public Map<String, Processor.Factory> getProcessors(Processor.Parameters parameters) {
-        var matcherWatchdog = createGrokThreadWatchdog(parameters);
         return Map.ofEntries(
             entry(AppendProcessor.TYPE, new AppendProcessor.Factory(parameters.scriptService)),
             entry(BytesProcessor.TYPE, new BytesProcessor.Factory()),
@@ -66,7 +51,7 @@ public class IngestCommonPlugin extends Plugin implements ActionPlugin, IngestPl
             entry(FailProcessor.TYPE, new FailProcessor.Factory(parameters.scriptService)),
             entry(FingerprintProcessor.TYPE, new FingerprintProcessor.Factory()),
             entry(ForEachProcessor.TYPE, new ForEachProcessor.Factory(parameters.scriptService)),
-            entry(GrokProcessor.TYPE, new GrokProcessor.Factory(matcherWatchdog)),
+            entry(GrokProcessor.TYPE, new GrokProcessor.Factory(parameters.matcherWatchdog)),
             entry(GsubProcessor.TYPE, new GsubProcessor.Factory()),
             entry(HtmlStripProcessor.TYPE, new HtmlStripProcessor.Factory()),
             entry(JoinProcessor.TYPE, new JoinProcessor.Factory()),
@@ -75,7 +60,6 @@ public class IngestCommonPlugin extends Plugin implements ActionPlugin, IngestPl
             entry(LowercaseProcessor.TYPE, new LowercaseProcessor.Factory()),
             entry(NetworkDirectionProcessor.TYPE, new NetworkDirectionProcessor.Factory(parameters.scriptService)),
             entry(PipelineProcessor.TYPE, new PipelineProcessor.Factory(parameters.ingestService)),
-            entry(RedactProcessor.TYPE, new RedactProcessor.Factory(matcherWatchdog)),
             entry(RegisteredDomainProcessor.TYPE, new RegisteredDomainProcessor.Factory()),
             entry(RemoveProcessor.TYPE, new RemoveProcessor.Factory(parameters.scriptService)),
             entry(RenameProcessor.TYPE, new RenameProcessor.Factory(parameters.scriptService)),
@@ -109,20 +93,4 @@ public class IngestCommonPlugin extends Plugin implements ActionPlugin, IngestPl
         return List.of(new GrokProcessorGetAction.RestAction());
     }
 
-    @Override
-    public List<Setting<?>> getSettings() {
-        return List.of(WATCHDOG_INTERVAL, WATCHDOG_MAX_EXECUTION_TIME);
-    }
-
-    private static MatcherWatchdog createGrokThreadWatchdog(Processor.Parameters parameters) {
-        long intervalMillis = WATCHDOG_INTERVAL.get(parameters.env.settings()).getMillis();
-        long maxExecutionTimeMillis = WATCHDOG_MAX_EXECUTION_TIME.get(parameters.env.settings()).getMillis();
-        return MatcherWatchdog.newInstance(
-            intervalMillis,
-            maxExecutionTimeMillis,
-            parameters.relativeTimeSupplier,
-            parameters.scheduler::apply
-        );
-    }
-
 }

+ 3 - 0
modules/lang-painless/src/main/java/org/elasticsearch/painless/action/PainlessExecuteAction.java

@@ -60,6 +60,8 @@ import org.elasticsearch.indices.IndicesService;
 import org.elasticsearch.painless.spi.PainlessTestScript;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
+import org.elasticsearch.rest.Scope;
+import org.elasticsearch.rest.ServerlessScope;
 import org.elasticsearch.rest.action.RestToXContentListener;
 import org.elasticsearch.script.BooleanFieldScript;
 import org.elasticsearch.script.CompositeFieldScript;
@@ -721,6 +723,7 @@ public class PainlessExecuteAction extends ActionType<PainlessExecuteAction.Resp
         }
     }
 
+    @ServerlessScope(Scope.PUBLIC)
     public static class RestAction extends BaseRestHandler {
 
         @Override

+ 0 - 1
plugins/discovery-azure-classic/build.gradle

@@ -30,7 +30,6 @@ dependencies {
   api "org.apache.logging.log4j:log4j-1.2-api:${localVersions.log4j}"
   api "commons-codec:commons-codec:${localVersions.commonscodec}"
   api "commons-lang:commons-lang:2.6"
-  api "commons-io:commons-io:2.4"
   api 'javax.mail:mail:1.4.5'
   api 'javax.inject:javax.inject:1'
   api "com.sun.jersey:jersey-client:${localVersions.jersey}"

+ 0 - 202
plugins/discovery-azure-classic/licenses/commons-io-LICENSE.txt

@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   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
plugins/discovery-azure-classic/licenses/commons-io-NOTICE.txt

@@ -1,5 +0,0 @@
-Apache Commons IO
-Copyright 2002-2014 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).

+ 2 - 1
rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.sort/10_basic.yml

@@ -7,7 +7,7 @@
         body:
           settings:
             number_of_shards: 1
-            number_of_replicas: 0
+            refresh_interval: -1
             index.sort.field: rank
             # ensure no relocation as tests rely on segments.
             routing.rebalance.enable: "none"
@@ -19,6 +19,7 @@
       cluster.health:
         index: test
         # ensure that all shards are ready before indexing/refresh as tests rely on segments.
+        wait_for_events: languid
         wait_for_no_initializing_shards: true
   - do:
       index:

+ 5 - 2
rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/search/380_sort_segments_on_timestamp.yml

@@ -21,6 +21,7 @@
       cluster.health:
         index: test_index1
         # ensure that all shards are ready before indexing/refresh as we will verify segments.
+        wait_for_events: languid
         wait_for_no_initializing_shards: true
   # 1st segment
   - do:
@@ -49,7 +50,7 @@
 ---
 "Test that index segments are NOT sorted on timestamp field when @timestamp field is dynamically added":
   - skip:
-      version: " - " # Tracked at https://github.com/elastic/elasticsearch/issues/94357
+      version: " - 7.99.99"
       reason: "sorting segments was added in 7.16"
       features: allowed_warnings
 
@@ -65,6 +66,7 @@
       cluster.health:
         index: test_index2
         # ensure that all shards are ready before indexing/refresh as we will verify segments.
+        wait_for_events: languid
         wait_for_no_initializing_shards: true
   # 1st segment
   - do:
@@ -110,7 +112,7 @@
 ---
 "Test if segments are missing @timestamp field we don't get errors":
   - skip:
-      version: " - " # Tracked at https://github.com/elastic/elasticsearch/issues/94357
+      version: "- 7.99.99"
       reason: "sorting segments was added in 7.16"
       features: allowed_warnings
 
@@ -130,6 +132,7 @@
       cluster.health:
         index: test_index3
         # ensure that all shards are ready before indexing/refresh as we will verify segments.
+        wait_for_events: languid
         wait_for_no_initializing_shards: true
   # 1st segment missing @timestamp field
   - do:

+ 1 - 0
server/build.gradle

@@ -33,6 +33,7 @@ dependencies {
   api project(":libs:elasticsearch-lz4")
   api project(":libs:elasticsearch-plugin-api")
   api project(":libs:elasticsearch-plugin-analysis-api")
+  api project(':libs:elasticsearch-grok')
 
   implementation project(':libs:elasticsearch-plugin-classloader')
   // no compile dependency by server, but server defines security policy for this codebase so it i>

+ 1 - 0
server/src/main/java/module-info.java

@@ -27,6 +27,7 @@ module org.elasticsearch.server {
     requires org.elasticsearch.logging;
     requires org.elasticsearch.plugin;
     requires org.elasticsearch.plugin.analysis;
+    requires org.elasticsearch.grok;
 
     requires com.sun.jna;
     requires hppc;

+ 3 - 0
server/src/main/java/org/elasticsearch/action/search/RestClosePointInTimeAction.java

@@ -11,6 +11,8 @@ package org.elasticsearch.action.search;
 import org.elasticsearch.client.internal.node.NodeClient;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
+import org.elasticsearch.rest.Scope;
+import org.elasticsearch.rest.ServerlessScope;
 import org.elasticsearch.rest.action.RestStatusToXContentListener;
 import org.elasticsearch.xcontent.XContentParser;
 
@@ -19,6 +21,7 @@ import java.util.List;
 
 import static org.elasticsearch.rest.RestRequest.Method.DELETE;
 
+@ServerlessScope(Scope.PUBLIC)
 public class RestClosePointInTimeAction extends BaseRestHandler {
 
     @Override

+ 3 - 0
server/src/main/java/org/elasticsearch/action/search/RestOpenPointInTimeAction.java

@@ -14,6 +14,8 @@ import org.elasticsearch.common.Strings;
 import org.elasticsearch.core.TimeValue;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
+import org.elasticsearch.rest.Scope;
+import org.elasticsearch.rest.ServerlessScope;
 import org.elasticsearch.rest.action.RestToXContentListener;
 
 import java.io.IOException;
@@ -21,6 +23,7 @@ import java.util.List;
 
 import static org.elasticsearch.rest.RestRequest.Method.POST;
 
+@ServerlessScope(Scope.PUBLIC)
 public class RestOpenPointInTimeAction extends BaseRestHandler {
 
     @Override

+ 4 - 1
server/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java

@@ -90,6 +90,7 @@ import org.elasticsearch.indices.cluster.IndicesClusterStateService;
 import org.elasticsearch.indices.fielddata.cache.IndicesFieldDataCache;
 import org.elasticsearch.indices.recovery.RecoverySettings;
 import org.elasticsearch.indices.store.IndicesStore;
+import org.elasticsearch.ingest.IngestSettings;
 import org.elasticsearch.monitor.fs.FsHealthService;
 import org.elasticsearch.monitor.fs.FsService;
 import org.elasticsearch.monitor.jvm.JvmGcMonitorService;
@@ -570,7 +571,9 @@ public final class ClusterSettings extends AbstractScopedSettings {
         StatelessSecureSettings.STATELESS_SECURE_SETTINGS,
         DataLifecycle.isEnabled() ? DataLifecycle.CLUSTER_DLM_DEFAULT_ROLLOVER_SETTING : null,
         IndicesClusterStateService.SHARD_LOCK_RETRY_INTERVAL_SETTING,
-        IndicesClusterStateService.SHARD_LOCK_RETRY_TIMEOUT_SETTING
+        IndicesClusterStateService.SHARD_LOCK_RETRY_TIMEOUT_SETTING,
+        IngestSettings.GROK_WATCHDOG_INTERVAL,
+        IngestSettings.GROK_WATCHDOG_MAX_EXECUTION_TIME
     ).filter(Objects::nonNull).collect(Collectors.toSet());
 
     static List<SettingUpgrader<?>> BUILT_IN_SETTING_UPGRADERS = Collections.emptyList();

+ 20 - 2
server/src/main/java/org/elasticsearch/common/settings/LocallyMountedSecrets.java

@@ -76,8 +76,8 @@ public class LocallyMountedSecrets implements SecureSettings {
      * Direct constructor to be used by the CLI
      */
     public LocallyMountedSecrets(Environment environment) {
-        var secretsDirPath = environment.configFile().toAbsolutePath().resolve(SECRETS_DIRECTORY);
-        var secretsFilePath = secretsDirPath.resolve(SECRETS_FILE_NAME);
+        var secretsDirPath = resolveSecretsDir(environment);
+        var secretsFilePath = resolveSecretsFile(environment);
         secretsParser.declareObject(ConstructingObjectParser.constructorArg(), (p, c) -> p.map(), SECRETS_FIELD);
         secretsParser.declareObject(ConstructingObjectParser.constructorArg(), (p, c) -> ReservedStateVersion.parse(p), METADATA_FIELD);
         if (Files.exists(secretsDirPath) && Files.exists(secretsFilePath)) {
@@ -93,6 +93,24 @@ public class LocallyMountedSecrets implements SecureSettings {
         this.secretsFile = secretsFilePath.toString();
     }
 
+    /**
+     * Resolve a secrets directory path given an environment
+     * @param environment Elasticsearch environment
+     * @return Secrets directory within an Elasticsearch environment
+     */
+    public static Path resolveSecretsDir(Environment environment) {
+        return environment.configFile().toAbsolutePath().resolve(SECRETS_DIRECTORY);
+    }
+
+    /**
+     * Resolve a secure settings file path given an environment
+     * @param environment Elasticsearch environment
+     * @return Secure settings file within an Elasticsearch environment
+     */
+    public static Path resolveSecretsFile(Environment environment) {
+        return resolveSecretsDir(environment).resolve(SECRETS_FILE_NAME);
+    }
+
     /**
      * Used by {@link org.elasticsearch.bootstrap.ServerArgs} to deserialize the secrets
      * when they are received by the Elasticsearch process. The ServerCli code serializes

+ 20 - 4
server/src/main/java/org/elasticsearch/ingest/IngestService.java

@@ -53,12 +53,14 @@ import org.elasticsearch.core.TimeValue;
 import org.elasticsearch.core.Tuple;
 import org.elasticsearch.env.Environment;
 import org.elasticsearch.gateway.GatewayService;
+import org.elasticsearch.grok.MatcherWatchdog;
 import org.elasticsearch.index.IndexSettings;
 import org.elasticsearch.index.VersionType;
 import org.elasticsearch.index.analysis.AnalysisRegistry;
 import org.elasticsearch.node.ReportingService;
 import org.elasticsearch.plugins.IngestPlugin;
 import org.elasticsearch.script.ScriptService;
+import org.elasticsearch.threadpool.Scheduler;
 import org.elasticsearch.threadpool.ThreadPool;
 import org.elasticsearch.xcontent.XContentBuilder;
 
@@ -79,6 +81,7 @@ import java.util.Set;
 import java.util.TreeMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.IntConsumer;
 import java.util.function.Predicate;
@@ -111,6 +114,18 @@ public class IngestService implements ClusterStateApplier, ReportingService<Inge
     private final List<Consumer<ClusterState>> ingestClusterStateListeners = new CopyOnWriteArrayList<>();
     private volatile ClusterState state;
 
+    private static BiFunction<Long, Runnable, Scheduler.ScheduledCancellable> createScheduler(ThreadPool threadPool) {
+        return (delay, command) -> threadPool.schedule(command, TimeValue.timeValueMillis(delay), ThreadPool.Names.GENERIC);
+    }
+
+    public static MatcherWatchdog createGrokThreadWatchdog(Environment env, ThreadPool threadPool) {
+        final Settings settings = env.settings();
+        final BiFunction<Long, Runnable, Scheduler.ScheduledCancellable> scheduler = createScheduler(threadPool);
+        long intervalMillis = IngestSettings.GROK_WATCHDOG_INTERVAL.get(settings).getMillis();
+        long maxExecutionTimeMillis = IngestSettings.GROK_WATCHDOG_INTERVAL.get(settings).getMillis();
+        return MatcherWatchdog.newInstance(intervalMillis, maxExecutionTimeMillis, threadPool::relativeTimeInMillis, scheduler::apply);
+    }
+
     /**
      * Cluster state task executor for ingest pipeline operations
      */
@@ -161,7 +176,8 @@ public class IngestService implements ClusterStateApplier, ReportingService<Inge
         ScriptService scriptService,
         AnalysisRegistry analysisRegistry,
         List<IngestPlugin> ingestPlugins,
-        Client client
+        Client client,
+        MatcherWatchdog matcherWatchdog
     ) {
         this.clusterService = clusterService;
         this.scriptService = scriptService;
@@ -173,13 +189,13 @@ public class IngestService implements ClusterStateApplier, ReportingService<Inge
                 analysisRegistry,
                 threadPool.getThreadContext(),
                 threadPool::relativeTimeInMillis,
-                (delay, command) -> threadPool.schedule(command, TimeValue.timeValueMillis(delay), ThreadPool.Names.GENERIC),
+                createScheduler(threadPool),
                 this,
                 client,
-                threadPool.generic()::execute
+                threadPool.generic()::execute,
+                matcherWatchdog
             )
         );
-
         this.threadPool = threadPool;
         this.taskQueue = clusterService.createTaskQueue("ingest-pipelines", Priority.NORMAL, PIPELINE_TASK_EXECUTOR);
     }

+ 31 - 0
server/src/main/java/org/elasticsearch/ingest/IngestSettings.java

@@ -0,0 +1,31 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+package org.elasticsearch.ingest;
+
+import org.elasticsearch.common.settings.Setting;
+import org.elasticsearch.core.TimeValue;
+
+public final class IngestSettings {
+
+    private IngestSettings() {
+        // utility class
+    }
+
+    public static final Setting<TimeValue> GROK_WATCHDOG_INTERVAL = Setting.timeSetting(
+        "ingest.grok.watchdog.interval",
+        TimeValue.timeValueSeconds(1),
+        Setting.Property.NodeScope
+    );
+    public static final Setting<TimeValue> GROK_WATCHDOG_MAX_EXECUTION_TIME = Setting.timeSetting(
+        "ingest.grok.watchdog.max_execution_time",
+        TimeValue.timeValueSeconds(1),
+        Setting.Property.NodeScope
+    );
+
+}

+ 6 - 2
server/src/main/java/org/elasticsearch/ingest/Processor.java

@@ -11,6 +11,7 @@ package org.elasticsearch.ingest;
 import org.elasticsearch.client.internal.Client;
 import org.elasticsearch.common.util.concurrent.ThreadContext;
 import org.elasticsearch.env.Environment;
+import org.elasticsearch.grok.MatcherWatchdog;
 import org.elasticsearch.index.analysis.AnalysisRegistry;
 import org.elasticsearch.script.ScriptService;
 import org.elasticsearch.threadpool.Scheduler;
@@ -138,6 +139,8 @@ public interface Processor {
          */
         public final Client client;
 
+        public final MatcherWatchdog matcherWatchdog;
+
         public Parameters(
             Environment env,
             ScriptService scriptService,
@@ -147,7 +150,8 @@ public interface Processor {
             BiFunction<Long, Runnable, Scheduler.ScheduledCancellable> scheduler,
             IngestService ingestService,
             Client client,
-            Consumer<Runnable> genericExecutor
+            Consumer<Runnable> genericExecutor,
+            MatcherWatchdog matcherWatchdog
         ) {
             this.env = env;
             this.scriptService = scriptService;
@@ -158,7 +162,7 @@ public interface Processor {
             this.ingestService = ingestService;
             this.client = client;
             this.genericExecutor = genericExecutor;
+            this.matcherWatchdog = matcherWatchdog;
         }
-
     }
 }

+ 2 - 1
server/src/main/java/org/elasticsearch/node/Node.java

@@ -522,7 +522,8 @@ public class Node implements Closeable {
                 scriptService,
                 analysisModule.getAnalysisRegistry(),
                 pluginsService.filterPlugins(IngestPlugin.class),
-                client
+                client,
+                IngestService.createGrokThreadWatchdog(this.environment, threadPool)
             );
             final SetOnce<RepositoriesService> repositoriesServiceReference = new SetOnce<>();
             final ClusterInfoService clusterInfoService = newClusterInfoService(settings, clusterService, threadPool, client);

+ 1 - 1
server/src/main/java/org/elasticsearch/rest/action/RestMainAction.java

@@ -26,7 +26,7 @@ import java.util.List;
 import static org.elasticsearch.rest.RestRequest.Method.GET;
 import static org.elasticsearch.rest.RestRequest.Method.HEAD;
 
-@ServerlessScope(Scope.INTERNAL)
+@ServerlessScope(Scope.PUBLIC)
 public class RestMainAction extends BaseRestHandler {
 
     @Override

+ 3 - 0
server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetScriptContextAction.java

@@ -13,6 +13,8 @@ import org.elasticsearch.action.admin.cluster.storedscripts.GetScriptContextRequ
 import org.elasticsearch.client.internal.node.NodeClient;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
+import org.elasticsearch.rest.Scope;
+import org.elasticsearch.rest.ServerlessScope;
 import org.elasticsearch.rest.action.RestToXContentListener;
 
 import java.io.IOException;
@@ -20,6 +22,7 @@ import java.util.List;
 
 import static org.elasticsearch.rest.RestRequest.Method.GET;
 
+@ServerlessScope(Scope.PUBLIC)
 public class RestGetScriptContextAction extends BaseRestHandler {
 
     @Override

+ 3 - 0
server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestGetScriptLanguageAction.java

@@ -13,6 +13,8 @@ import org.elasticsearch.action.admin.cluster.storedscripts.GetScriptLanguageReq
 import org.elasticsearch.client.internal.node.NodeClient;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
+import org.elasticsearch.rest.Scope;
+import org.elasticsearch.rest.ServerlessScope;
 import org.elasticsearch.rest.action.RestToXContentListener;
 
 import java.io.IOException;
@@ -20,6 +22,7 @@ import java.util.List;
 
 import static org.elasticsearch.rest.RestRequest.Method.GET;
 
+@ServerlessScope(Scope.PUBLIC)
 public class RestGetScriptLanguageAction extends BaseRestHandler {
 
     @Override

+ 3 - 0
server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestNodesHotThreadsAction.java

@@ -20,6 +20,8 @@ import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
 import org.elasticsearch.rest.RestResponse;
 import org.elasticsearch.rest.RestStatus;
+import org.elasticsearch.rest.Scope;
+import org.elasticsearch.rest.ServerlessScope;
 import org.elasticsearch.rest.action.RestResponseListener;
 
 import java.io.IOException;
@@ -28,6 +30,7 @@ import java.util.Locale;
 
 import static org.elasticsearch.rest.RestRequest.Method.GET;
 
+@ServerlessScope(Scope.INTERNAL)
 public class RestNodesHotThreadsAction extends BaseRestHandler {
 
     private static final String formatDeprecatedMessageWithoutNodeID = "[%s] is a deprecated endpoint. "

+ 3 - 0
server/src/main/java/org/elasticsearch/rest/action/admin/cluster/RestNodesInfoAction.java

@@ -16,6 +16,8 @@ import org.elasticsearch.common.settings.SettingsFilter;
 import org.elasticsearch.common.util.set.Sets;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
+import org.elasticsearch.rest.Scope;
+import org.elasticsearch.rest.ServerlessScope;
 import org.elasticsearch.rest.action.RestActions.NodesResponseRestListener;
 
 import java.io.IOException;
@@ -24,6 +26,7 @@ import java.util.Set;
 
 import static org.elasticsearch.rest.RestRequest.Method.GET;
 
+@ServerlessScope(Scope.INTERNAL)
 public class RestNodesInfoAction extends BaseRestHandler {
     static final Set<String> ALLOWED_METRICS = NodesInfoRequest.Metric.allMetrics();
 

+ 3 - 0
server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestAnalyzeIndexDiskUsageAction.java

@@ -17,6 +17,8 @@ import org.elasticsearch.core.Booleans;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestHandler;
 import org.elasticsearch.rest.RestRequest;
+import org.elasticsearch.rest.Scope;
+import org.elasticsearch.rest.ServerlessScope;
 import org.elasticsearch.rest.action.RestCancellableNodeClient;
 import org.elasticsearch.rest.action.RestToXContentListener;
 
@@ -25,6 +27,7 @@ import java.util.List;
 
 import static org.elasticsearch.rest.RestRequest.Method.POST;
 
+@ServerlessScope(Scope.PUBLIC)
 public class RestAnalyzeIndexDiskUsageAction extends BaseRestHandler {
 
     @Override

+ 3 - 0
server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestDeleteComposableIndexTemplateAction.java

@@ -13,6 +13,8 @@ import org.elasticsearch.client.internal.node.NodeClient;
 import org.elasticsearch.common.Strings;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
+import org.elasticsearch.rest.Scope;
+import org.elasticsearch.rest.ServerlessScope;
 import org.elasticsearch.rest.action.RestToXContentListener;
 
 import java.io.IOException;
@@ -20,6 +22,7 @@ import java.util.List;
 
 import static org.elasticsearch.rest.RestRequest.Method.DELETE;
 
+@ServerlessScope(Scope.PUBLIC)
 public class RestDeleteComposableIndexTemplateAction extends BaseRestHandler {
 
     @Override

+ 3 - 0
server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestGetComposableIndexTemplateAction.java

@@ -15,6 +15,8 @@ import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
 import org.elasticsearch.rest.RestStatus;
+import org.elasticsearch.rest.Scope;
+import org.elasticsearch.rest.ServerlessScope;
 import org.elasticsearch.rest.action.RestToXContentListener;
 
 import java.io.IOException;
@@ -26,6 +28,7 @@ import static org.elasticsearch.rest.RestRequest.Method.HEAD;
 import static org.elasticsearch.rest.RestStatus.NOT_FOUND;
 import static org.elasticsearch.rest.RestStatus.OK;
 
+@ServerlessScope(Scope.PUBLIC)
 public class RestGetComposableIndexTemplateAction extends BaseRestHandler {
 
     @Override

+ 3 - 0
server/src/main/java/org/elasticsearch/rest/action/admin/indices/RestPutComposableIndexTemplateAction.java

@@ -13,6 +13,8 @@ import org.elasticsearch.client.internal.node.NodeClient;
 import org.elasticsearch.cluster.metadata.ComposableIndexTemplate;
 import org.elasticsearch.rest.BaseRestHandler;
 import org.elasticsearch.rest.RestRequest;
+import org.elasticsearch.rest.Scope;
+import org.elasticsearch.rest.ServerlessScope;
 import org.elasticsearch.rest.action.RestToXContentListener;
 
 import java.io.IOException;
@@ -21,6 +23,7 @@ import java.util.List;
 import static org.elasticsearch.rest.RestRequest.Method.POST;
 import static org.elasticsearch.rest.RestRequest.Method.PUT;
 
+@ServerlessScope(Scope.PUBLIC)
 public class RestPutComposableIndexTemplateAction extends BaseRestHandler {
 
     @Override

+ 1 - 1
server/src/test/java/org/elasticsearch/action/admin/indices/diskusage/IndexDiskUsageAnalyzerTests.java

@@ -252,7 +252,7 @@ public class IndexDiskUsageAnalyzerTests extends ESTestCase {
         try (Directory dir = createNewDirectory()) {
             final CodecMode codec = randomFrom(CodecMode.values());
             VectorSimilarityFunction similarity = randomFrom(VectorSimilarityFunction.values());
-            int numDocs = between(100, 1000);
+            int numDocs = between(1000, 5000);
             int dimension = between(10, 200);
 
             indexRandomly(dir, codec, numDocs, doc -> {

+ 2 - 1
server/src/test/java/org/elasticsearch/action/ingest/ReservedPipelineActionTests.java

@@ -87,7 +87,8 @@ public class ReservedPipelineActionTests extends ESTestCase {
             null,
             null,
             Collections.singletonList(DUMMY_PLUGIN),
-            client
+            client,
+            null
         );
         Map<String, Processor.Factory> factories = ingestService.getProcessorFactories();
         assertTrue(factories.containsKey("set"));

+ 11 - 0
server/src/test/java/org/elasticsearch/common/settings/LocallyMountedSecretsTests.java

@@ -139,6 +139,17 @@ public class LocallyMountedSecretsTests extends ESTestCase {
         assertNull(secrets.getString("ccc"));
     }
 
+    public void testResolveSecretsDir() {
+        assertTrue(LocallyMountedSecrets.resolveSecretsDir(env).endsWith("config/" + LocallyMountedSecrets.SECRETS_DIRECTORY));
+    }
+
+    public void testResolveSecretsFile() {
+        assertTrue(
+            LocallyMountedSecrets.resolveSecretsFile(env)
+                .endsWith("config/" + LocallyMountedSecrets.SECRETS_DIRECTORY + "/" + LocallyMountedSecrets.SECRETS_FILE_NAME)
+        );
+    }
+
     private void writeTestFile(Path path, String contents) throws IOException {
         Path tempFilePath = createTempFile();
 

+ 18 - 6
server/src/test/java/org/elasticsearch/ingest/IngestServiceTests.java

@@ -145,7 +145,8 @@ public class IngestServiceTests extends ESTestCase {
             null,
             null,
             List.of(DUMMY_PLUGIN),
-            client
+            client,
+            null
         );
         Map<String, Processor.Factory> factories = ingestService.getProcessorFactories();
         assertTrue(factories.containsKey("foo"));
@@ -156,7 +157,16 @@ public class IngestServiceTests extends ESTestCase {
         Client client = mock(Client.class);
         IllegalArgumentException e = expectThrows(
             IllegalArgumentException.class,
-            () -> new IngestService(mock(ClusterService.class), threadPool, null, null, null, List.of(DUMMY_PLUGIN, DUMMY_PLUGIN), client)
+            () -> new IngestService(
+                mock(ClusterService.class),
+                threadPool,
+                null,
+                null,
+                null,
+                List.of(DUMMY_PLUGIN, DUMMY_PLUGIN),
+                client,
+                null
+            )
         );
         assertTrue(e.getMessage(), e.getMessage().contains("already registered"));
     }
@@ -170,7 +180,8 @@ public class IngestServiceTests extends ESTestCase {
             null,
             null,
             List.of(DUMMY_PLUGIN),
-            client
+            client,
+            null
         );
         final IndexRequest indexRequest = new IndexRequest("_index").id("_id")
             .source(Map.of())
@@ -1763,7 +1774,8 @@ public class IngestServiceTests extends ESTestCase {
             null,
             null,
             List.of(testPlugin),
-            client
+            client,
+            null
         );
         ingestService.addIngestClusterStateListener(ingestClusterStateListener);
 
@@ -2091,7 +2103,7 @@ public class IngestServiceTests extends ESTestCase {
         Client client = mock(Client.class);
         ClusterService clusterService = mock(ClusterService.class);
         when(clusterService.state()).thenReturn(clusterState);
-        IngestService ingestService = new IngestService(clusterService, threadPool, null, null, null, List.of(DUMMY_PLUGIN), client);
+        IngestService ingestService = new IngestService(clusterService, threadPool, null, null, null, List.of(DUMMY_PLUGIN), client, null);
         ingestService.applyClusterState(new ClusterChangedEvent("", clusterState, clusterState));
 
         CountDownLatch latch = new CountDownLatch(1);
@@ -2373,7 +2385,7 @@ public class IngestServiceTests extends ESTestCase {
             public Map<String, Processor.Factory> getProcessors(final Processor.Parameters parameters) {
                 return processors;
             }
-        }), client);
+        }), client, null);
     }
 
     private CompoundProcessor mockCompoundProcessor() {

+ 2 - 1
server/src/test/java/org/elasticsearch/snapshots/SnapshotResiliencyTests.java

@@ -1933,7 +1933,8 @@ public class SnapshotResiliencyTests extends ESTestCase {
                             scriptService,
                             new AnalysisModule(environment, Collections.emptyList(), new StablePluginsRegistry()).getAnalysisRegistry(),
                             Collections.emptyList(),
-                            client
+                            client,
+                            null
                         ),
                         client,
                         actionFilters,

+ 0 - 4
test/x-content/build.gradle

@@ -38,10 +38,6 @@ tasks.named("thirdPartyAudit").configure {
           'com.github.luben.zstd.ZstdInputStream',
           'com.github.luben.zstd.ZstdOutputStream',
           'org.brotli.dec.BrotliInputStream',
-          'org.jcodings.specific.UTF8Encoding',
-          'org.joni.Matcher',
-          'org.joni.Regex',
-          'org.joni.Syntax',
           'org.objectweb.asm.AnnotationVisitor',
           'org.objectweb.asm.Attribute',
           'org.objectweb.asm.ClassReader',

+ 10 - 1
x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/action/TransportGetTrainedModelsStatsActionTests.java

@@ -125,7 +125,16 @@ public class TransportGetTrainedModelsStatsActionTests extends ESTestCase {
             )
         );
         clusterService = new ClusterService(settings, clusterSettings, tp, null);
-        ingestService = new IngestService(clusterService, tp, null, null, null, Collections.singletonList(SKINNY_INGEST_PLUGIN), client);
+        ingestService = new IngestService(
+            clusterService,
+            tp,
+            null,
+            null,
+            null,
+            Collections.singletonList(SKINNY_INGEST_PLUGIN),
+            client,
+            null
+        );
     }
 
     public void testInferenceIngestStatsByModelId() {

+ 16 - 0
x-pack/plugin/redact/build.gradle

@@ -0,0 +1,16 @@
+apply plugin: 'elasticsearch.internal-es-plugin'
+apply plugin: 'elasticsearch.internal-cluster-test'
+esplugin {
+  name 'x-pack-redact'
+  description 'Elasticsearch Expanded Pack Plugin - Redact'
+  classname 'org.elasticsearch.xpack.redact.RedactPlugin'
+  extendedPlugins = ['x-pack-core']
+}
+archivesBaseName = 'x-pack-redact'
+
+dependencies {
+  compileOnly project(path: xpackModule('core'))
+  testImplementation(testArtifact(project(xpackModule('core'))))
+}
+
+addQaCheckDependencies(project)

+ 34 - 0
x-pack/plugin/redact/src/main/java/org/elasticsearch/xpack/redact/RedactPlugin.java

@@ -0,0 +1,34 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+package org.elasticsearch.xpack.redact;
+
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.ingest.Processor;
+import org.elasticsearch.license.XPackLicenseState;
+import org.elasticsearch.plugins.IngestPlugin;
+import org.elasticsearch.plugins.Plugin;
+import org.elasticsearch.xpack.core.XPackPlugin;
+
+import java.util.Map;
+
+public class RedactPlugin extends Plugin implements IngestPlugin {
+
+    private final Settings settings;
+
+    public RedactPlugin(final Settings settings) {
+        this.settings = settings;
+    }
+
+    @Override
+    public Map<String, Processor.Factory> getProcessors(Processor.Parameters parameters) {
+        return Map.of(RedactProcessor.TYPE, new RedactProcessor.Factory(parameters.matcherWatchdog));
+    }
+
+    protected XPackLicenseState getLicenseState() {
+        return XPackPlugin.getSharedLicenseState();
+    }
+}

+ 3 - 5
modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/RedactProcessor.java → x-pack/plugin/redact/src/main/java/org/elasticsearch/xpack/redact/RedactProcessor.java

@@ -1,12 +1,10 @@
 /*
  * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
  * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
  */
-
-package org.elasticsearch.ingest.common;
+package org.elasticsearch.xpack.redact;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;

+ 3 - 5
modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/RedactProcessorFactoryTests.java → x-pack/plugin/redact/src/test/java/org/elasticsearch/xpack/redact/RedactProcessorFactoryTests.java

@@ -1,12 +1,10 @@
 /*
  * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
  * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
  */
-
-package org.elasticsearch.ingest.common;
+package org.elasticsearch.xpack.redact;
 
 import org.elasticsearch.ElasticsearchException;
 import org.elasticsearch.grok.MatcherWatchdog;

+ 3 - 5
modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/RedactProcessorTests.java → x-pack/plugin/redact/src/test/java/org/elasticsearch/xpack/redact/RedactProcessorTests.java

@@ -1,12 +1,10 @@
 /*
  * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
  * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
  */
-
-package org.elasticsearch.ingest.common;
+package org.elasticsearch.xpack.redact;
 
 import org.elasticsearch.grok.MatcherWatchdog;
 import org.elasticsearch.index.VersionType;

+ 0 - 0
modules/ingest-common/src/yamlRestTest/resources/rest-api-spec/test/ingest/300_redact_processor.yml → x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/redact/10_redact_processor.yml


+ 4 - 6
x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/spatial/20_cartesian_centroid.yml

@@ -6,6 +6,8 @@ setup:
       indices.create:
         index: locations
         body:
+          settings:
+            number_of_shards: 1
           mappings:
             properties:
               location:
@@ -43,6 +45,8 @@ setup:
       indices.create:
         index: shapes
         body:
+          settings:
+            number_of_shards: 1
           mappings:
             properties:
               shape:
@@ -114,9 +118,6 @@ setup:
 
 ---
 "Test cartesian_centroid aggregation on cartesian shape shapes":
-  - skip:
-      version: "all"
-      reason: "Awaits fix: https://github.com/elastic/elasticsearch/issues/95147"
   - do:
       search:
         rest_total_hits_as_int: true
@@ -208,9 +209,6 @@ setup:
 
 ---
 "Test cartesian_centroid aggregation on cartesian shape shapes with grouping":
-  - skip:
-      version: "all"
-      reason: "Awaits fix: https://github.com/elastic/elasticsearch/issues/95147"
   - do:
       search:
         rest_total_hits_as_int: true

+ 2 - 3
x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/spatial/20_geo_centroid.yml

@@ -45,6 +45,8 @@ setup:
       indices.create:
         index: shapes
         body:
+          settings:
+            number_of_shards: 1
           mappings:
             properties:
               shape:
@@ -116,9 +118,6 @@ setup:
 
 ---
 "Test geo_centroid aggregation on geo_shape shapes":
-  - skip:
-      version: "all"
-      reason: "Awaits fix: https://github.com/elastic/elasticsearch/issues/95147"
   - do:
       search:
         rest_total_hits_as_int: true