From 6d943e9e53576700b8417164d0e4c899c5f84e52 Mon Sep 17 00:00:00 2001 From: Valeriy Khakhutskyy <1292899+valeriy42@users.noreply.github.com> Date: Tue, 17 Dec 2024 16:33:27 +0100 Subject: [PATCH 01/60] [ML] Ignore failures from renormalizing buckets in read-only index (#118674) In anomaly detection, score renormalization will update the anomaly score in the result indices. However, if the index in the old format was marked as read-only, the score update will fail. Since this failure is expected, this PR suppresses the error logging in this specific case. --- docs/changelog/118674.yaml | 5 ++++ .../JobRenormalizedResultsPersister.java | 26 ++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 docs/changelog/118674.yaml diff --git a/docs/changelog/118674.yaml b/docs/changelog/118674.yaml new file mode 100644 index 0000000000000..eeb90a3b38f66 --- /dev/null +++ b/docs/changelog/118674.yaml @@ -0,0 +1,5 @@ +pr: 118674 +summary: Ignore failures from renormalizing buckets in read-only index +area: Machine Learning +type: enhancement +issues: [] diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/persistence/JobRenormalizedResultsPersister.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/persistence/JobRenormalizedResultsPersister.java index 3c0d2aca4deda..3c82841f1b99e 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/persistence/JobRenormalizedResultsPersister.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/job/persistence/JobRenormalizedResultsPersister.java @@ -8,10 +8,12 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.client.internal.Client; +import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.xcontent.ToXContent; import org.elasticsearch.xcontent.XContentBuilder; @@ -102,7 +104,29 @@ public void executeRequest() { try (ThreadContext.StoredContext ignore = client.threadPool().getThreadContext().stashWithOrigin(ML_ORIGIN)) { BulkResponse addRecordsResponse = client.bulk(bulkRequest).actionGet(); if (addRecordsResponse.hasFailures()) { - logger.error("[{}] Bulk index of results has errors: {}", jobId, addRecordsResponse.buildFailureMessage()); + // Implementation note: Ignore the failures from writing to the read-only index, as it comes + // from changing the index format version. + boolean hasNonReadOnlyFailures = false; + for (BulkItemResponse response : addRecordsResponse.getItems()) { + if (response.isFailed() == false) { + continue; + } + if (response.getFailureMessage().contains(IndexMetadata.INDEX_READ_ONLY_BLOCK.description())) { + // We expect this to happen when the old index is made read-only and being reindexed + logger.debug( + "[{}] Ignoring failure to write renormalized results to a read-only index [{}]: {}", + jobId, + response.getFailure().getIndex(), + response.getFailureMessage() + ); + } else { + hasNonReadOnlyFailures = true; + break; + } + } + if (hasNonReadOnlyFailures) { + logger.error("[{}] Bulk index of results has errors: {}", jobId, addRecordsResponse.buildFailureMessage()); + } } } From f64c05ac32ee23930cf913c7939c9eeac12f00ce Mon Sep 17 00:00:00 2001 From: Adam Szaraniec Date: Tue, 17 Dec 2024 20:09:22 +0400 Subject: [PATCH 02/60] Update alias.asciidoc (#118553) Add section about removing index --- docs/reference/alias.asciidoc | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/reference/alias.asciidoc b/docs/reference/alias.asciidoc index 9d784f530d63c..f676644c4ec48 100644 --- a/docs/reference/alias.asciidoc +++ b/docs/reference/alias.asciidoc @@ -407,3 +407,24 @@ POST _aliases } ---- // TEST[s/^/PUT my-index-2099.05.06-000001\n/] + +[discrete] +[[remove-index]] +=== Remove an index + +To remove an index, use the aliases API's `remove_index` action. + +[source,console] +---- +POST _aliases +{ + "actions": [ + { + "remove_index": { + "index": "my-index-2099.05.06-000001" + } + } + ] +} +---- +// TEST[s/^/PUT my-index-2099.05.06-000001\n/] From 1d2840ece1b8a5fcc1e6836d70bb1187160f2cd2 Mon Sep 17 00:00:00 2001 From: Luigi Dell'Aquila Date: Tue, 17 Dec 2024 17:13:52 +0100 Subject: [PATCH 03/60] EQL: add support for partial search results (#116388) Allow queries to succeed if some shards are failing --- docs/changelog/116388.yaml | 5 + docs/reference/eql/eql-search-api.asciidoc | 47 ++ .../rest-api-spec/api/eql.search.json | 10 + .../org/elasticsearch/TransportVersions.java | 1 + .../test/eql/BaseEqlSpecTestCase.java | 84 +- .../elasticsearch/test/eql/DataLoader.java | 6 + .../test/eql/EqlDateNanosSpecTestCase.java | 36 +- .../test/eql/EqlExtraSpecTestCase.java | 36 +- .../eql/EqlMissingEventsSpecTestCase.java | 36 +- .../eql/EqlSampleMultipleEntriesTestCase.java | 36 +- .../test/eql/EqlSampleTestCase.java | 43 +- .../org/elasticsearch/test/eql/EqlSpec.java | 51 +- .../eql/EqlSpecFailingShardsTestCase.java | 83 ++ .../elasticsearch/test/eql/EqlSpecLoader.java | 7 + .../test/eql/EqlSpecTestCase.java | 43 +- .../data/endgame-shard-failures.data | 14 + .../data/endgame-shard-failures.mapping | 105 +++ .../main/resources/test_failing_shards.toml | 173 ++++ .../xpack/eql/qa/mixed_node/EqlSearchIT.java | 11 +- .../xpack/eql/EqlDateNanosIT.java | 25 +- .../elasticsearch/xpack/eql/EqlExtraIT.java | 25 +- .../elasticsearch/xpack/eql/EqlSampleIT.java | 25 +- .../xpack/eql/EqlSampleMultipleEntriesIT.java | 18 +- .../elasticsearch/xpack/eql/EqlSpecIT.java | 25 +- .../xpack/eql/EqlDateNanosIT.java | 24 +- .../elasticsearch/xpack/eql/EqlExtraIT.java | 24 +- .../xpack/eql/EqlMissingEventsIT.java | 24 +- .../elasticsearch/xpack/eql/EqlSampleIT.java | 24 +- .../xpack/eql/EqlSampleMultipleEntriesIT.java | 17 +- .../xpack/eql/EqlSpecFailingShardsIT.java | 53 ++ .../elasticsearch/xpack/eql/EqlSpecIT.java | 24 +- .../rest-api-spec/test/eql/10_basic.yml | 143 ++++ .../xpack/eql/action/CCSPartialResultsIT.java | 613 ++++++++++++++ .../eql/action/PartialSearchResultsIT.java | 780 ++++++++++++++++++ .../xpack/eql/action/EqlSearchRequest.java | 47 +- .../xpack/eql/action/EqlSearchResponse.java | 42 +- .../xpack/eql/action/EqlSearchTask.java | 4 +- .../execution/assembler/ExecutionManager.java | 7 +- .../execution/payload/AbstractPayload.java | 10 +- .../eql/execution/payload/EventPayload.java | 2 +- .../eql/execution/sample/SampleIterator.java | 29 +- .../eql/execution/sample/SamplePayload.java | 11 +- .../execution/search/BasicQueryClient.java | 18 +- .../execution/search/PITAwareQueryClient.java | 25 +- .../eql/execution/search/RuntimeUtils.java | 31 +- .../execution/sequence/SequencePayload.java | 11 +- .../execution/sequence/TumblingWindow.java | 43 +- .../xpack/eql/plugin/EqlPlugin.java | 16 +- .../xpack/eql/plugin/RestEqlSearchAction.java | 6 + .../eql/plugin/TransportEqlSearchAction.java | 36 +- .../xpack/eql/session/EmptyPayload.java | 13 +- .../xpack/eql/session/EqlConfiguration.java | 14 + .../xpack/eql/session/Payload.java | 3 + .../xpack/eql/session/Results.java | 19 +- .../xpack/eql/util/SearchHitUtils.java | 12 + .../elasticsearch/xpack/eql/EqlTestUtils.java | 4 + .../eql/action/EqlSearchRequestTests.java | 8 + .../eql/action/EqlSearchResponseTests.java | 14 +- .../eql/action/LocalStateEQLXPackPlugin.java | 21 +- .../assembler/ImplicitTiebreakerTests.java | 10 +- .../assembler/SequenceSpecTests.java | 10 +- .../execution/sample/CircuitBreakerTests.java | 5 +- .../search/PITAwareQueryClientTests.java | 12 +- .../sequence/CircuitBreakerTests.java | 32 +- .../execution/sequence/PITFailureTests.java | 12 +- 65 files changed, 3068 insertions(+), 130 deletions(-) create mode 100644 docs/changelog/116388.yaml create mode 100644 x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSpecFailingShardsTestCase.java create mode 100644 x-pack/plugin/eql/qa/common/src/main/resources/data/endgame-shard-failures.data create mode 100644 x-pack/plugin/eql/qa/common/src/main/resources/data/endgame-shard-failures.mapping create mode 100644 x-pack/plugin/eql/qa/common/src/main/resources/test_failing_shards.toml create mode 100644 x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSpecFailingShardsIT.java create mode 100644 x-pack/plugin/eql/src/internalClusterTest/java/org/elasticsearch/xpack/eql/action/CCSPartialResultsIT.java create mode 100644 x-pack/plugin/eql/src/internalClusterTest/java/org/elasticsearch/xpack/eql/action/PartialSearchResultsIT.java diff --git a/docs/changelog/116388.yaml b/docs/changelog/116388.yaml new file mode 100644 index 0000000000000..59cdafc9ec337 --- /dev/null +++ b/docs/changelog/116388.yaml @@ -0,0 +1,5 @@ +pr: 116388 +summary: Add support for partial shard results +area: EQL +type: enhancement +issues: [] diff --git a/docs/reference/eql/eql-search-api.asciidoc b/docs/reference/eql/eql-search-api.asciidoc index d7f10f4627f6c..0fd490609277f 100644 --- a/docs/reference/eql/eql-search-api.asciidoc +++ b/docs/reference/eql/eql-search-api.asciidoc @@ -88,6 +88,53 @@ request that targets only `bar*` still returns an error. + Defaults to `true`. +`allow_partial_search_results`:: +(Optional, Boolean) + +If `false`, the request returns an error if one or more shards involved in the query are unavailable. ++ +If `true`, the query is executed only on the available shards, ignoring shard request timeouts and +<>. ++ +Defaults to `false`. ++ +To override the default for this field, set the +`xpack.eql.default_allow_partial_results` cluster setting to `true`. + + +[IMPORTANT] +==== +You can also specify this value using the `allow_partial_search_results` request body parameter. +If both parameters are specified, only the query parameter is used. +==== + + +`allow_partial_sequence_results`:: +(Optional, Boolean) + + +Used together with `allow_partial_search_results=true`, controls the behavior of sequence queries specifically +(if `allow_partial_search_results=false`, this setting has no effect). +If `true` and if some shards are unavailable, the sequences are calculated on available shards only. ++ +If `false` and if some shards are unavailable, the query only returns information about the shard failures, +but no further results. ++ +Defaults to `false`. ++ +Consider that sequences calculated with `allow_partial_search_results=true` can return incorrect results +(eg. if a <> clause matches records in unavailable shards) ++ +To override the default for this field, set the +`xpack.eql.default_allow_partial_sequence_results` cluster setting to `true`. + + +[IMPORTANT] +==== +You can also specify this value using the `allow_partial_sequence_results` request body parameter. +If both parameters are specified, only the query parameter is used. +==== + `ccs_minimize_roundtrips`:: (Optional, Boolean) If `true`, network round-trips between the local and the remote cluster are minimized when running cross-cluster search (CCS) requests. diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/eql.search.json b/rest-api-spec/src/main/resources/rest-api-spec/api/eql.search.json index c854c44d9d761..0f9af508f4c16 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/eql.search.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/eql.search.json @@ -41,6 +41,16 @@ "type": "time", "description": "Update the time interval in which the results (partial or final) for this search will be available", "default": "5d" + }, + "allow_partial_search_results": { + "type":"boolean", + "description":"Control whether the query should keep running in case of shard failures, and return partial results", + "default":false + }, + "allow_partial_sequence_results": { + "type":"boolean", + "description":"Control whether a sequence query should return partial results or no results at all in case of shard failures. This option has effect only if [allow_partial_search_results] is true.", + "default":false } }, "body":{ diff --git a/server/src/main/java/org/elasticsearch/TransportVersions.java b/server/src/main/java/org/elasticsearch/TransportVersions.java index f5e581a81a37c..371af961720cc 100644 --- a/server/src/main/java/org/elasticsearch/TransportVersions.java +++ b/server/src/main/java/org/elasticsearch/TransportVersions.java @@ -138,6 +138,7 @@ static TransportVersion def(int id) { public static final TransportVersion KNN_QUERY_RESCORE_OVERSAMPLE = def(8_806_00_0); public static final TransportVersion SEMANTIC_QUERY_LENIENT = def(8_807_00_0); public static final TransportVersion ESQL_QUERY_BUILDER_IN_SEARCH_FUNCTIONS = def(8_808_00_0); + public static final TransportVersion EQL_ALLOW_PARTIAL_SEARCH_RESULTS = def(8_809_00_0); /* * STOP! READ THIS FIRST! No, really, diff --git a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/BaseEqlSpecTestCase.java b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/BaseEqlSpecTestCase.java index 90244d9b2c019..3557114e2f4c7 100644 --- a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/BaseEqlSpecTestCase.java +++ b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/BaseEqlSpecTestCase.java @@ -33,6 +33,9 @@ import java.util.function.Function; import java.util.stream.Collectors; +import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.is; + public abstract class BaseEqlSpecTestCase extends RemoteClusterAwareEqlRestTestCase { protected static final String PARAM_FORMATTING = "%2$s"; @@ -52,6 +55,9 @@ public abstract class BaseEqlSpecTestCase extends RemoteClusterAwareEqlRestTestC */ private final int size; private final int maxSamplesPerKey; + private final Boolean allowPartialSearchResults; + private final Boolean allowPartialSequenceResults; + private final Boolean expectShardFailures; @Before public void setup() throws Exception { @@ -104,7 +110,16 @@ protected static List asArray(List specs) { } results.add( - new Object[] { spec.query(), name, spec.expectedEventIds(), spec.joinKeys(), spec.size(), spec.maxSamplesPerKey() } + new Object[] { + spec.query(), + name, + spec.expectedEventIds(), + spec.joinKeys(), + spec.size(), + spec.maxSamplesPerKey(), + spec.allowPartialSearchResults(), + spec.allowPartialSequenceResults(), + spec.expectShardFailures() } ); } @@ -118,7 +133,10 @@ protected static List asArray(List specs) { List eventIds, String[] joinKeys, Integer size, - Integer maxSamplesPerKey + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures ) { this.index = index; @@ -128,6 +146,9 @@ protected static List asArray(List specs) { this.joinKeys = joinKeys; this.size = size == null ? -1 : size; this.maxSamplesPerKey = maxSamplesPerKey == null ? -1 : maxSamplesPerKey; + this.allowPartialSearchResults = allowPartialSearchResults; + this.allowPartialSequenceResults = allowPartialSequenceResults; + this.expectShardFailures = expectShardFailures; } public void test() throws Exception { @@ -137,6 +158,7 @@ public void test() throws Exception { private void assertResponse(ObjectPath response) throws Exception { List> events = response.evaluate("hits.events"); List> sequences = response.evaluate("hits.sequences"); + Object shardFailures = response.evaluate("shard_failures"); if (events != null) { assertEvents(events); @@ -145,6 +167,7 @@ private void assertResponse(ObjectPath response) throws Exception { } else { fail("No events or sequences found"); } + assertShardFailures(shardFailures); } protected ObjectPath runQuery(String index, String query) throws Exception { @@ -163,6 +186,32 @@ protected ObjectPath runQuery(String index, String query) throws Exception { if (maxSamplesPerKey > 0) { builder.field("max_samples_per_key", maxSamplesPerKey); } + boolean allowPartialResultsInBody = randomBoolean(); + if (allowPartialSearchResults != null) { + if (allowPartialResultsInBody) { + builder.field("allow_partial_search_results", String.valueOf(allowPartialSearchResults)); + if (allowPartialSequenceResults != null) { + builder.field("allow_partial_sequence_results", String.valueOf(allowPartialSequenceResults)); + } + } else { + // these will be overwritten by the path params, that have higher priority than the query (JSON body) params + if (allowPartialSearchResults != null) { + builder.field("allow_partial_search_results", randomBoolean()); + } + if (allowPartialSequenceResults != null) { + builder.field("allow_partial_sequence_results", randomBoolean()); + } + } + } else { + // Tests that don't specify a setting for these parameters should always pass. + // These params should be irrelevant. + if (randomBoolean()) { + builder.field("allow_partial_search_results", randomBoolean()); + } + if (randomBoolean()) { + builder.field("allow_partial_sequence_results", randomBoolean()); + } + } builder.endObject(); Request request = new Request("POST", "/" + index + "/_eql/search"); @@ -170,6 +219,23 @@ protected ObjectPath runQuery(String index, String query) throws Exception { if (ccsMinimizeRoundtrips != null) { request.addParameter("ccs_minimize_roundtrips", ccsMinimizeRoundtrips.toString()); } + if (allowPartialSearchResults != null) { + if (allowPartialResultsInBody == false) { + request.addParameter("allow_partial_search_results", String.valueOf(allowPartialSearchResults)); + if (allowPartialSequenceResults != null) { + request.addParameter("allow_partial_sequence_results", String.valueOf(allowPartialSequenceResults)); + } + } + } else { + // Tests that don't specify a setting for these parameters should always pass. + // These params should be irrelevant. + if (randomBoolean()) { + request.addParameter("allow_partial_search_results", String.valueOf(randomBoolean())); + } + if (randomBoolean()) { + request.addParameter("allow_partial_sequence_results", String.valueOf(randomBoolean())); + } + } int timeout = Math.toIntExact(timeout().millis()); RequestConfig config = RequestConfig.copy(RequestConfig.DEFAULT) .setConnectionRequestTimeout(timeout) @@ -182,6 +248,20 @@ protected ObjectPath runQuery(String index, String query) throws Exception { return ObjectPath.createFromResponse(client().performRequest(request)); } + private void assertShardFailures(Object shardFailures) { + if (expectShardFailures != null) { + if (expectShardFailures) { + assertNotNull(shardFailures); + List list = (List) shardFailures; + assertThat(list.size(), is(greaterThan(0))); + } else { + assertNull(shardFailures); + } + } else { + assertNull(shardFailures); + } + } + private void assertEvents(List> events) { assertNotNull(events); logger.debug("Events {}", new Object() { diff --git a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/DataLoader.java b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/DataLoader.java index 1d51af574c810..4618bd8f4ff3d 100644 --- a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/DataLoader.java +++ b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/DataLoader.java @@ -52,6 +52,7 @@ */ public class DataLoader { public static final String TEST_INDEX = "endgame-140"; + public static final String TEST_SHARD_FAILURES_INDEX = "endgame-shard-failures"; public static final String TEST_EXTRA_INDEX = "extra"; public static final String TEST_NANOS_INDEX = "endgame-140-nanos"; public static final String TEST_SAMPLE = "sample1,sample2,sample3"; @@ -103,6 +104,11 @@ public static void loadDatasetIntoEs(RestClient client, CheckedBiFunction eventIds, String[] joinKeys, Integer size, - Integer maxSamplesPerKey + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures ) { - this(TEST_NANOS_INDEX, query, name, eventIds, joinKeys, size, maxSamplesPerKey); + this( + TEST_NANOS_INDEX, + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } // constructor for multi-cluster tests @@ -40,9 +54,23 @@ public EqlDateNanosSpecTestCase( List eventIds, String[] joinKeys, Integer size, - Integer maxSamplesPerKey + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures ) { - super(index, query, name, eventIds, joinKeys, size, maxSamplesPerKey); + super( + index, + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } @Override diff --git a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlExtraSpecTestCase.java b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlExtraSpecTestCase.java index 292fe6c895cee..cc858ded25f37 100644 --- a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlExtraSpecTestCase.java +++ b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlExtraSpecTestCase.java @@ -27,9 +27,23 @@ public EqlExtraSpecTestCase( List eventIds, String[] joinKeys, Integer size, - Integer maxSamplesPerKey + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures ) { - this(TEST_EXTRA_INDEX, query, name, eventIds, joinKeys, size, maxSamplesPerKey); + this( + TEST_EXTRA_INDEX, + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } // constructor for multi-cluster tests @@ -40,9 +54,23 @@ public EqlExtraSpecTestCase( List eventIds, String[] joinKeys, Integer size, - Integer maxSamplesPerKey + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures ) { - super(index, query, name, eventIds, joinKeys, size, maxSamplesPerKey); + super( + index, + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } @Override diff --git a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlMissingEventsSpecTestCase.java b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlMissingEventsSpecTestCase.java index cdda9e9e068f5..f62c2b29101db 100644 --- a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlMissingEventsSpecTestCase.java +++ b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlMissingEventsSpecTestCase.java @@ -27,9 +27,23 @@ public EqlMissingEventsSpecTestCase( List eventIds, String[] joinKeys, Integer size, - Integer maxSamplesPerKey + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures ) { - this(TEST_MISSING_EVENTS_INDEX, query, name, eventIds, joinKeys, size, maxSamplesPerKey); + this( + TEST_MISSING_EVENTS_INDEX, + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } // constructor for multi-cluster tests @@ -40,9 +54,23 @@ public EqlMissingEventsSpecTestCase( List eventIds, String[] joinKeys, Integer size, - Integer maxSamplesPerKey + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures ) { - super(index, query, name, eventIds, joinKeys, size, maxSamplesPerKey); + super( + index, + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } @Override diff --git a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSampleMultipleEntriesTestCase.java b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSampleMultipleEntriesTestCase.java index 6471e264a92fa..a38ccacb42f5f 100644 --- a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSampleMultipleEntriesTestCase.java +++ b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSampleMultipleEntriesTestCase.java @@ -21,9 +21,23 @@ public EqlSampleMultipleEntriesTestCase( List eventIds, String[] joinKeys, Integer size, - Integer maxSamplesPerKey + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures ) { - this(TEST_SAMPLE_MULTI, query, name, eventIds, joinKeys, size, maxSamplesPerKey); + this( + TEST_SAMPLE_MULTI, + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } public EqlSampleMultipleEntriesTestCase( @@ -33,9 +47,23 @@ public EqlSampleMultipleEntriesTestCase( List eventIds, String[] joinKeys, Integer size, - Integer maxSamplesPerKey + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures ) { - super(index, query, name, eventIds, joinKeys, size, maxSamplesPerKey); + super( + index, + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } @ParametersFactory(shuffle = false, argumentFormatting = PARAM_FORMATTING) diff --git a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSampleTestCase.java b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSampleTestCase.java index dfae73b3602a7..4748bd0e3307b 100644 --- a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSampleTestCase.java +++ b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSampleTestCase.java @@ -15,8 +15,29 @@ public abstract class EqlSampleTestCase extends BaseEqlSpecTestCase { - public EqlSampleTestCase(String query, String name, List eventIds, String[] joinKeys, Integer size, Integer maxSamplesPerKey) { - this(TEST_SAMPLE, query, name, eventIds, joinKeys, size, maxSamplesPerKey); + public EqlSampleTestCase( + String query, + String name, + List eventIds, + String[] joinKeys, + Integer size, + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures + ) { + this( + TEST_SAMPLE, + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } public EqlSampleTestCase( @@ -26,9 +47,23 @@ public EqlSampleTestCase( List eventIds, String[] joinKeys, Integer size, - Integer maxSamplesPerKey + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures ) { - super(index, query, name, eventIds, joinKeys, size, maxSamplesPerKey); + super( + index, + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } @ParametersFactory(shuffle = false, argumentFormatting = PARAM_FORMATTING) diff --git a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSpec.java b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSpec.java index db7ee05ff2239..4dd617bac0abd 100644 --- a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSpec.java +++ b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSpec.java @@ -30,6 +30,9 @@ public class EqlSpec { private Integer size; private Integer maxSamplesPerKey; + private Boolean allowPartialSearchResults; + private Boolean allowPartialSequenceResults; + private Boolean expectShardFailures; public String name() { return name; @@ -103,6 +106,30 @@ public void maxSamplesPerKey(Integer maxSamplesPerKey) { this.maxSamplesPerKey = maxSamplesPerKey; } + public Boolean allowPartialSearchResults() { + return allowPartialSearchResults; + } + + public void allowPartialSearchResults(Boolean allowPartialSearchResults) { + this.allowPartialSearchResults = allowPartialSearchResults; + } + + public Boolean allowPartialSequenceResults() { + return allowPartialSequenceResults; + } + + public void allowPartialSequenceResults(Boolean allowPartialSequenceResults) { + this.allowPartialSequenceResults = allowPartialSequenceResults; + } + + public Boolean expectShardFailures() { + return expectShardFailures; + } + + public void expectShardFailures(Boolean expectShardFailures) { + this.expectShardFailures = expectShardFailures; + } + @Override public String toString() { String str = ""; @@ -132,7 +159,15 @@ public String toString() { if (maxSamplesPerKey != null) { str = appendWithComma(str, "max_samples_per_key", "" + maxSamplesPerKey); } - + if (allowPartialSearchResults != null) { + str = appendWithComma(str, "allow_partial_search_results", String.valueOf(allowPartialSearchResults)); + } + if (allowPartialSequenceResults != null) { + str = appendWithComma(str, "allow_partial_sequence_results", String.valueOf(allowPartialSequenceResults)); + } + if (expectShardFailures != null) { + str = appendWithComma(str, "expect_shard_failures", String.valueOf(expectShardFailures)); + } return str; } @@ -150,12 +185,22 @@ public boolean equals(Object other) { return Objects.equals(this.query(), that.query()) && Objects.equals(size, that.size) - && Objects.equals(maxSamplesPerKey, that.maxSamplesPerKey); + && Objects.equals(maxSamplesPerKey, that.maxSamplesPerKey) + && Objects.equals(allowPartialSearchResults, that.allowPartialSearchResults) + && Objects.equals(allowPartialSequenceResults, that.allowPartialSequenceResults) + && Objects.equals(expectShardFailures, that.expectShardFailures); } @Override public int hashCode() { - return Objects.hash(this.query, size, maxSamplesPerKey); + return Objects.hash( + this.query, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } private static String appendWithComma(String str, String name, String append) { diff --git a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSpecFailingShardsTestCase.java b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSpecFailingShardsTestCase.java new file mode 100644 index 0000000000000..c490a2f703dcc --- /dev/null +++ b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSpecFailingShardsTestCase.java @@ -0,0 +1,83 @@ +/* + * 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.test.eql; + +import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; + +import java.util.List; + +import static org.elasticsearch.test.eql.DataLoader.TEST_INDEX; +import static org.elasticsearch.test.eql.DataLoader.TEST_SHARD_FAILURES_INDEX; + +public abstract class EqlSpecFailingShardsTestCase extends BaseEqlSpecTestCase { + + @ParametersFactory(shuffle = false, argumentFormatting = PARAM_FORMATTING) + public static List readTestSpecs() throws Exception { + + // Load EQL validation specs + return asArray(EqlSpecLoader.load("/test_failing_shards.toml")); + } + + @Override + protected String tiebreaker() { + return "serial_event_id"; + } + + // constructor for "local" rest tests + public EqlSpecFailingShardsTestCase( + String query, + String name, + List eventIds, + String[] joinKeys, + Integer size, + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures + ) { + this( + TEST_INDEX + "," + TEST_SHARD_FAILURES_INDEX, + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); + } + + // constructor for multi-cluster tests + public EqlSpecFailingShardsTestCase( + String index, + String query, + String name, + List eventIds, + String[] joinKeys, + Integer size, + Integer maxSamplesPerKey, + Boolean allowPartialSearch, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures + ) { + super( + index, + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearch, + allowPartialSequenceResults, + expectShardFailures + ); + } +} diff --git a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSpecLoader.java b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSpecLoader.java index a1f555563e29c..f86107cf3bac5 100644 --- a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSpecLoader.java +++ b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSpecLoader.java @@ -76,6 +76,10 @@ private static Integer getInteger(TomlTable table, String key) { return null; } + private static Boolean getBoolean(TomlTable table, String key) { + return table.getBoolean(key); + } + private static List readFromStream(InputStream is, Set uniqueTestNames) throws Exception { List testSpecs = new ArrayList<>(); @@ -90,6 +94,9 @@ private static List readFromStream(InputStream is, Set uniqueTe spec.note(getTrimmedString(table, "note")); spec.description(getTrimmedString(table, "description")); spec.size(getInteger(table, "size")); + spec.allowPartialSearchResults(getBoolean(table, "allow_partial_search_results")); + spec.allowPartialSequenceResults(getBoolean(table, "allow_partial_sequence_results")); + spec.expectShardFailures(getBoolean(table, "expect_shard_failures")); List arr = table.getList("tags"); if (arr != null) { diff --git a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSpecTestCase.java b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSpecTestCase.java index 7113924f79029..62a3ea72fe51f 100644 --- a/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSpecTestCase.java +++ b/x-pack/plugin/eql/qa/common/src/main/java/org/elasticsearch/test/eql/EqlSpecTestCase.java @@ -28,8 +28,29 @@ protected String tiebreaker() { } // constructor for "local" rest tests - public EqlSpecTestCase(String query, String name, List eventIds, String[] joinKeys, Integer size, Integer maxSamplesPerKey) { - this(TEST_INDEX, query, name, eventIds, joinKeys, size, maxSamplesPerKey); + public EqlSpecTestCase( + String query, + String name, + List eventIds, + String[] joinKeys, + Integer size, + Integer maxSamplesPerKey, + Boolean allowPartialSearch, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures + ) { + this( + TEST_INDEX, + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearch, + allowPartialSequenceResults, + expectShardFailures + ); } // constructor for multi-cluster tests @@ -40,8 +61,22 @@ public EqlSpecTestCase( List eventIds, String[] joinKeys, Integer size, - Integer maxSamplesPerKey + Integer maxSamplesPerKey, + Boolean allowPartialSearch, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures ) { - super(index, query, name, eventIds, joinKeys, size, maxSamplesPerKey); + super( + index, + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearch, + allowPartialSequenceResults, + expectShardFailures + ); } } diff --git a/x-pack/plugin/eql/qa/common/src/main/resources/data/endgame-shard-failures.data b/x-pack/plugin/eql/qa/common/src/main/resources/data/endgame-shard-failures.data new file mode 100644 index 0000000000000..18a1d05656d09 --- /dev/null +++ b/x-pack/plugin/eql/qa/common/src/main/resources/data/endgame-shard-failures.data @@ -0,0 +1,14 @@ +[ + { + "event_subtype_full": "already_running", + "event_type": "process", + "event_type_full": "process_event", + "opcode": 3, + "pid": 0, + "process_name": "System Idle Process", + "serial_event_id": 10000, + "subtype": "create", + "timestamp": 117444736000000000, + "unique_pid": 1 + } +] diff --git a/x-pack/plugin/eql/qa/common/src/main/resources/data/endgame-shard-failures.mapping b/x-pack/plugin/eql/qa/common/src/main/resources/data/endgame-shard-failures.mapping new file mode 100644 index 0000000000000..3b5039f4098af --- /dev/null +++ b/x-pack/plugin/eql/qa/common/src/main/resources/data/endgame-shard-failures.mapping @@ -0,0 +1,105 @@ +# Text patterns like "[runtime_random_keyword_type]" will get replaced at runtime with a random string type. +# See DataLoader class for pattern replacements. +{ + "runtime":{ + "broken":{ + "type": "long", + "script": { + "lang": "painless", + "source": "emit(doc['non_existing'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))" + } + } + }, + "properties" : { + "command_line" : { + "type" : "[runtime_random_keyword_type]" + }, + "event_type" : { + "type" : "[runtime_random_keyword_type]" + }, + "event" : { + "properties" : { + "category" : { + "type" : "alias", + "path" : "event_type" + }, + "sequence" : { + "type" : "alias", + "path" : "serial_event_id" + } + } + }, + "md5" : { + "type" : "[runtime_random_keyword_type]" + }, + "parent_process_name": { + "type" : "[runtime_random_keyword_type]" + }, + "parent_process_path": { + "type" : "[runtime_random_keyword_type]" + }, + "pid" : { + "type" : "long" + }, + "ppid" : { + "type" : "long" + }, + "process_name": { + "type" : "[runtime_random_keyword_type]" + }, + "process_path": { + "type" : "[runtime_random_keyword_type]" + }, + "subtype" : { + "type" : "[runtime_random_keyword_type]" + }, + "timestamp" : { + "type" : "date" + }, + "@timestamp" : { + "type" : "date" + }, + "user" : { + "type" : "[runtime_random_keyword_type]" + }, + "user_name" : { + "type" : "[runtime_random_keyword_type]" + }, + "user_domain": { + "type" : "[runtime_random_keyword_type]" + }, + "hostname" : { + "type" : "text", + "fields" : { + "[runtime_random_keyword_type]" : { + "type" : "[runtime_random_keyword_type]", + "ignore_above" : 256 + } + } + }, + "opcode" : { + "type" : "long" + }, + "file_name" : { + "type" : "text", + "fields" : { + "[runtime_random_keyword_type]" : { + "type" : "[runtime_random_keyword_type]", + "ignore_above" : 256 + } + } + }, + "file_path" : { + "type" : "[runtime_random_keyword_type]" + }, + "serial_event_id" : { + "type" : "long" + }, + "source_address" : { + "type" : "ip" + }, + "exit_code" : { + "type" : "long" + } + } +} diff --git a/x-pack/plugin/eql/qa/common/src/main/resources/test_failing_shards.toml b/x-pack/plugin/eql/qa/common/src/main/resources/test_failing_shards.toml new file mode 100644 index 0000000000000..a551c66fd48bd --- /dev/null +++ b/x-pack/plugin/eql/qa/common/src/main/resources/test_failing_shards.toml @@ -0,0 +1,173 @@ +# this query doesn't touch the "broken" field, so it should not fail +[[queries]] +name = "eventQueryNoShardFailures" +query = 'process where serial_event_id == 1' +allow_partial_search_results = true +expected_event_ids = [1] +expect_shard_failures = false + + +[[queries]] +name = "eventQueryShardFailures" +query = 'process where serial_event_id == 1 or broken == 1' +allow_partial_search_results = true +expected_event_ids = [1] +expect_shard_failures = true + + +[[queries]] +name = "eventQueryShardFailuresOptionalField" +query = 'process where serial_event_id == 1 and ?optional_field_default_null == null or broken == 1' +allow_partial_search_results = true +expected_event_ids = [1] +expect_shard_failures = true + + +[[queries]] +name = "eventQueryShardFailuresOptionalFieldMatching" +query = 'process where serial_event_id == 2 and ?subtype == "create" or broken == 1' +allow_partial_search_results = true +expected_event_ids = [2] +expect_shard_failures = true + + +# this query doesn't touch the "broken" field, so it should not fail +[[queries]] +name = "sequenceQueryNoShardFailures" +query = ''' +sequence + [process where serial_event_id == 1] + [process where serial_event_id == 2] +''' +expected_event_ids = [1, 2] +expect_shard_failures = false + + +# this query doesn't touch the "broken" field, so it should not fail +[[queries]] +name = "sequenceQueryNoShardFailuresAllowFalse" +query = ''' +sequence + [process where serial_event_id == 1] + [process where serial_event_id == 2] +''' +allow_partial_search_results = false +expected_event_ids = [1, 2] +expect_shard_failures = false + + +# this query doesn't touch the "broken" field, so it should not fail +[[queries]] +name = "sequenceQueryNoShardFailuresAllowTrue" +query = ''' +sequence + [process where serial_event_id == 1] + [process where serial_event_id == 2] +''' +allow_partial_search_results = true +expected_event_ids = [1, 2] +expect_shard_failures = false + + +[[queries]] +name = "sequenceQueryMissingShards" +query = ''' +sequence + [process where serial_event_id == 1 or broken == 1] + [process where serial_event_id == 2] +''' +allow_partial_search_results = true +expected_event_ids = [] +expect_shard_failures = true + + +[[queries]] +name = "sequenceQueryMissingShardsPartialResults" +query = ''' +sequence + [process where serial_event_id == 1 or broken == 1] + [process where serial_event_id == 2] +''' +allow_partial_search_results = true +allow_partial_sequence_results = true +expected_event_ids = [1, 2] +expect_shard_failures = true + + +[[queries]] +name = "sequenceQueryMissingShardsPartialResultsOptional" +query = ''' +sequence + [process where ?serial_event_id == 1 or broken == 1] + [process where serial_event_id == 2] +''' +allow_partial_search_results = true +allow_partial_sequence_results = true +expected_event_ids = [1, 2] +expect_shard_failures = true + + +[[queries]] +name = "sequenceQueryMissingShardsPartialResultsOptional2" +query = ''' +sequence with maxspan=100000d + [process where serial_event_id == 1 and ?subtype == "create" or broken == 1] + [process where serial_event_id == 2] +''' +allow_partial_search_results = true +allow_partial_sequence_results = true +expected_event_ids = [1, 2] +expect_shard_failures = true + + +[[queries]] +name = "sequenceQueryMissingShardsPartialResultsOptionalMissing" +query = ''' +sequence with maxspan=100000d + [process where serial_event_id == 1 and ?subtype == "create"] + ![process where broken == 1] + [process where serial_event_id == 2] +''' +allow_partial_search_results = true +allow_partial_sequence_results = true +expected_event_ids = [1, -1, 2] +expect_shard_failures = true + + +[[queries]] +name = "sequenceQueryMissingShardsPartialResultsOptionalMissing2" +query = ''' +sequence with maxspan=100000d + [process where serial_event_id == 1 and ?subtype == "create" or broken == 1] + ![process where broken == 1] + [process where serial_event_id == 2] +''' +allow_partial_search_results = true +allow_partial_sequence_results = true +expected_event_ids = [1, -1, 2] +expect_shard_failures = true + + +[[queries]] +name = "sampleQueryMissingShardsPartialResults" +query = ''' +sample by event_subtype_full + [process where serial_event_id == 1 or broken == 1] + [process where serial_event_id == 2] +''' +allow_partial_search_results = true +expected_event_ids = [1, 2] +expect_shard_failures = true + + +[[queries]] +name = "sampleQueryMissingShardsPartialResultsOptional" +query = ''' +sample by event_subtype_full + [process where serial_event_id == 1 and ?subtype == "create" or broken == 1] + [process where serial_event_id == 2] +''' +allow_partial_search_results = true +expected_event_ids = [1, 2] +expect_shard_failures = true + diff --git a/x-pack/plugin/eql/qa/mixed-node/src/javaRestTest/java/org/elasticsearch/xpack/eql/qa/mixed_node/EqlSearchIT.java b/x-pack/plugin/eql/qa/mixed-node/src/javaRestTest/java/org/elasticsearch/xpack/eql/qa/mixed_node/EqlSearchIT.java index 2a29572374fa8..60c7fb1c7ad25 100644 --- a/x-pack/plugin/eql/qa/mixed-node/src/javaRestTest/java/org/elasticsearch/xpack/eql/qa/mixed_node/EqlSearchIT.java +++ b/x-pack/plugin/eql/qa/mixed-node/src/javaRestTest/java/org/elasticsearch/xpack/eql/qa/mixed_node/EqlSearchIT.java @@ -407,7 +407,16 @@ private void assertMultiValueFunctionQuery( for (int id : ids) { eventIds.add(String.valueOf(id)); } - request.setJsonEntity("{\"query\":\"" + query + "\"}"); + + StringBuilder payload = new StringBuilder("{\"query\":\"" + query + "\""); + if (randomBoolean()) { + payload.append(", \"allow_partial_search_results\": true"); + } + if (randomBoolean()) { + payload.append(", \"allow_partial_sequence_results\": true"); + } + payload.append("}"); + request.setJsonEntity(payload.toString()); assertResponse(query, eventIds, runEql(client, request)); testedFunctions.add(functionName); } diff --git a/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlDateNanosIT.java b/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlDateNanosIT.java index c20968871472f..5d6824232d80f 100644 --- a/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlDateNanosIT.java +++ b/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlDateNanosIT.java @@ -37,7 +37,28 @@ protected String getRemoteCluster() { return REMOTE_CLUSTER.getHttpAddresses(); } - public EqlDateNanosIT(String query, String name, List eventIds, String[] joinKeys, Integer size, Integer maxSamplesPerKey) { - super(remoteClusterIndex(TEST_NANOS_INDEX), query, name, eventIds, joinKeys, size, maxSamplesPerKey); + public EqlDateNanosIT( + String query, + String name, + List eventIds, + String[] joinKeys, + Integer size, + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures + ) { + super( + remoteClusterIndex(TEST_NANOS_INDEX), + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } } diff --git a/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlExtraIT.java b/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlExtraIT.java index 774c19d02adf0..79b095434814b 100644 --- a/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlExtraIT.java +++ b/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlExtraIT.java @@ -37,7 +37,28 @@ protected String getRemoteCluster() { return REMOTE_CLUSTER.getHttpAddresses(); } - public EqlExtraIT(String query, String name, List eventIds, String[] joinKeys, Integer size, Integer maxSamplesPerKey) { - super(remoteClusterIndex(TEST_EXTRA_INDEX), query, name, eventIds, joinKeys, size, maxSamplesPerKey); + public EqlExtraIT( + String query, + String name, + List eventIds, + String[] joinKeys, + Integer size, + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures + ) { + super( + remoteClusterIndex(TEST_EXTRA_INDEX), + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } } diff --git a/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSampleIT.java b/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSampleIT.java index 1502c250bd058..7673eec32ec55 100644 --- a/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSampleIT.java +++ b/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSampleIT.java @@ -37,7 +37,28 @@ protected String getRemoteCluster() { return REMOTE_CLUSTER.getHttpAddresses(); } - public EqlSampleIT(String query, String name, List eventIds, String[] joinKeys, Integer size, Integer maxSamplesPerKey) { - super(remoteClusterPattern(TEST_SAMPLE), query, name, eventIds, joinKeys, size, maxSamplesPerKey); + public EqlSampleIT( + String query, + String name, + List eventIds, + String[] joinKeys, + Integer size, + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures + ) { + super( + remoteClusterPattern(TEST_SAMPLE), + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } } diff --git a/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSampleMultipleEntriesIT.java b/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSampleMultipleEntriesIT.java index 795fe4e103a31..ac6f7fe508c99 100644 --- a/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSampleMultipleEntriesIT.java +++ b/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSampleMultipleEntriesIT.java @@ -43,8 +43,22 @@ public EqlSampleMultipleEntriesIT( List eventIds, String[] joinKeys, Integer size, - Integer maxSamplesPerKey + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures ) { - super(remoteClusterPattern(TEST_SAMPLE_MULTI), query, name, eventIds, joinKeys, size, maxSamplesPerKey); + super( + remoteClusterPattern(TEST_SAMPLE_MULTI), + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } } diff --git a/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSpecIT.java b/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSpecIT.java index 2cddecb644a1a..db0c03e8fdb6f 100644 --- a/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSpecIT.java +++ b/x-pack/plugin/eql/qa/multi-cluster-with-security/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSpecIT.java @@ -37,7 +37,28 @@ protected String getRemoteCluster() { return REMOTE_CLUSTER.getHttpAddresses(); } - public EqlSpecIT(String query, String name, List eventIds, String[] joinKeys, Integer size, Integer maxSamplesPerKey) { - super(remoteClusterIndex(TEST_INDEX), query, name, eventIds, joinKeys, size, maxSamplesPerKey); + public EqlSpecIT( + String query, + String name, + List eventIds, + String[] joinKeys, + Integer size, + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures + ) { + super( + remoteClusterIndex(TEST_INDEX), + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } } diff --git a/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlDateNanosIT.java b/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlDateNanosIT.java index 1df10fde7fde5..5e1fa224de58d 100644 --- a/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlDateNanosIT.java +++ b/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlDateNanosIT.java @@ -27,7 +27,27 @@ protected String getTestRestCluster() { return cluster.getHttpAddresses(); } - public EqlDateNanosIT(String query, String name, List eventIds, String[] joinKeys, Integer size, Integer maxSamplesPerKey) { - super(query, name, eventIds, joinKeys, size, maxSamplesPerKey); + public EqlDateNanosIT( + String query, + String name, + List eventIds, + String[] joinKeys, + Integer size, + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures + ) { + super( + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } } diff --git a/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlExtraIT.java b/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlExtraIT.java index 8af8fcac087b5..cb92eddeb0410 100644 --- a/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlExtraIT.java +++ b/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlExtraIT.java @@ -27,7 +27,27 @@ protected String getTestRestCluster() { return cluster.getHttpAddresses(); } - public EqlExtraIT(String query, String name, List eventIds, String[] joinKeys, Integer size, Integer maxSamplesPerKey) { - super(query, name, eventIds, joinKeys, size, maxSamplesPerKey); + public EqlExtraIT( + String query, + String name, + List eventIds, + String[] joinKeys, + Integer size, + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures + ) { + super( + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } } diff --git a/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlMissingEventsIT.java b/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlMissingEventsIT.java index 05557fb4883b3..4f1faf3322e7f 100644 --- a/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlMissingEventsIT.java +++ b/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlMissingEventsIT.java @@ -27,8 +27,28 @@ protected String getTestRestCluster() { return cluster.getHttpAddresses(); } - public EqlMissingEventsIT(String query, String name, List eventIds, String[] joinKeys, Integer size, Integer maxSamplesPerKey) { - super(query, name, eventIds, joinKeys, size, maxSamplesPerKey); + public EqlMissingEventsIT( + String query, + String name, + List eventIds, + String[] joinKeys, + Integer size, + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures + ) { + super( + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } } diff --git a/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSampleIT.java b/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSampleIT.java index dc2c653fad89e..c0bce3ffc9e4f 100644 --- a/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSampleIT.java +++ b/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSampleIT.java @@ -27,8 +27,28 @@ protected String getTestRestCluster() { return cluster.getHttpAddresses(); } - public EqlSampleIT(String query, String name, List eventIds, String[] joinKeys, Integer size, Integer maxSamplesPerKey) { - super(query, name, eventIds, joinKeys, size, maxSamplesPerKey); + public EqlSampleIT( + String query, + String name, + List eventIds, + String[] joinKeys, + Integer size, + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures + ) { + super( + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } } diff --git a/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSampleMultipleEntriesIT.java b/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSampleMultipleEntriesIT.java index af1ade9120bbd..f50ee36095ae0 100644 --- a/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSampleMultipleEntriesIT.java +++ b/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSampleMultipleEntriesIT.java @@ -33,9 +33,22 @@ public EqlSampleMultipleEntriesIT( List eventIds, String[] joinKeys, Integer size, - Integer maxSamplesPerKey + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures ) { - super(query, name, eventIds, joinKeys, size, maxSamplesPerKey); + super( + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } } diff --git a/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSpecFailingShardsIT.java b/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSpecFailingShardsIT.java new file mode 100644 index 0000000000000..cf05811a77857 --- /dev/null +++ b/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSpecFailingShardsIT.java @@ -0,0 +1,53 @@ +/* + * 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.eql; + +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters; + +import org.elasticsearch.test.TestClustersThreadFilter; +import org.elasticsearch.test.cluster.ElasticsearchCluster; +import org.elasticsearch.test.eql.EqlSpecFailingShardsTestCase; +import org.junit.ClassRule; + +import java.util.List; + +@ThreadLeakFilters(filters = TestClustersThreadFilter.class) +public class EqlSpecFailingShardsIT extends EqlSpecFailingShardsTestCase { + + @ClassRule + public static final ElasticsearchCluster cluster = EqlTestCluster.CLUSTER; + + @Override + protected String getTestRestCluster() { + return cluster.getHttpAddresses(); + } + + public EqlSpecFailingShardsIT( + String query, + String name, + List eventIds, + String[] joinKeys, + Integer size, + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures + ) { + super( + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); + } +} diff --git a/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSpecIT.java b/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSpecIT.java index 7aac0ae336c8a..0aad5cc1b73da 100644 --- a/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSpecIT.java +++ b/x-pack/plugin/eql/qa/rest/src/javaRestTest/java/org/elasticsearch/xpack/eql/EqlSpecIT.java @@ -27,7 +27,27 @@ protected String getTestRestCluster() { return cluster.getHttpAddresses(); } - public EqlSpecIT(String query, String name, List eventIds, String[] joinKeys, Integer size, Integer maxSamplesPerKey) { - super(query, name, eventIds, joinKeys, size, maxSamplesPerKey); + public EqlSpecIT( + String query, + String name, + List eventIds, + String[] joinKeys, + Integer size, + Integer maxSamplesPerKey, + Boolean allowPartialSearchResults, + Boolean allowPartialSequenceResults, + Boolean expectShardFailures + ) { + super( + query, + name, + eventIds, + joinKeys, + size, + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults, + expectShardFailures + ); } } diff --git a/x-pack/plugin/eql/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/eql/10_basic.yml b/x-pack/plugin/eql/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/eql/10_basic.yml index e49264d76d5e9..c7974f3b584b4 100644 --- a/x-pack/plugin/eql/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/eql/10_basic.yml +++ b/x-pack/plugin/eql/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/eql/10_basic.yml @@ -83,6 +83,34 @@ setup: id: 123 valid: true + - do: + indices.create: + index: eql_test_rebel + body: + mappings: + properties: + some_keyword: + type: keyword + runtime: + day_of_week: + type: keyword + script: + source: "throw new IllegalArgumentException(\"rebel shards\")" + - do: + bulk: + refresh: true + body: + - index: + _index: eql_test_rebel + _id: "1" + - event: + - category: process + "@timestamp": 2020-02-03T12:34:56Z + user: SYSTEM + id: 123 + valid: false + some_keyword: longer than normal + --- # Testing round-trip and the basic shape of the response "Execute some EQL.": @@ -478,3 +506,118 @@ setup: query: 'sequence with maxspan=10d [network where user == "ADMIN"] ![network where used == "SYSTEM"]' - match: { error.root_cause.0.type: "verification_exception" } - match: { error.root_cause.0.reason: "Found 1 problem\nline 1:75: Unknown column [used], did you mean [user]?" } + + +--- +"Execute query shard failures and with allow_partial_search_results": + - do: + eql.search: + index: eql_test* + body: + query: 'process where user == "SYSTEM" and day_of_week == "Monday"' + fields: [{"field":"@timestamp","format":"epoch_millis"},"id","valid","day_of_week"] + allow_partial_search_results: true + + - match: {timed_out: false} + - match: {hits.total.value: 1} + - match: {hits.total.relation: "eq"} + - match: {hits.events.0._source.user: "SYSTEM"} + - match: {hits.events.0._id: "1"} + - match: {hits.events.0.fields.@timestamp: ["1580733296000"]} + - match: {hits.events.0.fields.id: [123]} + - match: {hits.events.0.fields.valid: [false]} + - match: {hits.events.0.fields.day_of_week: ["Monday"]} + - match: {shard_failures.0.index: "eql_test_rebel"} + + +--- +"Execute query shard failures and with allow_partial_search_results as request param": + - do: + eql.search: + index: eql_test* + allow_partial_search_results: true + body: + query: 'process where user == "SYSTEM" and day_of_week == "Monday"' + fields: [{"field":"@timestamp","format":"epoch_millis"},"id","valid","day_of_week"] + + - match: {timed_out: false} + - match: {hits.total.value: 1} + - match: {hits.total.relation: "eq"} + - match: {hits.events.0._source.user: "SYSTEM"} + - match: {hits.events.0._id: "1"} + - match: {hits.events.0.fields.@timestamp: ["1580733296000"]} + - match: {hits.events.0.fields.id: [123]} + - match: {hits.events.0.fields.valid: [false]} + - match: {hits.events.0.fields.day_of_week: ["Monday"]} + - match: {shard_failures.0.index: "eql_test_rebel"} + + +--- +"Execute sequence with shard failures and allow_partial_search_results=true": + - do: + eql.search: + index: eql_test* + body: + query: 'sequence [process where user == "SYSTEM" and day_of_week == "Monday"] [process where user == "SYSTEM" and day_of_week == "Tuesday"]' + fields: [{"field":"@timestamp","format":"epoch_millis"},"id","valid","day_of_week"] + allow_partial_search_results: true + + - match: {timed_out: false} + - match: {hits.total.value: 0} + - match: {shard_failures.0.index: "eql_test_rebel"} + + +--- +"Execute sequence with shard failures, allow_partial_search_results=true and allow_partial_sequence_results=true": + - do: + eql.search: + index: eql_test* + body: + query: 'sequence [process where user == "SYSTEM" and day_of_week == "Monday"] [process where user == "SYSTEM" and day_of_week == "Tuesday"]' + fields: [{"field":"@timestamp","format":"epoch_millis"},"id","valid","day_of_week"] + allow_partial_search_results: true + allow_partial_sequence_results: true + + - match: {timed_out: false} + - match: {hits.total.value: 1} + - match: {hits.total.relation: "eq"} + - match: {hits.sequences.0.events.0._source.user: "SYSTEM"} + - match: {hits.sequences.0.events.0._id: "1"} + - match: {hits.sequences.0.events.0.fields.@timestamp: ["1580733296000"]} + - match: {hits.sequences.0.events.0.fields.id: [123]} + - match: {hits.sequences.0.events.0.fields.valid: [false]} + - match: {hits.sequences.0.events.0.fields.day_of_week: ["Monday"]} + - match: {hits.sequences.0.events.1._id: "2"} + - match: {hits.sequences.0.events.1.fields.@timestamp: ["1580819696000"]} + - match: {hits.sequences.0.events.1.fields.id: [123]} + - match: {hits.sequences.0.events.1.fields.valid: [true]} + - match: {hits.sequences.0.events.1.fields.day_of_week: ["Tuesday"]} + - match: {shard_failures.0.index: "eql_test_rebel"} + + +--- +"Execute sequence with shard failures, allow_partial_search_results=true and allow_partial_sequence_results=true as query params": + - do: + eql.search: + index: eql_test* + allow_partial_search_results: true + allow_partial_sequence_results: true + body: + query: 'sequence [process where user == "SYSTEM" and day_of_week == "Monday"] [process where user == "SYSTEM" and day_of_week == "Tuesday"]' + fields: [{"field":"@timestamp","format":"epoch_millis"},"id","valid","day_of_week"] + + - match: {timed_out: false} + - match: {hits.total.value: 1} + - match: {hits.total.relation: "eq"} + - match: {hits.sequences.0.events.0._source.user: "SYSTEM"} + - match: {hits.sequences.0.events.0._id: "1"} + - match: {hits.sequences.0.events.0.fields.@timestamp: ["1580733296000"]} + - match: {hits.sequences.0.events.0.fields.id: [123]} + - match: {hits.sequences.0.events.0.fields.valid: [false]} + - match: {hits.sequences.0.events.0.fields.day_of_week: ["Monday"]} + - match: {hits.sequences.0.events.1._id: "2"} + - match: {hits.sequences.0.events.1.fields.@timestamp: ["1580819696000"]} + - match: {hits.sequences.0.events.1.fields.id: [123]} + - match: {hits.sequences.0.events.1.fields.valid: [true]} + - match: {hits.sequences.0.events.1.fields.day_of_week: ["Tuesday"]} + - match: {shard_failures.0.index: "eql_test_rebel"} diff --git a/x-pack/plugin/eql/src/internalClusterTest/java/org/elasticsearch/xpack/eql/action/CCSPartialResultsIT.java b/x-pack/plugin/eql/src/internalClusterTest/java/org/elasticsearch/xpack/eql/action/CCSPartialResultsIT.java new file mode 100644 index 0000000000000..da6bb6180428b --- /dev/null +++ b/x-pack/plugin/eql/src/internalClusterTest/java/org/elasticsearch/xpack/eql/action/CCSPartialResultsIT.java @@ -0,0 +1,613 @@ +/* + * 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.eql.action; + +import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsAction; +import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest; +import org.elasticsearch.client.internal.Client; +import org.elasticsearch.cluster.metadata.IndexMetadata; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.core.TimeValue; +import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.test.AbstractMultiClustersTestCase; +import org.elasticsearch.xpack.eql.plugin.EqlPlugin; + +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; + +public class CCSPartialResultsIT extends AbstractMultiClustersTestCase { + + static String REMOTE_CLUSTER = "cluster_a"; + + protected Collection> nodePlugins(String cluster) { + return Collections.singletonList(LocalStateEQLXPackPlugin.class); + } + + protected final Client localClient() { + return client(LOCAL_CLUSTER); + } + + @Override + protected List remoteClusterAlias() { + return List.of(REMOTE_CLUSTER); + } + + @Override + protected boolean reuseClusters() { + return false; + } + + /** + * + * @return remote node name + */ + private String createSchema() { + final Client remoteClient = client(REMOTE_CLUSTER); + final String remoteNode = cluster(REMOTE_CLUSTER).startDataOnlyNode(); + final String remoteNode2 = cluster(REMOTE_CLUSTER).startDataOnlyNode(); + + assertAcked( + remoteClient.admin() + .indices() + .prepareCreate("test-1-remote") + .setSettings( + Settings.builder() + .put("index.routing.allocation.require._name", remoteNode) + .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0) + .build() + ) + .setMapping("@timestamp", "type=date"), + TimeValue.timeValueSeconds(60) + ); + + assertAcked( + remoteClient.admin() + .indices() + .prepareCreate("test-2-remote") + .setSettings( + Settings.builder() + .put("index.routing.allocation.require._name", remoteNode2) + .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0) + .build() + ) + .setMapping("@timestamp", "type=date"), + TimeValue.timeValueSeconds(60) + ); + + for (int i = 0; i < 5; i++) { + int val = i * 2; + remoteClient.prepareIndex("test-1-remote") + .setId(Integer.toString(i)) + .setSource("@timestamp", 100000 + val, "event.category", "process", "key", "same", "value", val) + .get(); + } + for (int i = 0; i < 5; i++) { + int val = i * 2 + 1; + remoteClient.prepareIndex("test-2-remote") + .setId(Integer.toString(i)) + .setSource("@timestamp", 100000 + val, "event.category", "process", "key", "same", "value", val) + .get(); + } + + remoteClient.admin().indices().prepareRefresh().get(); + return remoteNode; + } + + // ------------------------------------------------------------------------ + // queries with full cluster (no missing shards) + // ------------------------------------------------------------------------ + + public void testNoFailures() throws ExecutionException, InterruptedException, IOException { + createSchema(); + + // event query + var request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("process where true") + .allowPartialSearchResults(randomBoolean()) + .allowPartialSequenceResults(randomBoolean()); + EqlSearchResponse response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().events().size(), equalTo(10)); + for (int i = 0; i < 10; i++) { + assertThat(response.hits().events().get(i).toString(), containsString("\"value\" : " + i)); + } + assertThat(response.shardFailures().length, is(0)); + + // sequence query on both shards + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sequence [process where value == 1] [process where value == 2]") + .allowPartialSearchResults(randomBoolean()) + .allowPartialSequenceResults(randomBoolean()); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + EqlSearchResponse.Sequence sequence = response.hits().sequences().get(0); + assertThat(sequence.events().get(0).toString(), containsString("\"value\" : 1")); + assertThat(sequence.events().get(1).toString(), containsString("\"value\" : 2")); + assertThat(response.shardFailures().length, is(0)); + + // sequence query on the available shard only + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sequence [process where value == 1] [process where value == 3]") + .allowPartialSearchResults(randomBoolean()) + .allowPartialSequenceResults(randomBoolean()); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + sequence = response.hits().sequences().get(0); + assertThat(sequence.events().get(0).toString(), containsString("\"value\" : 1")); + assertThat(sequence.events().get(1).toString(), containsString("\"value\" : 3")); + assertThat(response.shardFailures().length, is(0)); + + // sequence query on the unavailable shard only + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sequence [process where value == 0] [process where value == 2]") + .allowPartialSearchResults(randomBoolean()) + .allowPartialSequenceResults(randomBoolean()); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + sequence = response.hits().sequences().get(0); + assertThat(sequence.events().get(0).toString(), containsString("\"value\" : 0")); + assertThat(sequence.events().get(1).toString(), containsString("\"value\" : 2")); + assertThat(response.shardFailures().length, is(0)); + + // sequence query with missing event on unavailable shard + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sequence with maxspan=10s [process where value == 1] ![process where value == 2] [process where value == 3]") + .allowPartialSearchResults(randomBoolean()) + .allowPartialSequenceResults(randomBoolean()); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(0)); + + // sample query on both shards + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sample by key [process where value == 2] [process where value == 1]") + .allowPartialSearchResults(randomBoolean()) + .allowPartialSequenceResults(randomBoolean()); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + EqlSearchResponse.Sequence sample = response.hits().sequences().get(0); + assertThat(sample.events().get(0).toString(), containsString("\"value\" : 2")); + assertThat(sample.events().get(1).toString(), containsString("\"value\" : 1")); + assertThat(response.shardFailures().length, is(0)); + + // sample query on the available shard only + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sample by key [process where value == 3] [process where value == 1]") + .allowPartialSearchResults(randomBoolean()) + .allowPartialSequenceResults(randomBoolean()); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + sample = response.hits().sequences().get(0); + assertThat(sample.events().get(0).toString(), containsString("\"value\" : 3")); + assertThat(sample.events().get(1).toString(), containsString("\"value\" : 1")); + assertThat(response.shardFailures().length, is(0)); + + // sample query on the unavailable shard only + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sample by key [process where value == 2] [process where value == 0]") + .allowPartialSearchResults(randomBoolean()) + .allowPartialSequenceResults(randomBoolean()); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + sample = response.hits().sequences().get(0); + assertThat(sample.events().get(0).toString(), containsString("\"value\" : 2")); + assertThat(sample.events().get(1).toString(), containsString("\"value\" : 0")); + assertThat(response.shardFailures().length, is(0)); + + } + + // ------------------------------------------------------------------------ + // same queries, with missing shards and allow_partial_search_results=true + // and allow_partial_sequence_result=true + // ------------------------------------------------------------------------ + + public void testAllowPartialSearchAndSequence_event() throws ExecutionException, InterruptedException, IOException { + var remoteNode = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + cluster(REMOTE_CLUSTER).stopNode(remoteNode); + + // event query + var request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("process where true") + .allowPartialSearchResults(true); + var response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().events().size(), equalTo(5)); + for (int i = 0; i < 5; i++) { + assertThat(response.hits().events().get(i).toString(), containsString("\"value\" : " + (i * 2 + 1))); + } + assertThat(response.shardFailures().length, is(1)); + } + + public void testAllowPartialSearchAndSequence_sequence() throws ExecutionException, InterruptedException, IOException { + var remoteNode = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + cluster(REMOTE_CLUSTER).stopNode(remoteNode); + + // sequence query on both shards + var request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sequence [process where value == 1] [process where value == 2]") + .allowPartialSearchResults(true) + .allowPartialSequenceResults(true); + var response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query on the available shard only + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sequence [process where value == 1] [process where value == 3]") + .allowPartialSearchResults(true) + .allowPartialSequenceResults(true); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + var sequence = response.hits().sequences().get(0); + assertThat(sequence.events().get(0).toString(), containsString("\"value\" : 1")); + assertThat(sequence.events().get(1).toString(), containsString("\"value\" : 3")); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query on the unavailable shard only + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sequence [process where value == 0] [process where value == 2]") + .allowPartialSearchResults(true) + .allowPartialSequenceResults(true); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query with missing event on unavailable shard. THIS IS A FALSE POSITIVE + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sequence with maxspan=10s [process where value == 1] ![process where value == 2] [process where value == 3]") + .allowPartialSearchResults(true) + .allowPartialSequenceResults(true); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + sequence = response.hits().sequences().get(0); + assertThat(sequence.events().get(0).toString(), containsString("\"value\" : 1")); + assertThat(sequence.events().get(2).toString(), containsString("\"value\" : 3")); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + } + + public void testAllowPartialSearchAndSequence_sample() throws ExecutionException, InterruptedException, IOException { + var remoteNode = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + cluster(REMOTE_CLUSTER).stopNode(remoteNode); + + // sample query on both shards + var request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sample by key [process where value == 2] [process where value == 1]") + .allowPartialSearchResults(true) + .allowPartialSequenceResults(true); + var response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sample query on the available shard only + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sample by key [process where value == 3] [process where value == 1]") + .allowPartialSearchResults(true) + .allowPartialSequenceResults(true); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + var sample = response.hits().sequences().get(0); + assertThat(sample.events().get(0).toString(), containsString("\"value\" : 3")); + assertThat(sample.events().get(1).toString(), containsString("\"value\" : 1")); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sample query on the unavailable shard only + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sample by key [process where value == 2] [process where value == 0]") + .allowPartialSearchResults(true) + .allowPartialSequenceResults(true); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + } + + // ------------------------------------------------------------------------ + // same queries, with missing shards and allow_partial_search_results=true + // and default allow_partial_sequence_results (ie. false) + // ------------------------------------------------------------------------ + + public void testAllowPartialSearch_event() throws ExecutionException, InterruptedException, IOException { + var remoteNode = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + cluster(REMOTE_CLUSTER).stopNode(remoteNode); + + // event query + var request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("process where true") + .allowPartialSearchResults(true); + var response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().events().size(), equalTo(5)); + for (int i = 0; i < 5; i++) { + assertThat(response.hits().events().get(i).toString(), containsString("\"value\" : " + (i * 2 + 1))); + } + assertThat(response.shardFailures().length, is(1)); + + } + + public void testAllowPartialSearch_sequence() throws ExecutionException, InterruptedException, IOException { + var remoteNode = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + cluster(REMOTE_CLUSTER).stopNode(remoteNode); + + // sequence query on both shards + var request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sequence [process where value == 1] [process where value == 2]") + .allowPartialSearchResults(true); + var response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query on the available shard only + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sequence [process where value == 1] [process where value == 3]") + .allowPartialSearchResults(true); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query on the unavailable shard only + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sequence [process where value == 0] [process where value == 2]") + .allowPartialSearchResults(true); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query with missing event on unavailable shard. THIS IS A FALSE POSITIVE + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sequence with maxspan=10s [process where value == 1] ![process where value == 2] [process where value == 3]") + .allowPartialSearchResults(true); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + } + + public void testAllowPartialSearch_sample() throws ExecutionException, InterruptedException, IOException { + var remoteNode = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + cluster(REMOTE_CLUSTER).stopNode(remoteNode); + + // sample query on both shards + var request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sample by key [process where value == 2] [process where value == 1]") + .allowPartialSearchResults(true); + var response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sample query on the available shard only + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sample by key [process where value == 3] [process where value == 1]") + .allowPartialSearchResults(true); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + var sample = response.hits().sequences().get(0); + assertThat(sample.events().get(0).toString(), containsString("\"value\" : 3")); + assertThat(sample.events().get(1).toString(), containsString("\"value\" : 1")); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sample query on the unavailable shard only + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sample by key [process where value == 2] [process where value == 0]") + .allowPartialSearchResults(true); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + } + + // ------------------------------------------------------------------------ + // same queries, with missing shards and with default xpack.eql.default_allow_partial_results=true + // ------------------------------------------------------------------------ + + public void testClusterSetting_event() throws ExecutionException, InterruptedException, IOException { + var remoteNode = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + cluster(REMOTE_CLUSTER).stopNode(remoteNode); + + cluster(REMOTE_CLUSTER).client() + .execute( + ClusterUpdateSettingsAction.INSTANCE, + new ClusterUpdateSettingsRequest(TimeValue.THIRTY_SECONDS, TimeValue.THIRTY_SECONDS).persistentSettings( + Settings.builder().put(EqlPlugin.DEFAULT_ALLOW_PARTIAL_SEARCH_RESULTS.getKey(), true) + ) + ) + .get(); + + // event query + var request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*").query("process where true"); + var response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().events().size(), equalTo(5)); + for (int i = 0; i < 5; i++) { + assertThat(response.hits().events().get(i).toString(), containsString("\"value\" : " + (i * 2 + 1))); + } + assertThat(response.shardFailures().length, is(1)); + + localClient().execute( + ClusterUpdateSettingsAction.INSTANCE, + new ClusterUpdateSettingsRequest(TimeValue.THIRTY_SECONDS, TimeValue.THIRTY_SECONDS).persistentSettings( + Settings.builder().putNull(EqlPlugin.DEFAULT_ALLOW_PARTIAL_SEARCH_RESULTS.getKey()) + ) + ).get(); + } + + public void testClusterSetting_sequence() throws ExecutionException, InterruptedException, IOException { + var remoteNode = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + cluster(REMOTE_CLUSTER).stopNode(remoteNode); + + cluster(REMOTE_CLUSTER).client() + .execute( + ClusterUpdateSettingsAction.INSTANCE, + new ClusterUpdateSettingsRequest(TimeValue.THIRTY_SECONDS, TimeValue.THIRTY_SECONDS).persistentSettings( + Settings.builder().put(EqlPlugin.DEFAULT_ALLOW_PARTIAL_SEARCH_RESULTS.getKey(), true) + ) + ) + .get(); + // sequence query on both shards + var request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sequence [process where value == 1] [process where value == 2]"); + var response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query on the available shard only + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sequence [process where value == 1] [process where value == 3]"); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query on the unavailable shard only + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sequence [process where value == 0] [process where value == 2]"); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query with missing event on unavailable shard. THIS IS A FALSE POSITIVE + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sequence with maxspan=10s [process where value == 1] ![process where value == 2] [process where value == 3]"); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + localClient().execute( + ClusterUpdateSettingsAction.INSTANCE, + new ClusterUpdateSettingsRequest(TimeValue.THIRTY_SECONDS, TimeValue.THIRTY_SECONDS).persistentSettings( + Settings.builder().putNull(EqlPlugin.DEFAULT_ALLOW_PARTIAL_SEARCH_RESULTS.getKey()) + ) + ).get(); + } + + public void testClusterSetting_sample() throws ExecutionException, InterruptedException, IOException { + var remoteNode = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + cluster(REMOTE_CLUSTER).stopNode(remoteNode); + + cluster(REMOTE_CLUSTER).client() + .execute( + ClusterUpdateSettingsAction.INSTANCE, + new ClusterUpdateSettingsRequest(TimeValue.THIRTY_SECONDS, TimeValue.THIRTY_SECONDS).persistentSettings( + Settings.builder().put(EqlPlugin.DEFAULT_ALLOW_PARTIAL_SEARCH_RESULTS.getKey(), true) + ) + ) + .get(); + + // sample query on both shards + var request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sample by key [process where value == 2] [process where value == 1]"); + var response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sample query on the available shard only + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sample by key [process where value == 3] [process where value == 1]"); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + var sample = response.hits().sequences().get(0); + assertThat(sample.events().get(0).toString(), containsString("\"value\" : 3")); + assertThat(sample.events().get(1).toString(), containsString("\"value\" : 1")); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sample query on the unavailable shard only + request = new EqlSearchRequest().indices(REMOTE_CLUSTER + ":test-*") + .query("sample by key [process where value == 2] [process where value == 0]"); + response = localClient().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1-remote")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + localClient().execute( + ClusterUpdateSettingsAction.INSTANCE, + new ClusterUpdateSettingsRequest(TimeValue.THIRTY_SECONDS, TimeValue.THIRTY_SECONDS).persistentSettings( + Settings.builder().putNull(EqlPlugin.DEFAULT_ALLOW_PARTIAL_SEARCH_RESULTS.getKey()) + ) + ).get(); + } +} diff --git a/x-pack/plugin/eql/src/internalClusterTest/java/org/elasticsearch/xpack/eql/action/PartialSearchResultsIT.java b/x-pack/plugin/eql/src/internalClusterTest/java/org/elasticsearch/xpack/eql/action/PartialSearchResultsIT.java new file mode 100644 index 0000000000000..9048d11f4eddf --- /dev/null +++ b/x-pack/plugin/eql/src/internalClusterTest/java/org/elasticsearch/xpack/eql/action/PartialSearchResultsIT.java @@ -0,0 +1,780 @@ +/* + * 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.eql.action; + +import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsAction; +import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest; +import org.elasticsearch.action.search.SearchPhaseExecutionException; +import org.elasticsearch.cluster.metadata.IndexMetadata; +import org.elasticsearch.cluster.node.DiscoveryNode; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.util.CollectionUtils; +import org.elasticsearch.core.TimeValue; +import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.search.SearchService; +import org.elasticsearch.test.transport.MockTransportService; +import org.elasticsearch.xpack.core.async.GetAsyncResultRequest; +import org.elasticsearch.xpack.eql.plugin.EqlAsyncGetResultAction; +import org.elasticsearch.xpack.eql.plugin.EqlPlugin; + +import java.util.Collection; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; + +public class PartialSearchResultsIT extends AbstractEqlIntegTestCase { + + @Override + protected Collection> nodePlugins() { + return CollectionUtils.appendToCopy(super.nodePlugins(), MockTransportService.TestPlugin.class); + } + + @Override + protected Settings nodeSettings(int nodeOrdinal, Settings otherSettings) { + return Settings.builder() + .put(super.nodeSettings(nodeOrdinal, otherSettings)) + .put(SearchService.KEEPALIVE_INTERVAL_SETTING.getKey(), TimeValue.timeValueMillis(randomIntBetween(100, 500))) + .build(); + } + + /** + * + * @return node name where the first index is + */ + private String createSchema() { + internalCluster().ensureAtLeastNumDataNodes(2); + final List dataNodes = internalCluster().clusterService() + .state() + .nodes() + .getDataNodes() + .values() + .stream() + .map(DiscoveryNode::getName) + .toList(); + final String assignedNodeForIndex1 = randomFrom(dataNodes); + + assertAcked( + indicesAdmin().prepareCreate("test-1") + .setSettings( + Settings.builder() + .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0) + .put("index.routing.allocation.include._name", assignedNodeForIndex1) + .build() + ) + .setMapping("@timestamp", "type=date") + ); + assertAcked( + indicesAdmin().prepareCreate("test-2") + .setSettings( + Settings.builder() + .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0) + .put("index.routing.allocation.exclude._name", assignedNodeForIndex1) + .build() + ) + .setMapping("@timestamp", "type=date") + ); + + for (int i = 0; i < 5; i++) { + int val = i * 2; + prepareIndex("test-1").setId(Integer.toString(i)) + .setSource("@timestamp", 100000 + val, "event.category", "process", "key", "same", "value", val) + .get(); + } + for (int i = 0; i < 5; i++) { + int val = i * 2 + 1; + prepareIndex("test-2").setId(Integer.toString(i)) + .setSource("@timestamp", 100000 + val, "event.category", "process", "key", "same", "value", val) + .get(); + } + refresh(); + return assignedNodeForIndex1; + } + + public void testNoFailures() throws Exception { + createSchema(); + + // ------------------------------------------------------------------------ + // queries with full cluster (no missing shards) + // ------------------------------------------------------------------------ + + // event query + var request = new EqlSearchRequest().indices("test-*") + .query("process where true") + .allowPartialSearchResults(randomBoolean()) + .allowPartialSequenceResults(randomBoolean()); + EqlSearchResponse response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().events().size(), equalTo(10)); + for (int i = 0; i < 10; i++) { + assertThat(response.hits().events().get(i).toString(), containsString("\"value\" : " + i)); + } + assertThat(response.shardFailures().length, is(0)); + + // sequence query on both shards + request = new EqlSearchRequest().indices("test-*") + .query("sequence [process where value == 1] [process where value == 2]") + .allowPartialSearchResults(randomBoolean()) + .allowPartialSequenceResults(randomBoolean()); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + EqlSearchResponse.Sequence sequence = response.hits().sequences().get(0); + assertThat(sequence.events().get(0).toString(), containsString("\"value\" : 1")); + assertThat(sequence.events().get(1).toString(), containsString("\"value\" : 2")); + assertThat(response.shardFailures().length, is(0)); + + // sequence query on the available shard only + request = new EqlSearchRequest().indices("test-*") + .query("sequence [process where value == 1] [process where value == 3]") + .allowPartialSearchResults(randomBoolean()) + .allowPartialSequenceResults(randomBoolean()); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + sequence = response.hits().sequences().get(0); + assertThat(sequence.events().get(0).toString(), containsString("\"value\" : 1")); + assertThat(sequence.events().get(1).toString(), containsString("\"value\" : 3")); + assertThat(response.shardFailures().length, is(0)); + + // sequence query on the unavailable shard only + request = new EqlSearchRequest().indices("test-*") + .query("sequence [process where value == 0] [process where value == 2]") + .allowPartialSearchResults(randomBoolean()) + .allowPartialSequenceResults(randomBoolean()); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + sequence = response.hits().sequences().get(0); + assertThat(sequence.events().get(0).toString(), containsString("\"value\" : 0")); + assertThat(sequence.events().get(1).toString(), containsString("\"value\" : 2")); + assertThat(response.shardFailures().length, is(0)); + + // sequence query with missing event on unavailable shard + request = new EqlSearchRequest().indices("test-*") + .query("sequence with maxspan=10s [process where value == 1] ![process where value == 2] [process where value == 3]") + .allowPartialSearchResults(randomBoolean()) + .allowPartialSequenceResults(randomBoolean()); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(0)); + + // sample query on both shards + request = new EqlSearchRequest().indices("test-*") + .query("sample by key [process where value == 2] [process where value == 1]") + .allowPartialSearchResults(randomBoolean()) + .allowPartialSequenceResults(randomBoolean()); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + EqlSearchResponse.Sequence sample = response.hits().sequences().get(0); + assertThat(sample.events().get(0).toString(), containsString("\"value\" : 2")); + assertThat(sample.events().get(1).toString(), containsString("\"value\" : 1")); + assertThat(response.shardFailures().length, is(0)); + + // sample query on the available shard only + request = new EqlSearchRequest().indices("test-*") + .query("sample by key [process where value == 3] [process where value == 1]") + .allowPartialSearchResults(randomBoolean()) + .allowPartialSequenceResults(randomBoolean()); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + sample = response.hits().sequences().get(0); + assertThat(sample.events().get(0).toString(), containsString("\"value\" : 3")); + assertThat(sample.events().get(1).toString(), containsString("\"value\" : 1")); + assertThat(response.shardFailures().length, is(0)); + + // sample query on the unavailable shard only + request = new EqlSearchRequest().indices("test-*") + .query("sample by key [process where value == 2] [process where value == 0]") + .allowPartialSearchResults(randomBoolean()) + .allowPartialSequenceResults(randomBoolean()); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + sample = response.hits().sequences().get(0); + assertThat(sample.events().get(0).toString(), containsString("\"value\" : 2")); + assertThat(sample.events().get(1).toString(), containsString("\"value\" : 0")); + assertThat(response.shardFailures().length, is(0)); + + } + + // ------------------------------------------------------------------------ + // same queries, with missing shards. Let them fail + // allow_partial_sequence_results has no effect if allow_partial_sequence_results is not set to true. + // ------------------------------------------------------------------------ + + public void testFailures_event() throws Exception { + final String assignedNodeForIndex1 = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + internalCluster().stopNode(assignedNodeForIndex1); + + // event query + shouldFail("process where true"); + + } + + public void testFailures_sequence() throws Exception { + final String assignedNodeForIndex1 = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + internalCluster().stopNode(assignedNodeForIndex1); + + // sequence query on both shards + shouldFail("sequence [process where value == 1] [process where value == 2]"); + + // sequence query on the available shard only + shouldFail("sequence [process where value == 1] [process where value == 3]"); + + // sequence query on the unavailable shard only + shouldFail("sequence [process where value == 0] [process where value == 2]"); + + // sequence query with missing event on unavailable shard. + shouldFail("sequence with maxspan=10s [process where value == 1] ![process where value == 2] [process where value == 3]"); + } + + public void testFailures_sample() throws Exception { + final String assignedNodeForIndex1 = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + internalCluster().stopNode(assignedNodeForIndex1); + + // sample query on both shards + shouldFail("sample by key [process where value == 2] [process where value == 1]"); + + // sample query on the available shard only + shouldFail("sample by key [process where value == 3] [process where value == 1]"); + + // sample query on the unavailable shard only + shouldFail("sample by key [process where value == 2] [process where value == 0]"); + + } + + // ------------------------------------------------------------------------ + // same queries, with missing shards and allow_partial_search_results=true + // and allow_partial_sequence_result=true + // ------------------------------------------------------------------------ + + public void testAllowPartialSearchAndSequenceResults_event() throws Exception { + final String assignedNodeForIndex1 = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + internalCluster().stopNode(assignedNodeForIndex1); + + // event query + var request = new EqlSearchRequest().indices("test-*").query("process where true").allowPartialSearchResults(true); + var response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().events().size(), equalTo(5)); + for (int i = 0; i < 5; i++) { + assertThat(response.hits().events().get(i).toString(), containsString("\"value\" : " + (i * 2 + 1))); + } + assertThat(response.shardFailures().length, is(1)); + + } + + public void testAllowPartialSearchAndSequenceResults_sequence() throws Exception { + final String assignedNodeForIndex1 = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + internalCluster().stopNode(assignedNodeForIndex1); + + // sequence query on both shards + var request = new EqlSearchRequest().indices("test-*") + .query("sequence [process where value == 1] [process where value == 2]") + .allowPartialSearchResults(true) + .allowPartialSequenceResults(true); + var response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query on the available shard only + request = new EqlSearchRequest().indices("test-*") + .query("sequence [process where value == 1] [process where value == 3]") + .allowPartialSearchResults(true) + .allowPartialSequenceResults(true); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + var sequence = response.hits().sequences().get(0); + assertThat(sequence.events().get(0).toString(), containsString("\"value\" : 1")); + assertThat(sequence.events().get(1).toString(), containsString("\"value\" : 3")); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query on the unavailable shard only + request = new EqlSearchRequest().indices("test-*") + .query("sequence [process where value == 0] [process where value == 2]") + .allowPartialSearchResults(true) + .allowPartialSequenceResults(true); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query with missing event on unavailable shard. THIS IS A FALSE POSITIVE + request = new EqlSearchRequest().indices("test-*") + .query("sequence with maxspan=10s [process where value == 1] ![process where value == 2] [process where value == 3]") + .allowPartialSearchResults(true) + .allowPartialSequenceResults(true); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + sequence = response.hits().sequences().get(0); + assertThat(sequence.events().get(0).toString(), containsString("\"value\" : 1")); + assertThat(sequence.events().get(2).toString(), containsString("\"value\" : 3")); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + } + + public void testAllowPartialSearchAndSequenceResults_sample() throws Exception { + final String assignedNodeForIndex1 = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + internalCluster().stopNode(assignedNodeForIndex1); + + // sample query on both shards + var request = new EqlSearchRequest().indices("test-*") + .query("sample by key [process where value == 2] [process where value == 1]") + .allowPartialSearchResults(true) + .allowPartialSequenceResults(true); + var response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sample query on the available shard only + request = new EqlSearchRequest().indices("test-*") + .query("sample by key [process where value == 3] [process where value == 1]") + .allowPartialSearchResults(true) + .allowPartialSequenceResults(true); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + var sample = response.hits().sequences().get(0); + assertThat(sample.events().get(0).toString(), containsString("\"value\" : 3")); + assertThat(sample.events().get(1).toString(), containsString("\"value\" : 1")); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sample query on the unavailable shard only + request = new EqlSearchRequest().indices("test-*") + .query("sample by key [process where value == 2] [process where value == 0]") + .allowPartialSearchResults(true) + .allowPartialSequenceResults(true); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + } + + // ------------------------------------------------------------------------ + // same queries, with missing shards and allow_partial_search_results=true + // and default allow_partial_sequence_results (ie. false) + // ------------------------------------------------------------------------ + + public void testAllowPartialSearchResults_event() throws Exception { + final String assignedNodeForIndex1 = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + internalCluster().stopNode(assignedNodeForIndex1); + + // event query + var request = new EqlSearchRequest().indices("test-*").query("process where true").allowPartialSearchResults(true); + var response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().events().size(), equalTo(5)); + for (int i = 0; i < 5; i++) { + assertThat(response.hits().events().get(i).toString(), containsString("\"value\" : " + (i * 2 + 1))); + } + assertThat(response.shardFailures().length, is(1)); + + } + + public void testAllowPartialSearchResults_sequence() throws Exception { + final String assignedNodeForIndex1 = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + internalCluster().stopNode(assignedNodeForIndex1); + + // sequence query on both shards + var request = new EqlSearchRequest().indices("test-*") + .query("sequence [process where value == 1] [process where value == 2]") + .allowPartialSearchResults(true); + var response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query on the available shard only + request = new EqlSearchRequest().indices("test-*") + .query("sequence [process where value == 1] [process where value == 3]") + .allowPartialSearchResults(true); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query on the unavailable shard only + request = new EqlSearchRequest().indices("test-*") + .query("sequence [process where value == 0] [process where value == 2]") + .allowPartialSearchResults(true); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query with missing event on unavailable shard. THIS IS A FALSE POSITIVE + request = new EqlSearchRequest().indices("test-*") + .query("sequence with maxspan=10s [process where value == 1] ![process where value == 2] [process where value == 3]") + .allowPartialSearchResults(true); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + } + + public void testAllowPartialSearchResults_sample() throws Exception { + final String assignedNodeForIndex1 = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + internalCluster().stopNode(assignedNodeForIndex1); + + // sample query on both shards + var request = new EqlSearchRequest().indices("test-*") + .query("sample by key [process where value == 2] [process where value == 1]") + .allowPartialSearchResults(true); + var response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sample query on the available shard only + request = new EqlSearchRequest().indices("test-*") + .query("sample by key [process where value == 3] [process where value == 1]") + .allowPartialSearchResults(true); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + var sample = response.hits().sequences().get(0); + assertThat(sample.events().get(0).toString(), containsString("\"value\" : 3")); + assertThat(sample.events().get(1).toString(), containsString("\"value\" : 1")); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sample query on the unavailable shard only + request = new EqlSearchRequest().indices("test-*") + .query("sample by key [process where value == 2] [process where value == 0]") + .allowPartialSearchResults(true); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + } + + // ------------------------------------------------------------------------ + // same queries, this time async, with missing shards and allow_partial_search_results=true + // and default allow_partial_sequence_results (ie. false) + // ------------------------------------------------------------------------ + + public void testAsyncAllowPartialSearchResults_event() throws Exception { + final String assignedNodeForIndex1 = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + internalCluster().stopNode(assignedNodeForIndex1); + + // event query + var response = runAsync("process where true", true); + assertThat(response.hits().events().size(), equalTo(5)); + for (int i = 0; i < 5; i++) { + assertThat(response.hits().events().get(i).toString(), containsString("\"value\" : " + (i * 2 + 1))); + } + assertThat(response.shardFailures().length, is(1)); + + } + + public void testAsyncAllowPartialSearchResults_sequence() throws Exception { + final String assignedNodeForIndex1 = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + internalCluster().stopNode(assignedNodeForIndex1); + + // sequence query on both shards + var response = runAsync("sequence [process where value == 1] [process where value == 2]", true); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query on the available shard only + response = runAsync("sequence [process where value == 1] [process where value == 3]", true); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query on the unavailable shard only + response = runAsync("sequence [process where value == 0] [process where value == 2]", true); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query with missing event on unavailable shard. THIS IS A FALSE POSITIVE + response = runAsync( + "sequence with maxspan=10s [process where value == 1] ![process where value == 2] [process where value == 3]", + true + ); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + } + + public void testAsyncAllowPartialSearchResults_sample() throws Exception { + final String assignedNodeForIndex1 = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + internalCluster().stopNode(assignedNodeForIndex1); + // sample query on both shards + var response = runAsync("sample by key [process where value == 2] [process where value == 1]", true); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sample query on the available shard only + response = runAsync("sample by key [process where value == 3] [process where value == 1]", true); + assertThat(response.hits().sequences().size(), equalTo(1)); + var sample = response.hits().sequences().get(0); + assertThat(sample.events().get(0).toString(), containsString("\"value\" : 3")); + assertThat(sample.events().get(1).toString(), containsString("\"value\" : 1")); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sample query on the unavailable shard only + response = runAsync("sample by key [process where value == 2] [process where value == 0]", true); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + } + + // ------------------------------------------------------------------------ + // same queries, with missing shards and with default xpack.eql.default_allow_partial_results=true + // ------------------------------------------------------------------------ + + public void testClusterSetting_event() throws Exception { + final String assignedNodeForIndex1 = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + internalCluster().stopNode(assignedNodeForIndex1); + + client().execute( + ClusterUpdateSettingsAction.INSTANCE, + new ClusterUpdateSettingsRequest(TimeValue.THIRTY_SECONDS, TimeValue.THIRTY_SECONDS).persistentSettings( + Settings.builder().put(EqlPlugin.DEFAULT_ALLOW_PARTIAL_SEARCH_RESULTS.getKey(), true) + ) + ).get(); + + // event query + var request = new EqlSearchRequest().indices("test-*").query("process where true"); + var response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().events().size(), equalTo(5)); + for (int i = 0; i < 5; i++) { + assertThat(response.hits().events().get(i).toString(), containsString("\"value\" : " + (i * 2 + 1))); + } + assertThat(response.shardFailures().length, is(1)); + + client().execute( + ClusterUpdateSettingsAction.INSTANCE, + new ClusterUpdateSettingsRequest(TimeValue.THIRTY_SECONDS, TimeValue.THIRTY_SECONDS).persistentSettings( + Settings.builder().putNull(EqlPlugin.DEFAULT_ALLOW_PARTIAL_SEARCH_RESULTS.getKey()) + ) + ).get(); + } + + public void testClusterSetting_sequence() throws Exception { + final String assignedNodeForIndex1 = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + internalCluster().stopNode(assignedNodeForIndex1); + + client().execute( + ClusterUpdateSettingsAction.INSTANCE, + new ClusterUpdateSettingsRequest(TimeValue.THIRTY_SECONDS, TimeValue.THIRTY_SECONDS).persistentSettings( + Settings.builder().put(EqlPlugin.DEFAULT_ALLOW_PARTIAL_SEARCH_RESULTS.getKey(), true) + ) + ).get(); + // sequence query on both shards + var request = new EqlSearchRequest().indices("test-*").query("sequence [process where value == 1] [process where value == 2]"); + var response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query on the available shard only + request = new EqlSearchRequest().indices("test-*").query("sequence [process where value == 1] [process where value == 3]"); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query on the unavailable shard only + request = new EqlSearchRequest().indices("test-*").query("sequence [process where value == 0] [process where value == 2]"); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sequence query with missing event on unavailable shard. THIS IS A FALSE POSITIVE + request = new EqlSearchRequest().indices("test-*") + .query("sequence with maxspan=10s [process where value == 1] ![process where value == 2] [process where value == 3]"); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + client().execute( + ClusterUpdateSettingsAction.INSTANCE, + new ClusterUpdateSettingsRequest(TimeValue.THIRTY_SECONDS, TimeValue.THIRTY_SECONDS).persistentSettings( + Settings.builder().putNull(EqlPlugin.DEFAULT_ALLOW_PARTIAL_SEARCH_RESULTS.getKey()) + ) + ).get(); + } + + public void testClusterSetting_sample() throws Exception { + final String assignedNodeForIndex1 = createSchema(); + // ------------------------------------------------------------------------ + // stop one of the nodes, make one of the shards unavailable + // ------------------------------------------------------------------------ + + internalCluster().stopNode(assignedNodeForIndex1); + + client().execute( + ClusterUpdateSettingsAction.INSTANCE, + new ClusterUpdateSettingsRequest(TimeValue.THIRTY_SECONDS, TimeValue.THIRTY_SECONDS).persistentSettings( + Settings.builder().put(EqlPlugin.DEFAULT_ALLOW_PARTIAL_SEARCH_RESULTS.getKey(), true) + ) + ).get(); + + // sample query on both shards + var request = new EqlSearchRequest().indices("test-*").query("sample by key [process where value == 2] [process where value == 1]"); + var response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sample query on the available shard only + request = new EqlSearchRequest().indices("test-*").query("sample by key [process where value == 3] [process where value == 1]"); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(1)); + var sample = response.hits().sequences().get(0); + assertThat(sample.events().get(0).toString(), containsString("\"value\" : 3")); + assertThat(sample.events().get(1).toString(), containsString("\"value\" : 1")); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + // sample query on the unavailable shard only + request = new EqlSearchRequest().indices("test-*").query("sample by key [process where value == 2] [process where value == 0]"); + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + assertThat(response.hits().sequences().size(), equalTo(0)); + assertThat(response.shardFailures().length, is(1)); + assertThat(response.shardFailures()[0].index(), is("test-1")); + assertThat(response.shardFailures()[0].reason(), containsString("NoShardAvailableActionException")); + + client().execute( + ClusterUpdateSettingsAction.INSTANCE, + new ClusterUpdateSettingsRequest(TimeValue.THIRTY_SECONDS, TimeValue.THIRTY_SECONDS).persistentSettings( + Settings.builder().putNull(EqlPlugin.DEFAULT_ALLOW_PARTIAL_SEARCH_RESULTS.getKey()) + ) + ).get(); + } + + private static EqlSearchResponse runAsync(String query, Boolean allowPartialSearchResults) throws InterruptedException, + ExecutionException { + EqlSearchRequest request; + EqlSearchResponse response; + request = new EqlSearchRequest().indices("test-*").query(query).waitForCompletionTimeout(TimeValue.ZERO); + if (allowPartialSearchResults != null) { + request = request.allowPartialSearchResults(allowPartialSearchResults); + } + response = client().execute(EqlSearchAction.INSTANCE, request).get(); + while (response.isRunning()) { + GetAsyncResultRequest getResultsRequest = new GetAsyncResultRequest(response.id()).setKeepAlive(TimeValue.timeValueMinutes(10)) + .setWaitForCompletionTimeout(TimeValue.timeValueMillis(10)); + response = client().execute(EqlAsyncGetResultAction.INSTANCE, getResultsRequest).get(); + } + return response; + } + + private static void shouldFail(String query) throws InterruptedException { + EqlSearchRequest request = new EqlSearchRequest().indices("test-*").query(query); + if (randomBoolean()) { + request = request.allowPartialSearchResults(false); + } + if (randomBoolean()) { + request = request.allowPartialSequenceResults(randomBoolean()); + } + try { + client().execute(EqlSearchAction.INSTANCE, request).get(); + fail(); + } catch (ExecutionException e) { + assertThat(e.getCause(), instanceOf(SearchPhaseExecutionException.class)); + } + } +} diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/action/EqlSearchRequest.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/action/EqlSearchRequest.java index 0aeddd525e317..5804e11b72ff5 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/action/EqlSearchRequest.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/action/EqlSearchRequest.java @@ -63,6 +63,8 @@ public class EqlSearchRequest extends ActionRequest implements IndicesRequest.Re private List fetchFields; private Map runtimeMappings = emptyMap(); private int maxSamplesPerKey = RequestDefaults.MAX_SAMPLES_PER_KEY; + private Boolean allowPartialSearchResults; + private Boolean allowPartialSequenceResults; // Async settings private TimeValue waitForCompletionTimeout = null; @@ -83,6 +85,8 @@ public class EqlSearchRequest extends ActionRequest implements IndicesRequest.Re static final String KEY_FETCH_FIELDS = "fields"; static final String KEY_RUNTIME_MAPPINGS = "runtime_mappings"; static final String KEY_MAX_SAMPLES_PER_KEY = "max_samples_per_key"; + static final String KEY_ALLOW_PARTIAL_SEARCH_RESULTS = "allow_partial_search_results"; + static final String KEY_ALLOW_PARTIAL_SEQUENCE_RESULTS = "allow_partial_sequence_results"; static final ParseField FILTER = new ParseField(KEY_FILTER); static final ParseField TIMESTAMP_FIELD = new ParseField(KEY_TIMESTAMP_FIELD); @@ -97,6 +101,8 @@ public class EqlSearchRequest extends ActionRequest implements IndicesRequest.Re static final ParseField RESULT_POSITION = new ParseField(KEY_RESULT_POSITION); static final ParseField FETCH_FIELDS_FIELD = SearchSourceBuilder.FETCH_FIELDS_FIELD; static final ParseField MAX_SAMPLES_PER_KEY = new ParseField(KEY_MAX_SAMPLES_PER_KEY); + static final ParseField ALLOW_PARTIAL_SEARCH_RESULTS = new ParseField(KEY_ALLOW_PARTIAL_SEARCH_RESULTS); + static final ParseField ALLOW_PARTIAL_SEQUENCE_RESULTS = new ParseField(KEY_ALLOW_PARTIAL_SEQUENCE_RESULTS); private static final ObjectParser PARSER = objectParser(EqlSearchRequest::new); @@ -135,6 +141,13 @@ public EqlSearchRequest(StreamInput in) throws IOException { if (in.getTransportVersion().onOrAfter(TransportVersions.V_8_7_0)) { maxSamplesPerKey = in.readInt(); } + if (in.getTransportVersion().onOrAfter(TransportVersions.EQL_ALLOW_PARTIAL_SEARCH_RESULTS)) { + allowPartialSearchResults = in.readOptionalBoolean(); + allowPartialSequenceResults = in.readOptionalBoolean(); + } else { + allowPartialSearchResults = false; + allowPartialSequenceResults = false; + } } @Override @@ -245,6 +258,8 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.field(KEY_RUNTIME_MAPPINGS, runtimeMappings); } builder.field(KEY_MAX_SAMPLES_PER_KEY, maxSamplesPerKey); + builder.field(KEY_ALLOW_PARTIAL_SEARCH_RESULTS, allowPartialSearchResults); + builder.field(KEY_ALLOW_PARTIAL_SEQUENCE_RESULTS, allowPartialSequenceResults); return builder; } @@ -279,6 +294,8 @@ protected static ObjectParser objectParser parser.declareField(EqlSearchRequest::fetchFields, EqlSearchRequest::parseFetchFields, FETCH_FIELDS_FIELD, ValueType.VALUE_ARRAY); parser.declareObject(EqlSearchRequest::runtimeMappings, (p, c) -> p.map(), SearchSourceBuilder.RUNTIME_MAPPINGS_FIELD); parser.declareInt(EqlSearchRequest::maxSamplesPerKey, MAX_SAMPLES_PER_KEY); + parser.declareBoolean(EqlSearchRequest::allowPartialSearchResults, ALLOW_PARTIAL_SEARCH_RESULTS); + parser.declareBoolean(EqlSearchRequest::allowPartialSequenceResults, ALLOW_PARTIAL_SEQUENCE_RESULTS); return parser; } @@ -427,6 +444,24 @@ public EqlSearchRequest maxSamplesPerKey(int maxSamplesPerKey) { return this; } + public Boolean allowPartialSearchResults() { + return allowPartialSearchResults; + } + + public EqlSearchRequest allowPartialSearchResults(Boolean val) { + this.allowPartialSearchResults = val; + return this; + } + + public Boolean allowPartialSequenceResults() { + return allowPartialSequenceResults; + } + + public EqlSearchRequest allowPartialSequenceResults(Boolean val) { + this.allowPartialSequenceResults = val; + return this; + } + private static List parseFetchFields(XContentParser parser) throws IOException { List result = new ArrayList<>(); Token token = parser.currentToken(); @@ -470,6 +505,10 @@ public void writeTo(StreamOutput out) throws IOException { if (out.getTransportVersion().onOrAfter(TransportVersions.V_8_7_0)) { out.writeInt(maxSamplesPerKey); } + if (out.getTransportVersion().onOrAfter(TransportVersions.EQL_ALLOW_PARTIAL_SEARCH_RESULTS)) { + out.writeOptionalBoolean(allowPartialSearchResults); + out.writeOptionalBoolean(allowPartialSequenceResults); + } } @Override @@ -496,7 +535,9 @@ public boolean equals(Object o) { && Objects.equals(resultPosition, that.resultPosition) && Objects.equals(fetchFields, that.fetchFields) && Objects.equals(runtimeMappings, that.runtimeMappings) - && Objects.equals(maxSamplesPerKey, that.maxSamplesPerKey); + && Objects.equals(maxSamplesPerKey, that.maxSamplesPerKey) + && Objects.equals(allowPartialSearchResults, that.allowPartialSearchResults) + && Objects.equals(allowPartialSequenceResults, that.allowPartialSequenceResults); } @Override @@ -517,7 +558,9 @@ public int hashCode() { resultPosition, fetchFields, runtimeMappings, - maxSamplesPerKey + maxSamplesPerKey, + allowPartialSearchResults, + allowPartialSequenceResults ); } diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/action/EqlSearchResponse.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/action/EqlSearchResponse.java index 2b7b8b074fa71..a4d93b7659970 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/action/EqlSearchResponse.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/action/EqlSearchResponse.java @@ -7,8 +7,11 @@ package org.elasticsearch.xpack.eql.action; import org.apache.lucene.search.TotalHits; +import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.TransportVersions; import org.elasticsearch.action.ActionResponse; +import org.elasticsearch.action.ShardOperationFailedException; +import org.elasticsearch.action.search.ShardSearchFailure; import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; @@ -17,6 +20,7 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.lucene.Lucene; +import org.elasticsearch.common.util.CollectionUtils; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParserUtils; import org.elasticsearch.core.Nullable; @@ -36,6 +40,7 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -54,6 +59,7 @@ public class EqlSearchResponse extends ActionResponse implements ToXContentObjec private final String asyncExecutionId; private final boolean isRunning; private final boolean isPartial; + private final ShardSearchFailure[] shardFailures; private static final class Fields { static final String TOOK = "took"; @@ -62,6 +68,7 @@ private static final class Fields { static final String ID = "id"; static final String IS_RUNNING = "is_running"; static final String IS_PARTIAL = "is_partial"; + static final String SHARD_FAILURES = "shard_failures"; } private static final ParseField TOOK = new ParseField(Fields.TOOK); @@ -70,8 +77,10 @@ private static final class Fields { private static final ParseField ID = new ParseField(Fields.ID); private static final ParseField IS_RUNNING = new ParseField(Fields.IS_RUNNING); private static final ParseField IS_PARTIAL = new ParseField(Fields.IS_PARTIAL); + private static final ParseField SHARD_FAILURES = new ParseField(Fields.SHARD_FAILURES); private static final InstantiatingObjectParser PARSER; + static { InstantiatingObjectParser.Builder parser = InstantiatingObjectParser.builder( "eql/search_response", @@ -84,11 +93,12 @@ private static final class Fields { parser.declareString(optionalConstructorArg(), ID); parser.declareBoolean(constructorArg(), IS_RUNNING); parser.declareBoolean(constructorArg(), IS_PARTIAL); + parser.declareObjectArray(optionalConstructorArg(), (p, c) -> ShardSearchFailure.EMPTY_ARRAY, SHARD_FAILURES); PARSER = parser.build(); } - public EqlSearchResponse(Hits hits, long tookInMillis, boolean isTimeout) { - this(hits, tookInMillis, isTimeout, null, false, false); + public EqlSearchResponse(Hits hits, long tookInMillis, boolean isTimeout, ShardSearchFailure[] shardFailures) { + this(hits, tookInMillis, isTimeout, null, false, false, shardFailures); } public EqlSearchResponse( @@ -97,7 +107,8 @@ public EqlSearchResponse( boolean isTimeout, String asyncExecutionId, boolean isRunning, - boolean isPartial + boolean isPartial, + ShardSearchFailure[] shardFailures ) { super(); this.hits = hits == null ? Hits.EMPTY : hits; @@ -106,6 +117,7 @@ public EqlSearchResponse( this.asyncExecutionId = asyncExecutionId; this.isRunning = isRunning; this.isPartial = isPartial; + this.shardFailures = shardFailures; } public EqlSearchResponse(StreamInput in) throws IOException { @@ -116,6 +128,11 @@ public EqlSearchResponse(StreamInput in) throws IOException { asyncExecutionId = in.readOptionalString(); isPartial = in.readBoolean(); isRunning = in.readBoolean(); + if (in.getTransportVersion().onOrAfter(TransportVersions.EQL_ALLOW_PARTIAL_SEARCH_RESULTS)) { + shardFailures = in.readArray(ShardSearchFailure::readShardSearchFailure, ShardSearchFailure[]::new); + } else { + shardFailures = ShardSearchFailure.EMPTY_ARRAY; + } } public static EqlSearchResponse fromXContent(XContentParser parser) { @@ -130,6 +147,9 @@ public void writeTo(StreamOutput out) throws IOException { out.writeOptionalString(asyncExecutionId); out.writeBoolean(isPartial); out.writeBoolean(isRunning); + if (out.getTransportVersion().onOrAfter(TransportVersions.EQL_ALLOW_PARTIAL_SEARCH_RESULTS)) { + out.writeArray(shardFailures); + } } @Override @@ -147,6 +167,13 @@ private XContentBuilder innerToXContent(XContentBuilder builder, Params params) builder.field(IS_RUNNING.getPreferredName(), isRunning); builder.field(TOOK.getPreferredName(), tookInMillis); builder.field(TIMED_OUT.getPreferredName(), isTimeout); + if (CollectionUtils.isEmpty(shardFailures) == false) { + builder.startArray(SHARD_FAILURES.getPreferredName()); + for (ShardOperationFailedException shardFailure : ExceptionsHelper.groupBy(shardFailures)) { + shardFailure.toXContent(builder, params); + } + builder.endArray(); + } hits.toXContent(builder, params); return builder; } @@ -178,6 +205,10 @@ public boolean isPartial() { return isPartial; } + public ShardSearchFailure[] shardFailures() { + return shardFailures; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -190,12 +221,13 @@ public boolean equals(Object o) { return Objects.equals(hits, that.hits) && Objects.equals(tookInMillis, that.tookInMillis) && Objects.equals(isTimeout, that.isTimeout) - && Objects.equals(asyncExecutionId, that.asyncExecutionId); + && Objects.equals(asyncExecutionId, that.asyncExecutionId) + && Arrays.equals(shardFailures, that.shardFailures); } @Override public int hashCode() { - return Objects.hash(hits, tookInMillis, isTimeout, asyncExecutionId); + return Objects.hash(hits, tookInMillis, isTimeout, asyncExecutionId, Arrays.hashCode(shardFailures)); } @Override diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/action/EqlSearchTask.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/action/EqlSearchTask.java index 2a1bc3b7adb67..0fc8e8c88d7d9 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/action/EqlSearchTask.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/action/EqlSearchTask.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.eql.action; +import org.elasticsearch.action.search.ShardSearchFailure; import org.elasticsearch.core.TimeValue; import org.elasticsearch.tasks.TaskId; import org.elasticsearch.xpack.core.async.AsyncExecutionId; @@ -39,7 +40,8 @@ public EqlSearchResponse getCurrentResult() { false, getExecutionId().getEncoded(), true, - true + true, + ShardSearchFailure.EMPTY_ARRAY ); } } diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/assembler/ExecutionManager.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/assembler/ExecutionManager.java index b26c815c1a2b5..672d6b87a8dbb 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/assembler/ExecutionManager.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/assembler/ExecutionManager.java @@ -167,7 +167,9 @@ public Executable assemble( criteria.subList(0, completionStage), criteria.get(completionStage), matcher, - listOfKeys + listOfKeys, + cfg.allowPartialSearchResults(), + cfg.allowPartialSequenceResults() ); return w; @@ -235,7 +237,8 @@ public Executable assemble(List> listOfKeys, List cfg.fetchSize(), limit, session.circuitBreaker(), - cfg.maxSamplesPerKey() + cfg.maxSamplesPerKey(), + cfg.allowPartialSearchResults() ); } diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/payload/AbstractPayload.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/payload/AbstractPayload.java index 823cd04d25f45..9fecf958b9714 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/payload/AbstractPayload.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/payload/AbstractPayload.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.eql.execution.payload; +import org.elasticsearch.action.search.ShardSearchFailure; import org.elasticsearch.core.TimeValue; import org.elasticsearch.xpack.eql.session.Payload; @@ -14,10 +15,12 @@ public abstract class AbstractPayload implements Payload { private final boolean timedOut; private final TimeValue timeTook; + private ShardSearchFailure[] shardFailures; - protected AbstractPayload(boolean timedOut, TimeValue timeTook) { + protected AbstractPayload(boolean timedOut, TimeValue timeTook, ShardSearchFailure[] shardFailures) { this.timedOut = timedOut; this.timeTook = timeTook; + this.shardFailures = shardFailures; } @Override @@ -29,4 +32,9 @@ public boolean timedOut() { public TimeValue timeTook() { return timeTook; } + + @Override + public ShardSearchFailure[] shardFailures() { + return shardFailures; + } } diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/payload/EventPayload.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/payload/EventPayload.java index a7845ca62dccc..6471bc0814f70 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/payload/EventPayload.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/payload/EventPayload.java @@ -20,7 +20,7 @@ public class EventPayload extends AbstractPayload { private final List values; public EventPayload(SearchResponse response) { - super(response.isTimedOut(), response.getTook()); + super(response.isTimedOut(), response.getTook(), response.getShardFailures()); SearchHits hits = response.getHits(); values = new ArrayList<>(hits.getHits().length); diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/sample/SampleIterator.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/sample/SampleIterator.java index 89f1c4d1eb041..b9b7cfd6b615a 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/sample/SampleIterator.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/sample/SampleIterator.java @@ -14,6 +14,7 @@ import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.search.MultiSearchResponse; import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.ShardSearchFailure; import org.elasticsearch.common.breaker.CircuitBreaker; import org.elasticsearch.core.TimeValue; import org.elasticsearch.search.SearchHit; @@ -35,6 +36,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -44,6 +46,7 @@ import static org.elasticsearch.common.Strings.EMPTY_ARRAY; import static org.elasticsearch.xpack.eql.execution.assembler.SampleQueryRequest.COMPOSITE_AGG_NAME; import static org.elasticsearch.xpack.eql.execution.search.RuntimeUtils.prepareRequest; +import static org.elasticsearch.xpack.eql.util.SearchHitUtils.addShardFailures; public class SampleIterator implements Executable { @@ -58,6 +61,7 @@ public class SampleIterator implements Executable { private final Limit limit; private final int maxSamplesPerKey; private long startTime; + private Map shardFailures = new HashMap<>(); // ---------- CIRCUIT BREAKER ----------- @@ -84,13 +88,16 @@ public class SampleIterator implements Executable { */ private long previousTotalPageSize = 0; + private boolean allowPartialSearchResults; + public SampleIterator( QueryClient client, List criteria, int fetchSize, Limit limit, CircuitBreaker circuitBreaker, - int maxSamplesPerKey + int maxSamplesPerKey, + boolean allowPartialSearchResults ) { this.client = client; this.criteria = criteria; @@ -100,6 +107,7 @@ public SampleIterator( this.limit = limit; this.circuitBreaker = circuitBreaker; this.maxSamplesPerKey = maxSamplesPerKey; + this.allowPartialSearchResults = allowPartialSearchResults; } @Override @@ -147,6 +155,7 @@ private void advance(ActionListener listener) { private void queryForCompositeAggPage(ActionListener listener, final SampleQueryRequest request) { client.query(request, listener.delegateFailureAndWrap((delegate, r) -> { + addShardFailures(shardFailures, r); // either the fields values or the fields themselves are missing // or the filter applied on the eql query matches no documents if (r.hasAggregations() == false) { @@ -209,13 +218,16 @@ private void finalStep(ActionListener listener) { for (SampleCriterion criterion : criteria) { SampleQueryRequest r = criterion.finalQuery(); r.singleKeyPair(compositeKeyValues, maxCriteria, maxSamplesPerKey); - searches.add(prepareRequest(r.searchSource(), false, EMPTY_ARRAY)); + searches.add(prepareRequest(r.searchSource(), false, allowPartialSearchResults, EMPTY_ARRAY)); } sampleKeys.add(new SequenceKey(compositeKeyValues.toArray())); } int initialSize = samples.size(); client.multiQuery(searches, listener.delegateFailureAndWrap((delegate, r) -> { + for (MultiSearchResponse.Item item : r) { + addShardFailures(shardFailures, item.getResponse()); + } List> sample = new ArrayList<>(maxCriteria); MultiSearchResponse.Item[] response = r.getResponses(); int docGroupsCounter = 1; @@ -280,14 +292,23 @@ private void payload(ActionListener listener) { log.trace("Sending payload for [{}] samples", samples.size()); if (samples.isEmpty()) { - listener.onResponse(new EmptyPayload(Type.SAMPLE, timeTook())); + listener.onResponse(new EmptyPayload(Type.SAMPLE, timeTook(), shardFailures.values().toArray(new ShardSearchFailure[0]))); return; } // get results through search (to keep using PIT) client.fetchHits( hits(samples), - ActionListeners.map(listener, listOfHits -> new SamplePayload(samples, listOfHits, false, timeTook())) + ActionListeners.map( + listener, + listOfHits -> new SamplePayload( + samples, + listOfHits, + false, + timeTook(), + shardFailures.values().toArray(new ShardSearchFailure[0]) + ) + ) ); } diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/sample/SamplePayload.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/sample/SamplePayload.java index 121f4c208273b..aee084dd88734 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/sample/SamplePayload.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/sample/SamplePayload.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.eql.execution.sample; +import org.elasticsearch.action.search.ShardSearchFailure; import org.elasticsearch.core.TimeValue; import org.elasticsearch.search.SearchHit; import org.elasticsearch.xpack.eql.action.EqlSearchResponse.Event; @@ -19,8 +20,14 @@ class SamplePayload extends AbstractPayload { private final List values; - SamplePayload(List samples, List> docs, boolean timedOut, TimeValue timeTook) { - super(timedOut, timeTook); + SamplePayload( + List samples, + List> docs, + boolean timedOut, + TimeValue timeTook, + ShardSearchFailure[] shardFailures + ) { + super(timedOut, timeTook, shardFailures); values = new ArrayList<>(samples.size()); for (int i = 0; i < samples.size(); i++) { diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/search/BasicQueryClient.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/search/BasicQueryClient.java index 6cbe5298b5950..18623c17dcffb 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/search/BasicQueryClient.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/search/BasicQueryClient.java @@ -46,12 +46,14 @@ public class BasicQueryClient implements QueryClient { final Client client; final String[] indices; final List fetchFields; + private final boolean allowPartialSearchResults; public BasicQueryClient(EqlSession eqlSession) { this.cfg = eqlSession.configuration(); this.client = eqlSession.client(); this.indices = cfg.indices(); this.fetchFields = cfg.fetchFields(); + this.allowPartialSearchResults = cfg.allowPartialSearchResults(); } @Override @@ -60,11 +62,11 @@ public void query(QueryRequest request, ActionListener listener) // set query timeout searchSource.timeout(cfg.requestTimeout()); - SearchRequest search = prepareRequest(searchSource, false, indices); - search(search, searchLogListener(listener, log)); + SearchRequest search = prepareRequest(searchSource, false, allowPartialSearchResults, indices); + search(search, allowPartialSearchResults, searchLogListener(listener, log, allowPartialSearchResults)); } - protected void search(SearchRequest search, ActionListener listener) { + protected void search(SearchRequest search, boolean allowPartialSearchResults, ActionListener listener) { if (cfg.isCancelled()) { listener.onFailure(new TaskCancelledException("cancelled")); return; @@ -77,7 +79,7 @@ protected void search(SearchRequest search, ActionListener liste client.search(search, listener); } - protected void search(MultiSearchRequest search, ActionListener listener) { + protected void search(MultiSearchRequest search, boolean allowPartialSearchResults, ActionListener listener) { if (cfg.isCancelled()) { listener.onFailure(new TaskCancelledException("cancelled")); return; @@ -91,7 +93,7 @@ protected void search(MultiSearchRequest search, ActionListener> refs, ActionListener { + search(multiSearchBuilder.request(), allowPartialSearchResults, listener.delegateFailureAndWrap((delegate, r) -> { for (MultiSearchResponse.Item item : r.getResponses()) { // check for failures if (item.isFailure()) { @@ -187,6 +189,6 @@ public void multiQuery(List searches, ActionListener listener) { + protected void search(SearchRequest search, boolean allowPartialSearchResults, ActionListener listener) { // no pitId, ask for one if (pitId == null) { - openPIT(listener, () -> searchWithPIT(search, listener)); + openPIT(listener, () -> searchWithPIT(search, listener, allowPartialSearchResults), allowPartialSearchResults); } else { - searchWithPIT(search, listener); + searchWithPIT(search, listener, allowPartialSearchResults); } } - private void searchWithPIT(SearchRequest request, ActionListener listener) { + private void searchWithPIT(SearchRequest request, ActionListener listener, boolean allowPartialSearchResults) { makeRequestPITCompatible(request); // get the pid on each response - super.search(request, pitListener(SearchResponse::pointInTimeId, listener)); + super.search(request, allowPartialSearchResults, pitListener(SearchResponse::pointInTimeId, listener)); } @Override - protected void search(MultiSearchRequest search, ActionListener listener) { + protected void search(MultiSearchRequest search, boolean allowPartialSearchResults, ActionListener listener) { // no pitId, ask for one if (pitId == null) { - openPIT(listener, () -> searchWithPIT(search, listener)); + openPIT(listener, () -> searchWithPIT(search, allowPartialSearchResults, listener), allowPartialSearchResults); } else { - searchWithPIT(search, listener); + searchWithPIT(search, allowPartialSearchResults, listener); } } - private void searchWithPIT(MultiSearchRequest search, ActionListener listener) { + private void searchWithPIT(MultiSearchRequest search, boolean allowPartialSearchResults, ActionListener listener) { for (SearchRequest request : search.requests()) { makeRequestPITCompatible(request); } // get the pid on each request - super.search(search, pitListener(r -> { + super.search(search, allowPartialSearchResults, pitListener(r -> { // get pid for (MultiSearchResponse.Item item : r.getResponses()) { // pick the first non-failing response @@ -135,9 +135,10 @@ private ActionListener pitListener( ); } - private void openPIT(ActionListener listener, Runnable runnable) { + private void openPIT(ActionListener listener, Runnable runnable, boolean allowPartialSearchResults) { OpenPointInTimeRequest request = new OpenPointInTimeRequest(indices).indicesOptions(IndexResolver.FIELD_CAPS_INDICES_OPTIONS) - .keepAlive(keepAlive); + .keepAlive(keepAlive) + .allowPartialSearchResults(allowPartialSearchResults); request.indexFilter(filter); client.execute(TransportOpenPointInTimeAction.TYPE, request, listener.delegateFailureAndWrap((l, r) -> { pitId = r.getPointInTimeId(); diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/search/RuntimeUtils.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/search/RuntimeUtils.java index 40f7f7139efa1..92af8c562f840 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/search/RuntimeUtils.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/search/RuntimeUtils.java @@ -56,10 +56,14 @@ public final class RuntimeUtils { private RuntimeUtils() {} - public static ActionListener searchLogListener(ActionListener listener, Logger log) { + public static ActionListener searchLogListener( + ActionListener listener, + Logger log, + boolean allowPartialResults + ) { return listener.delegateFailureAndWrap((delegate, response) -> { ShardSearchFailure[] failures = response.getShardFailures(); - if (CollectionUtils.isEmpty(failures) == false) { + if (CollectionUtils.isEmpty(failures) == false && allowPartialResults == false) { delegate.onFailure(new EqlIllegalArgumentException(failures[0].reason(), failures[0].getCause())); return; } @@ -70,16 +74,22 @@ public static ActionListener searchLogListener(ActionListener multiSearchLogListener(ActionListener listener, Logger log) { + public static ActionListener multiSearchLogListener( + ActionListener listener, + boolean allowPartialSearchResults, + Logger log + ) { return listener.delegateFailureAndWrap((delegate, items) -> { for (MultiSearchResponse.Item item : items) { Exception failure = item.getFailure(); SearchResponse response = item.getResponse(); if (failure == null) { - ShardSearchFailure[] failures = response.getShardFailures(); - if (CollectionUtils.isEmpty(failures) == false) { - failure = new EqlIllegalArgumentException(failures[0].reason(), failures[0].getCause()); + if (allowPartialSearchResults == false) { + ShardSearchFailure[] failures = response.getShardFailures(); + if (CollectionUtils.isEmpty(failures) == false) { + failure = new EqlIllegalArgumentException(failures[0].reason(), failures[0].getCause()); + } } } if (failure != null) { @@ -170,11 +180,16 @@ public static HitExtractor createExtractor(FieldExtraction ref, EqlConfiguration throw new EqlIllegalArgumentException("Unexpected value reference {}", ref.getClass()); } - public static SearchRequest prepareRequest(SearchSourceBuilder source, boolean includeFrozen, String... indices) { + public static SearchRequest prepareRequest( + SearchSourceBuilder source, + boolean includeFrozen, + boolean allowPartialSearchResults, + String... indices + ) { SearchRequest searchRequest = new SearchRequest(); searchRequest.indices(indices); searchRequest.source(source); - searchRequest.allowPartialSearchResults(false); + searchRequest.allowPartialSearchResults(allowPartialSearchResults); searchRequest.indicesOptions( includeFrozen ? IndexResolver.FIELD_CAPS_FROZEN_INDICES_OPTIONS : IndexResolver.FIELD_CAPS_INDICES_OPTIONS ); diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/sequence/SequencePayload.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/sequence/SequencePayload.java index 45083babddbb4..b4a8edc79b3ad 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/sequence/SequencePayload.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/sequence/SequencePayload.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.eql.execution.sequence; +import org.elasticsearch.action.search.ShardSearchFailure; import org.elasticsearch.core.TimeValue; import org.elasticsearch.search.SearchHit; import org.elasticsearch.xpack.eql.action.EqlSearchResponse.Event; @@ -19,8 +20,14 @@ class SequencePayload extends AbstractPayload { private final List values; - SequencePayload(List sequences, List> docs, boolean timedOut, TimeValue timeTook) { - super(timedOut, timeTook); + SequencePayload( + List sequences, + List> docs, + boolean timedOut, + TimeValue timeTook, + ShardSearchFailure[] shardFailures + ) { + super(timedOut, timeTook, shardFailures); values = new ArrayList<>(sequences.size()); for (int i = 0; i < sequences.size(); i++) { diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/sequence/TumblingWindow.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/sequence/TumblingWindow.java index eabf6df518ad4..fac8788db0f95 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/sequence/TumblingWindow.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/execution/sequence/TumblingWindow.java @@ -13,6 +13,7 @@ import org.elasticsearch.action.search.MultiSearchResponse; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.action.search.ShardSearchFailure; import org.elasticsearch.common.Strings; import org.elasticsearch.core.TimeValue; import org.elasticsearch.core.Tuple; @@ -41,6 +42,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; @@ -51,6 +53,7 @@ import static org.elasticsearch.action.ActionListener.runAfter; import static org.elasticsearch.xpack.eql.execution.ExecutionUtils.copySource; import static org.elasticsearch.xpack.eql.execution.search.RuntimeUtils.combineFilters; +import static org.elasticsearch.xpack.eql.util.SearchHitUtils.addShardFailures; import static org.elasticsearch.xpack.eql.util.SearchHitUtils.qualifiedIndex; /** @@ -103,6 +106,9 @@ protected boolean removeEldestEntry(Map.Entry eldest) { private final boolean hasKeys; private final List> listOfKeys; + private final boolean allowPartialSearchResults; + private final boolean allowPartialSequenceResults; + private Map shardFailures = new HashMap<>(); // flag used for DESC sequences to indicate whether // the window needs to restart (since the DESC query still has results) @@ -127,7 +133,10 @@ public TumblingWindow( List criteria, SequenceCriterion until, SequenceMatcher matcher, - List> listOfKeys + List> listOfKeys, + boolean allowPartialSearchResults, + boolean allowPartialSequenceResults + ) { this.client = client; @@ -141,6 +150,8 @@ public TumblingWindow( this.hasKeys = baseRequest.keySize() > 0; this.restartWindowFromTailQuery = baseRequest.descending(); this.listOfKeys = listOfKeys; + this.allowPartialSearchResults = allowPartialSearchResults; + this.allowPartialSequenceResults = allowPartialSequenceResults; } @Override @@ -158,6 +169,9 @@ public void execute(ActionListener listener) { * Move the window while preserving the same base. */ private void tumbleWindow(int currentStage, ActionListener listener) { + if (allowPartialSequenceResults == false && shardFailures.isEmpty() == false) { + doPayload(listener); + } if (currentStage > matcher.firstPositiveStage && matcher.hasCandidates() == false) { if (restartWindowFromTailQuery) { currentStage = matcher.firstPositiveStage; @@ -224,6 +238,9 @@ public void checkMissingEvents(Runnable next, ActionListener listener) private void doCheckMissingEvents(List batchToCheck, MultiSearchResponse p, ActionListener listener, Runnable next) { MultiSearchResponse.Item[] responses = p.getResponses(); + for (MultiSearchResponse.Item response : responses) { + addShardFailures(shardFailures, response.getResponse()); + } int nextResponse = 0; for (Sequence sequence : batchToCheck) { boolean leading = true; @@ -316,7 +333,14 @@ private List prepareQueryForMissingEvents(List toCheck) } addKeyFilter(i, sequence, builder); RuntimeUtils.combineFilters(builder, range); - result.add(RuntimeUtils.prepareRequest(builder.size(1).trackTotalHits(false), false, Strings.EMPTY_ARRAY)); + result.add( + RuntimeUtils.prepareRequest( + builder.size(1).trackTotalHits(false), + false, + allowPartialSearchResults, + Strings.EMPTY_ARRAY + ) + ); } else { leading = false; } @@ -361,6 +385,7 @@ private void advance(int stage, ActionListener listener) { * Execute the base query. */ private void baseCriterion(int baseStage, SearchResponse r, ActionListener listener) { + addShardFailures(shardFailures, r); SequenceCriterion base = criteria.get(baseStage); SearchHits hits = r.getHits(); @@ -731,8 +756,10 @@ private void doPayload(ActionListener listener) { log.trace("Sending payload for [{}] sequences", completed.size()); - if (completed.isEmpty()) { - listener.onResponse(new EmptyPayload(Type.SEQUENCE, timeTook())); + if (completed.isEmpty() || (allowPartialSequenceResults == false && shardFailures.isEmpty() == false)) { + listener.onResponse( + new EmptyPayload(Type.SEQUENCE, timeTook(), shardFailures.values().toArray(new ShardSearchFailure[shardFailures.size()])) + ); return; } @@ -741,7 +768,13 @@ private void doPayload(ActionListener listener) { if (criteria.get(matcher.firstPositiveStage).descending()) { Collections.reverse(completed); } - return new SequencePayload(completed, addMissingEventPlaceholders(listOfHits), false, timeTook()); + return new SequencePayload( + completed, + addMissingEventPlaceholders(listOfHits), + false, + timeTook(), + shardFailures.values().toArray(new ShardSearchFailure[0]) + ); })); } diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/EqlPlugin.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/EqlPlugin.java index 084a5e74a47e8..210f88c991539 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/EqlPlugin.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/EqlPlugin.java @@ -60,6 +60,20 @@ public class EqlPlugin extends Plugin implements ActionPlugin, CircuitBreakerPlu Setting.Property.DeprecatedWarning ); + public static final Setting DEFAULT_ALLOW_PARTIAL_SEARCH_RESULTS = Setting.boolSetting( + "xpack.eql.default_allow_partial_results", + false, + Setting.Property.NodeScope, + Setting.Property.Dynamic + ); + + public static final Setting DEFAULT_ALLOW_PARTIAL_SEQUENCE_RESULTS = Setting.boolSetting( + "xpack.eql.default_allow_partial_sequence_results", + false, + Setting.Property.NodeScope, + Setting.Property.Dynamic + ); + public EqlPlugin() {} @Override @@ -86,7 +100,7 @@ private Collection createComponents(Client client, Settings settings, Cl */ @Override public List> getSettings() { - return List.of(EQL_ENABLED_SETTING); + return List.of(EQL_ENABLED_SETTING, DEFAULT_ALLOW_PARTIAL_SEARCH_RESULTS, DEFAULT_ALLOW_PARTIAL_SEQUENCE_RESULTS); } @Override diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/RestEqlSearchAction.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/RestEqlSearchAction.java index e24a4749f45cd..65def24563e5e 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/RestEqlSearchAction.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/RestEqlSearchAction.java @@ -64,6 +64,12 @@ protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient cli } eqlRequest.keepOnCompletion(request.paramAsBoolean("keep_on_completion", eqlRequest.keepOnCompletion())); eqlRequest.ccsMinimizeRoundtrips(request.paramAsBoolean("ccs_minimize_roundtrips", eqlRequest.ccsMinimizeRoundtrips())); + eqlRequest.allowPartialSearchResults( + request.paramAsBoolean("allow_partial_search_results", eqlRequest.allowPartialSearchResults()) + ); + eqlRequest.allowPartialSequenceResults( + request.paramAsBoolean("allow_partial_sequence_results", eqlRequest.allowPartialSequenceResults()) + ); } return channel -> { diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/TransportEqlSearchAction.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/TransportEqlSearchAction.java index c0141da2432ce..582352722fc58 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/TransportEqlSearchAction.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/plugin/TransportEqlSearchAction.java @@ -10,6 +10,7 @@ import org.apache.logging.log4j.Logger; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionListenerResponseHandler; +import org.elasticsearch.action.search.ShardSearchFailure; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.HandledTransportAction; import org.elasticsearch.client.internal.Client; @@ -144,7 +145,8 @@ public EqlSearchResponse initialResponse(EqlSearchTask task) { false, task.getExecutionId().getEncoded(), true, - true + true, + ShardSearchFailure.EMPTY_ARRAY ); } @@ -231,6 +233,12 @@ public static void operation( request.indicesOptions(), request.fetchSize(), request.maxSamplesPerKey(), + request.allowPartialSearchResults() == null + ? defaultAllowPartialSearchResults(clusterService) + : request.allowPartialSearchResults(), + request.allowPartialSequenceResults() == null + ? defaultAllowPartialSequenceResults(clusterService) + : request.allowPartialSequenceResults(), clientId, new TaskId(nodeId, task.getId()), task @@ -244,12 +252,34 @@ public static void operation( } } + private static boolean defaultAllowPartialSearchResults(ClusterService clusterService) { + if (clusterService.getClusterSettings() == null) { + return EqlPlugin.DEFAULT_ALLOW_PARTIAL_SEARCH_RESULTS.getDefault(Settings.EMPTY); + } + return clusterService.getClusterSettings().get(EqlPlugin.DEFAULT_ALLOW_PARTIAL_SEARCH_RESULTS); + } + + private static boolean defaultAllowPartialSequenceResults(ClusterService clusterService) { + if (clusterService.getClusterSettings() == null) { + return EqlPlugin.DEFAULT_ALLOW_PARTIAL_SEQUENCE_RESULTS.getDefault(Settings.EMPTY); + } + return clusterService.getClusterSettings().get(EqlPlugin.DEFAULT_ALLOW_PARTIAL_SEQUENCE_RESULTS); + } + static EqlSearchResponse createResponse(Results results, AsyncExecutionId id) { EqlSearchResponse.Hits hits = new EqlSearchResponse.Hits(results.events(), results.sequences(), results.totalHits()); if (id != null) { - return new EqlSearchResponse(hits, results.tookTime().getMillis(), results.timedOut(), id.getEncoded(), false, false); + return new EqlSearchResponse( + hits, + results.tookTime().getMillis(), + results.timedOut(), + id.getEncoded(), + false, + false, + results.shardFailures() + ); } else { - return new EqlSearchResponse(hits, results.tookTime().getMillis(), results.timedOut()); + return new EqlSearchResponse(hits, results.tookTime().getMillis(), results.timedOut(), results.shardFailures()); } } diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/session/EmptyPayload.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/session/EmptyPayload.java index 9822285465087..33ed5799cd073 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/session/EmptyPayload.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/session/EmptyPayload.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.eql.session; +import org.elasticsearch.action.search.ShardSearchFailure; import org.elasticsearch.core.TimeValue; import java.util.List; @@ -17,14 +18,16 @@ public class EmptyPayload implements Payload { private final Type type; private final TimeValue timeTook; + private final ShardSearchFailure[] shardFailures; public EmptyPayload(Type type) { - this(type, TimeValue.ZERO); + this(type, TimeValue.ZERO, ShardSearchFailure.EMPTY_ARRAY); } - public EmptyPayload(Type type, TimeValue timeTook) { + public EmptyPayload(Type type, TimeValue timeTook, ShardSearchFailure[] shardFailures) { this.type = type; this.timeTook = timeTook; + this.shardFailures = shardFailures; } @Override @@ -46,4 +49,10 @@ public TimeValue timeTook() { public List values() { return emptyList(); } + + @Override + public ShardSearchFailure[] shardFailures() { + return shardFailures; + } + } diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/session/EqlConfiguration.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/session/EqlConfiguration.java index 8dd8220fb63bc..8242b0b533ad3 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/session/EqlConfiguration.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/session/EqlConfiguration.java @@ -30,6 +30,8 @@ public class EqlConfiguration extends org.elasticsearch.xpack.ql.session.Configu private final EqlSearchTask task; private final int fetchSize; private final int maxSamplesPerKey; + private final boolean allowPartialSearchResults; + private final boolean allowPartialSequenceResults; @Nullable private final QueryBuilder filter; @@ -50,6 +52,8 @@ public EqlConfiguration( IndicesOptions indicesOptions, int fetchSize, int maxSamplesPerKey, + boolean allowPartialSearchResults, + boolean allowPartialSequenceResults, String clientId, TaskId taskId, EqlSearchTask task @@ -67,6 +71,8 @@ public EqlConfiguration( this.task = task; this.fetchSize = fetchSize; this.maxSamplesPerKey = maxSamplesPerKey; + this.allowPartialSearchResults = allowPartialSearchResults; + this.allowPartialSequenceResults = allowPartialSequenceResults; } public String[] indices() { @@ -89,6 +95,14 @@ public int maxSamplesPerKey() { return maxSamplesPerKey; } + public boolean allowPartialSearchResults() { + return allowPartialSearchResults; + } + + public boolean allowPartialSequenceResults() { + return allowPartialSequenceResults; + } + public QueryBuilder filter() { return filter; } diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/session/Payload.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/session/Payload.java index 1d82478e6db26..05e614714a5aa 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/session/Payload.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/session/Payload.java @@ -7,6 +7,7 @@ package org.elasticsearch.xpack.eql.session; +import org.elasticsearch.action.search.ShardSearchFailure; import org.elasticsearch.core.TimeValue; import java.util.List; @@ -29,4 +30,6 @@ enum Type { TimeValue timeTook(); List values(); + + ShardSearchFailure[] shardFailures(); } diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/session/Results.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/session/Results.java index bb76c08c801cb..13886470f21f5 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/session/Results.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/session/Results.java @@ -9,6 +9,7 @@ import org.apache.lucene.search.TotalHits; import org.apache.lucene.search.TotalHits.Relation; +import org.elasticsearch.action.search.ShardSearchFailure; import org.elasticsearch.core.TimeValue; import org.elasticsearch.xpack.eql.action.EqlSearchResponse.Event; import org.elasticsearch.xpack.eql.action.EqlSearchResponse.Sequence; @@ -23,18 +24,28 @@ public class Results { private final boolean timedOut; private final TimeValue tookTime; private final Type type; + private ShardSearchFailure[] shardFailures; public static Results fromPayload(Payload payload) { List values = payload.values(); - return new Results(new TotalHits(values.size(), Relation.EQUAL_TO), payload.timeTook(), false, values, payload.resultType()); + payload.shardFailures(); + return new Results( + new TotalHits(values.size(), Relation.EQUAL_TO), + payload.timeTook(), + false, + values, + payload.resultType(), + payload.shardFailures() + ); } - Results(TotalHits totalHits, TimeValue tookTime, boolean timedOut, List results, Type type) { + Results(TotalHits totalHits, TimeValue tookTime, boolean timedOut, List results, Type type, ShardSearchFailure[] shardFailures) { this.totalHits = totalHits; this.tookTime = tookTime; this.timedOut = timedOut; this.results = results; this.type = type; + this.shardFailures = shardFailures; } public TotalHits totalHits() { @@ -51,6 +62,10 @@ public List sequences() { return (type == Type.SEQUENCE || type == Type.SAMPLE) ? (List) results : null; } + public ShardSearchFailure[] shardFailures() { + return shardFailures; + } + public TimeValue tookTime() { return tookTime; } diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/util/SearchHitUtils.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/util/SearchHitUtils.java index 91795ac15b53e..2b5ec9718cfc4 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/util/SearchHitUtils.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/util/SearchHitUtils.java @@ -7,8 +7,12 @@ package org.elasticsearch.xpack.eql.util; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.action.search.ShardSearchFailure; import org.elasticsearch.search.SearchHit; +import java.util.Map; + import static org.elasticsearch.transport.RemoteClusterAware.buildRemoteIndexName; public final class SearchHitUtils { @@ -16,4 +20,12 @@ public final class SearchHitUtils { public static String qualifiedIndex(SearchHit hit) { return buildRemoteIndexName(hit.getClusterAlias(), hit.getIndex()); } + + public static void addShardFailures(Map shardFailures, SearchResponse r) { + if (r.getShardFailures() != null) { + for (ShardSearchFailure shardFailure : r.getShardFailures()) { + shardFailures.put(shardFailure.toString(), shardFailure); + } + } + } } diff --git a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/EqlTestUtils.java b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/EqlTestUtils.java index a1aa8e4bd98d7..75884fab4dbb3 100644 --- a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/EqlTestUtils.java +++ b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/EqlTestUtils.java @@ -51,6 +51,8 @@ private EqlTestUtils() {} null, 123, 1, + false, + true, "", new TaskId("test", 123), null @@ -69,6 +71,8 @@ public static EqlConfiguration randomConfiguration() { randomIndicesOptions(), randomIntBetween(1, 1000), randomIntBetween(1, 1000), + randomBoolean(), + randomBoolean(), randomAlphaOfLength(16), new TaskId(randomAlphaOfLength(10), randomNonNegativeLong()), randomTask() diff --git a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/action/EqlSearchRequestTests.java b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/action/EqlSearchRequestTests.java index 0ff9fa9131b27..1a06aead910c8 100644 --- a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/action/EqlSearchRequestTests.java +++ b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/action/EqlSearchRequestTests.java @@ -80,6 +80,8 @@ protected EqlSearchRequest createTestInstance() { .waitForCompletionTimeout(randomTimeValue()) .keepAlive(randomTimeValue()) .keepOnCompletion(randomBoolean()) + .allowPartialSearchResults(randomBoolean()) + .allowPartialSequenceResults(randomBoolean()) .fetchFields(randomFetchFields) .runtimeMappings(randomRuntimeMappings()) .resultPosition(randomFrom("tail", "head")) @@ -136,6 +138,12 @@ protected EqlSearchRequest mutateInstanceForVersion(EqlSearchRequest instance, T mutatedInstance.runtimeMappings(version.onOrAfter(TransportVersions.V_7_13_0) ? instance.runtimeMappings() : emptyMap()); mutatedInstance.resultPosition(version.onOrAfter(TransportVersions.V_7_17_8) ? instance.resultPosition() : "tail"); mutatedInstance.maxSamplesPerKey(version.onOrAfter(TransportVersions.V_8_7_0) ? instance.maxSamplesPerKey() : 1); + mutatedInstance.allowPartialSearchResults( + version.onOrAfter(TransportVersions.EQL_ALLOW_PARTIAL_SEARCH_RESULTS) ? instance.allowPartialSearchResults() : false + ); + mutatedInstance.allowPartialSequenceResults( + version.onOrAfter(TransportVersions.EQL_ALLOW_PARTIAL_SEARCH_RESULTS) ? instance.allowPartialSequenceResults() : false + ); return mutatedInstance; } diff --git a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/action/EqlSearchResponseTests.java b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/action/EqlSearchResponseTests.java index 6cb283d11848e..fa118a5256df1 100644 --- a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/action/EqlSearchResponseTests.java +++ b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/action/EqlSearchResponseTests.java @@ -9,6 +9,7 @@ import org.apache.lucene.search.TotalHits; import org.elasticsearch.TransportVersion; import org.elasticsearch.TransportVersions; +import org.elasticsearch.action.search.ShardSearchFailure; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.document.DocumentField; @@ -190,7 +191,7 @@ public static EqlSearchResponse createRandomEventsResponse(TotalHits totalHits, hits = new EqlSearchResponse.Hits(randomEvents(xType), null, totalHits); } if (randomBoolean()) { - return new EqlSearchResponse(hits, randomIntBetween(0, 1001), randomBoolean()); + return new EqlSearchResponse(hits, randomIntBetween(0, 1001), randomBoolean(), ShardSearchFailure.EMPTY_ARRAY); } else { return new EqlSearchResponse( hits, @@ -198,7 +199,8 @@ public static EqlSearchResponse createRandomEventsResponse(TotalHits totalHits, randomBoolean(), randomAlphaOfLength(10), randomBoolean(), - randomBoolean() + randomBoolean(), + ShardSearchFailure.EMPTY_ARRAY ); } } @@ -222,7 +224,7 @@ public static EqlSearchResponse createRandomSequencesResponse(TotalHits totalHit hits = new EqlSearchResponse.Hits(null, seq, totalHits); } if (randomBoolean()) { - return new EqlSearchResponse(hits, randomIntBetween(0, 1001), randomBoolean()); + return new EqlSearchResponse(hits, randomIntBetween(0, 1001), randomBoolean(), ShardSearchFailure.EMPTY_ARRAY); } else { return new EqlSearchResponse( hits, @@ -230,7 +232,8 @@ public static EqlSearchResponse createRandomSequencesResponse(TotalHits totalHit randomBoolean(), randomAlphaOfLength(10), randomBoolean(), - randomBoolean() + randomBoolean(), + ShardSearchFailure.EMPTY_ARRAY ); } } @@ -273,7 +276,8 @@ protected EqlSearchResponse mutateInstanceForVersion(EqlSearchResponse instance, instance.isTimeout(), instance.id(), instance.isRunning(), - instance.isPartial() + instance.isPartial(), + ShardSearchFailure.EMPTY_ARRAY ); } diff --git a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/action/LocalStateEQLXPackPlugin.java b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/action/LocalStateEQLXPackPlugin.java index 4d5201f544d72..33573b99546fb 100644 --- a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/action/LocalStateEQLXPackPlugin.java +++ b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/action/LocalStateEQLXPackPlugin.java @@ -7,26 +7,41 @@ package org.elasticsearch.xpack.eql.action; +import org.elasticsearch.common.breaker.CircuitBreaker; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.indices.breaker.BreakerSettings; import org.elasticsearch.license.XPackLicenseState; +import org.elasticsearch.plugins.CircuitBreakerPlugin; import org.elasticsearch.xpack.core.LocalStateCompositeXPackPlugin; import org.elasticsearch.xpack.eql.plugin.EqlPlugin; import org.elasticsearch.xpack.ql.plugin.QlPlugin; import java.nio.file.Path; -public class LocalStateEQLXPackPlugin extends LocalStateCompositeXPackPlugin { +public class LocalStateEQLXPackPlugin extends LocalStateCompositeXPackPlugin implements CircuitBreakerPlugin { + + private final EqlPlugin eqlPlugin; public LocalStateEQLXPackPlugin(final Settings settings, final Path configPath) { super(settings, configPath); LocalStateEQLXPackPlugin thisVar = this; - plugins.add(new EqlPlugin() { + this.eqlPlugin = new EqlPlugin() { @Override protected XPackLicenseState getLicenseState() { return thisVar.getLicenseState(); } - }); + }; + plugins.add(eqlPlugin); plugins.add(new QlPlugin()); } + @Override + public BreakerSettings getCircuitBreaker(Settings settings) { + return eqlPlugin.getCircuitBreaker(settings); + } + + @Override + public void setCircuitBreaker(CircuitBreaker circuitBreaker) { + eqlPlugin.setCircuitBreaker(circuitBreaker); + } } diff --git a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/assembler/ImplicitTiebreakerTests.java b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/assembler/ImplicitTiebreakerTests.java index 7bb6a228f6e48..abd928b04a9c7 100644 --- a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/assembler/ImplicitTiebreakerTests.java +++ b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/assembler/ImplicitTiebreakerTests.java @@ -141,7 +141,15 @@ public void testImplicitTiebreakerBeingSet() { booleanArrayOf(stages, false), NOOP_CIRCUIT_BREAKER ); - TumblingWindow window = new TumblingWindow(client, criteria, null, matcher, Collections.emptyList()); + TumblingWindow window = new TumblingWindow( + client, + criteria, + null, + matcher, + Collections.emptyList(), + randomBoolean(), + randomBoolean() + ); window.execute(wrap(p -> {}, ex -> { throw ExceptionsHelper.convertToRuntime(ex); })); } } diff --git a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/assembler/SequenceSpecTests.java b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/assembler/SequenceSpecTests.java index a8ed842e94c44..f6aa851b2fff0 100644 --- a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/assembler/SequenceSpecTests.java +++ b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/assembler/SequenceSpecTests.java @@ -277,7 +277,15 @@ public void test() throws Exception { ); QueryClient testClient = new TestQueryClient(); - TumblingWindow window = new TumblingWindow(testClient, criteria, null, matcher, Collections.emptyList()); + TumblingWindow window = new TumblingWindow( + testClient, + criteria, + null, + matcher, + Collections.emptyList(), + randomBoolean(), + randomBoolean() + ); // finally make the assertion at the end of the listener window.execute(ActionTestUtils.assertNoFailureListener(this::checkResults)); diff --git a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/sample/CircuitBreakerTests.java b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/sample/CircuitBreakerTests.java index dc132659417ff..80b1ff97b725d 100644 --- a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/sample/CircuitBreakerTests.java +++ b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/sample/CircuitBreakerTests.java @@ -89,7 +89,7 @@ public void query(QueryRequest r, ActionListener l) {} @Override public void fetchHits(Iterable> refs, ActionListener>> listener) {} - }, mockCriteria(), randomIntBetween(10, 500), new Limit(1000, 0), CIRCUIT_BREAKER, 1); + }, mockCriteria(), randomIntBetween(10, 500), new Limit(1000, 0), CIRCUIT_BREAKER, 1, randomBoolean()); CIRCUIT_BREAKER.startBreaking(); iterator.pushToStack(new SampleIterator.Page(CB_STACK_SIZE_PRECISION - 1)); @@ -142,7 +142,8 @@ public void fetchHits(Iterable> refs, ActionListener> refs, ActionListener { // do nothing, we don't care about the query results }, ex -> { fail("Shouldn't have failed"); })); diff --git a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/sequence/CircuitBreakerTests.java b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/sequence/CircuitBreakerTests.java index fe1fca45364e3..58448d981fcca 100644 --- a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/sequence/CircuitBreakerTests.java +++ b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/sequence/CircuitBreakerTests.java @@ -146,7 +146,15 @@ public void testCircuitBreakerTumblingWindow() { booleanArrayOf(stages, false), CIRCUIT_BREAKER ); - TumblingWindow window = new TumblingWindow(client, criteria, null, matcher, Collections.emptyList()); + TumblingWindow window = new TumblingWindow( + client, + criteria, + null, + matcher, + Collections.emptyList(), + randomBoolean(), + randomBoolean() + ); window.execute(ActionTestUtils.assertNoFailureListener(p -> {})); CIRCUIT_BREAKER.startBreaking(); @@ -228,7 +236,15 @@ private void assertMemoryCleared( booleanArrayOf(sequenceFiltersCount, false), eqlCircuitBreaker ); - TumblingWindow window = new TumblingWindow(eqlClient, criteria, null, matcher, Collections.emptyList()); + TumblingWindow window = new TumblingWindow( + eqlClient, + criteria, + null, + matcher, + Collections.emptyList(), + randomBoolean(), + randomBoolean() + ); window.execute(ActionListener.noop()); assertTrue(esClient.searchRequestsRemainingCount() == 0); // ensure all the search requests have been asked for @@ -271,7 +287,15 @@ public void testEqlCBCleanedUp_on_ParentCBBreak() { booleanArrayOf(sequenceFiltersCount, false), eqlCircuitBreaker ); - TumblingWindow window = new TumblingWindow(eqlClient, criteria, null, matcher, Collections.emptyList()); + TumblingWindow window = new TumblingWindow( + eqlClient, + criteria, + null, + matcher, + Collections.emptyList(), + randomBoolean(), + randomBoolean() + ); window.execute(wrap(p -> fail(), ex -> assertTrue(ex instanceof CircuitBreakingException))); } assertCriticalWarnings("[indices.breaker.total.limit] setting of [0%] is below the recommended minimum of 50.0% of the heap"); @@ -329,6 +353,8 @@ private QueryClient buildQueryClient(ESMockClient esClient, CircuitBreaker eqlCi null, 123, 1, + randomBoolean(), + randomBoolean(), "", new TaskId("test", 123), new EqlSearchTask( diff --git a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/sequence/PITFailureTests.java b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/sequence/PITFailureTests.java index 1a2f00463b49b..2eee6a262e73c 100644 --- a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/sequence/PITFailureTests.java +++ b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/execution/sequence/PITFailureTests.java @@ -83,6 +83,8 @@ public void testHandlingPitFailure() { null, 123, 1, + randomBoolean(), + randomBoolean(), "", new TaskId("test", 123), new EqlSearchTask( @@ -132,7 +134,15 @@ public void testHandlingPitFailure() { ); SequenceMatcher matcher = new SequenceMatcher(1, false, TimeValue.MINUS_ONE, null, booleanArrayOf(1, false), cb); - TumblingWindow window = new TumblingWindow(eqlClient, criteria, null, matcher, Collections.emptyList()); + TumblingWindow window = new TumblingWindow( + eqlClient, + criteria, + null, + matcher, + Collections.emptyList(), + randomBoolean(), + randomBoolean() + ); window.execute( wrap( p -> { fail("Search succeeded despite PIT failure"); }, From 51eb386a70e20bf17b42f44dda3e6a9bdd37321c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20J=C3=B3zala?= <377355+jozala@users.noreply.github.com> Date: Tue, 17 Dec 2024 17:48:57 +0100 Subject: [PATCH 04/60] [ci] Add ubuntu-2404-aarch64 to test matrix in platform-support (#118847) --- .buildkite/pipelines/periodic-platform-support.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.buildkite/pipelines/periodic-platform-support.yml b/.buildkite/pipelines/periodic-platform-support.yml index c5846a763f5e8..ea0d7b13b55b4 100644 --- a/.buildkite/pipelines/periodic-platform-support.yml +++ b/.buildkite/pipelines/periodic-platform-support.yml @@ -63,6 +63,7 @@ steps: image: - almalinux-8-aarch64 - ubuntu-2004-aarch64 + - ubuntu-2404-aarch64 GRADLE_TASK: - checkPart1 - checkPart2 From b8f4677254f7a0cd29c8ded0361f3ab201232cd5 Mon Sep 17 00:00:00 2001 From: Ievgen Degtiarenko Date: Tue, 17 Dec 2024 18:11:50 +0100 Subject: [PATCH 05/60] Replace build with scope parameter (#118643) This change replaces the build with scope parameter in order to make it cleaner when parameter is build and how it is used. --- .../org/elasticsearch/compute/ann/Fixed.java | 26 +++++++++++++------ .../compute/gen/EvaluatorImplementer.java | 15 ++++++++--- .../function/scalar/convert/FromBase64.java | 3 ++- .../function/scalar/convert/ToBase64.java | 3 ++- .../function/scalar/ip/IpPrefix.java | 3 ++- .../multivalue/MvPSeriesWeightedSum.java | 3 ++- .../scalar/multivalue/MvPercentile.java | 7 ++--- .../function/scalar/string/Concat.java | 3 ++- .../function/scalar/string/Left.java | 5 ++-- .../function/scalar/string/Repeat.java | 9 +++++-- .../function/scalar/string/Right.java | 5 ++-- .../function/scalar/string/Space.java | 3 ++- .../function/scalar/string/Split.java | 5 ++-- 13 files changed, 61 insertions(+), 29 deletions(-) diff --git a/x-pack/plugin/esql/compute/ann/src/main/java/org/elasticsearch/compute/ann/Fixed.java b/x-pack/plugin/esql/compute/ann/src/main/java/org/elasticsearch/compute/ann/Fixed.java index 62703fa400ff7..1f10abf3b9fb0 100644 --- a/x-pack/plugin/esql/compute/ann/src/main/java/org/elasticsearch/compute/ann/Fixed.java +++ b/x-pack/plugin/esql/compute/ann/src/main/java/org/elasticsearch/compute/ann/Fixed.java @@ -11,7 +11,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import java.util.function.Function; /** * Used on parameters on methods annotated with {@link Evaluator} to indicate @@ -27,12 +26,23 @@ boolean includeInToString() default true; /** - * Should the Evaluator's factory build this per evaluator with a - * {@code Function} or just take fixed implementation? - * This is typically set to {@code true} to use the {@link Function} - * to make "scratch" objects which have to be isolated in a single thread. - * This is typically set to {@code false} when the parameter is simply - * immutable and can be shared. + * Defines the scope of the parameter. + * - SINGLETON (default) will build a single instance and share it across all evaluators + * - THREAD_LOCAL will build a new instance for each evaluator thread */ - boolean build() default false; + Scope scope() default Scope.SINGLETON; + + /** + * Defines the parameter scope + */ + enum Scope { + /** + * Should be used for immutable parameters that can be shared across different threads + */ + SINGLETON, + /** + * Should be used for mutable or not thread safe parameters + */ + THREAD_LOCAL, + } } diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorImplementer.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorImplementer.java index 5869eff23a9ab..b4a0cf9127f23 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorImplementer.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorImplementer.java @@ -16,6 +16,7 @@ import com.squareup.javapoet.TypeSpec; import org.elasticsearch.compute.ann.Fixed; +import org.elasticsearch.compute.ann.Fixed.Scope; import java.util.ArrayList; import java.util.Arrays; @@ -725,7 +726,7 @@ public String closeInvocation() { } } - private record FixedProcessFunctionArg(TypeName type, String name, boolean includeInToString, boolean build, boolean releasable) + private record FixedProcessFunctionArg(TypeName type, String name, boolean includeInToString, Scope scope, boolean releasable) implements ProcessFunctionArg { @Override @@ -762,12 +763,18 @@ public void implementFactoryCtor(MethodSpec.Builder builder) { } private TypeName factoryFieldType() { - return build ? ParameterizedTypeName.get(ClassName.get(Function.class), DRIVER_CONTEXT, type.box()) : type; + return switch (scope) { + case SINGLETON -> type; + case THREAD_LOCAL -> ParameterizedTypeName.get(ClassName.get(Function.class), DRIVER_CONTEXT, type.box()); + }; } @Override public String factoryInvocation(MethodSpec.Builder factoryMethodBuilder) { - return build ? name + ".apply(context)" : name; + return switch (scope) { + case SINGLETON -> name; + case THREAD_LOCAL -> name + ".apply(context)"; + }; } @Override @@ -1020,7 +1027,7 @@ private ProcessFunction( type, name, fixed.includeInToString(), - fixed.build(), + fixed.scope(), Types.extendsSuper(types, v.asType(), "org.elasticsearch.core.Releasable") ) ); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/FromBase64.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/FromBase64.java index 7f9d0d3f2e647..832c511a2dc50 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/FromBase64.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/FromBase64.java @@ -30,6 +30,7 @@ import java.util.Base64; import java.util.List; +import static org.elasticsearch.compute.ann.Fixed.Scope.THREAD_LOCAL; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isString; import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; @@ -85,7 +86,7 @@ protected NodeInfo info() { } @Evaluator() - static BytesRef process(BytesRef field, @Fixed(includeInToString = false, build = true) BytesRefBuilder oScratch) { + static BytesRef process(BytesRef field, @Fixed(includeInToString = false, scope = THREAD_LOCAL) BytesRefBuilder oScratch) { byte[] bytes = new byte[field.length]; System.arraycopy(field.bytes, field.offset, bytes, 0, field.length); oScratch.grow(field.length); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBase64.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBase64.java index c23cef31f32f5..e78968bb209b6 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBase64.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToBase64.java @@ -30,6 +30,7 @@ import java.util.Base64; import java.util.List; +import static org.elasticsearch.compute.ann.Fixed.Scope.THREAD_LOCAL; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isString; import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; @@ -78,7 +79,7 @@ protected NodeInfo info() { } @Evaluator(warnExceptions = { ArithmeticException.class }) - static BytesRef process(BytesRef field, @Fixed(includeInToString = false, build = true) BytesRefBuilder oScratch) { + static BytesRef process(BytesRef field, @Fixed(includeInToString = false, scope = THREAD_LOCAL) BytesRefBuilder oScratch) { int outLength = Math.multiplyExact(4, (Math.addExact(field.length, 2) / 3)); byte[] bytes = new byte[field.length]; System.arraycopy(field.bytes, field.offset, bytes, 0, field.length); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/ip/IpPrefix.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/ip/IpPrefix.java index 26e75e752f681..5fc61c5c07b58 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/ip/IpPrefix.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/ip/IpPrefix.java @@ -30,6 +30,7 @@ import java.util.Arrays; import java.util.List; +import static org.elasticsearch.compute.ann.Fixed.Scope.THREAD_LOCAL; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.FIRST; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.SECOND; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.THIRD; @@ -138,7 +139,7 @@ static BytesRef process( BytesRef ip, int prefixLengthV4, int prefixLengthV6, - @Fixed(includeInToString = false, build = true) BytesRef scratch + @Fixed(includeInToString = false, scope = THREAD_LOCAL) BytesRef scratch ) { if (prefixLengthV4 < 0 || prefixLengthV4 > 32) { throw new IllegalArgumentException("Prefix length v4 must be in range [0, 32], found " + prefixLengthV4); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvPSeriesWeightedSum.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvPSeriesWeightedSum.java index cf49607893aae..4dd447f938880 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvPSeriesWeightedSum.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvPSeriesWeightedSum.java @@ -33,6 +33,7 @@ import java.util.Arrays; import java.util.List; +import static org.elasticsearch.compute.ann.Fixed.Scope.THREAD_LOCAL; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.FIRST; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.SECOND; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isFoldable; @@ -144,7 +145,7 @@ static void process( DoubleBlock.Builder builder, int position, DoubleBlock block, - @Fixed(includeInToString = false, build = true) CompensatedSum sum, + @Fixed(includeInToString = false, scope = THREAD_LOCAL) CompensatedSum sum, @Fixed double p ) { sum.reset(0, 0); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvPercentile.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvPercentile.java index f3a63c835bd34..4e4aee307f1c7 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvPercentile.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvPercentile.java @@ -35,6 +35,7 @@ import java.util.Arrays; import java.util.List; +import static org.elasticsearch.compute.ann.Fixed.Scope.THREAD_LOCAL; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.FIRST; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.SECOND; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isType; @@ -167,7 +168,7 @@ static void process( int position, DoubleBlock values, double percentile, - @Fixed(includeInToString = false, build = true) DoubleSortingScratch scratch + @Fixed(includeInToString = false, scope = THREAD_LOCAL) DoubleSortingScratch scratch ) { int valueCount = values.getValueCount(position); int firstValueIndex = values.getFirstValueIndex(position); @@ -190,7 +191,7 @@ static void process( int position, IntBlock values, double percentile, - @Fixed(includeInToString = false, build = true) IntSortingScratch scratch + @Fixed(includeInToString = false, scope = THREAD_LOCAL) IntSortingScratch scratch ) { int valueCount = values.getValueCount(position); int firstValueIndex = values.getFirstValueIndex(position); @@ -213,7 +214,7 @@ static void process( int position, LongBlock values, double percentile, - @Fixed(includeInToString = false, build = true) LongSortingScratch scratch + @Fixed(includeInToString = false, scope = THREAD_LOCAL) LongSortingScratch scratch ) { int valueCount = values.getValueCount(position); int firstValueIndex = values.getFirstValueIndex(position); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Concat.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Concat.java index 46ecc9e026d3d..eb173029876d3 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Concat.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Concat.java @@ -32,6 +32,7 @@ import java.util.stream.Stream; import static org.elasticsearch.common.unit.ByteSizeUnit.MB; +import static org.elasticsearch.compute.ann.Fixed.Scope.THREAD_LOCAL; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.DEFAULT; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isString; @@ -111,7 +112,7 @@ public ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvaluator) { } @Evaluator - static BytesRef process(@Fixed(includeInToString = false, build = true) BreakingBytesRefBuilder scratch, BytesRef[] values) { + static BytesRef process(@Fixed(includeInToString = false, scope = THREAD_LOCAL) BreakingBytesRefBuilder scratch, BytesRef[] values) { scratch.grow(checkedTotalLength(values)); scratch.clear(); for (int i = 0; i < values.length; i++) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Left.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Left.java index e7572caafd8f5..0d885e3f3c341 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Left.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Left.java @@ -30,6 +30,7 @@ import java.util.Arrays; import java.util.List; +import static org.elasticsearch.compute.ann.Fixed.Scope.THREAD_LOCAL; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.FIRST; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.SECOND; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isString; @@ -77,8 +78,8 @@ public String getWriteableName() { @Evaluator static BytesRef process( - @Fixed(includeInToString = false, build = true) BytesRef out, - @Fixed(includeInToString = false, build = true) UnicodeUtil.UTF8CodePoint cp, + @Fixed(includeInToString = false, scope = THREAD_LOCAL) BytesRef out, + @Fixed(includeInToString = false, scope = THREAD_LOCAL) UnicodeUtil.UTF8CodePoint cp, BytesRef str, int length ) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Repeat.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Repeat.java index 2cc14399df2ae..e91f03de3dd7e 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Repeat.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Repeat.java @@ -31,6 +31,7 @@ import java.util.List; import static org.elasticsearch.common.unit.ByteSizeUnit.MB; +import static org.elasticsearch.compute.ann.Fixed.Scope.THREAD_LOCAL; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.FIRST; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.SECOND; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isString; @@ -101,7 +102,7 @@ public boolean foldable() { @Evaluator(extraName = "Constant", warnExceptions = { IllegalArgumentException.class }) static BytesRef processConstantNumber( - @Fixed(includeInToString = false, build = true) BreakingBytesRefBuilder scratch, + @Fixed(includeInToString = false, scope = THREAD_LOCAL) BreakingBytesRefBuilder scratch, BytesRef str, @Fixed int number ) { @@ -109,7 +110,11 @@ static BytesRef processConstantNumber( } @Evaluator(warnExceptions = { IllegalArgumentException.class }) - static BytesRef process(@Fixed(includeInToString = false, build = true) BreakingBytesRefBuilder scratch, BytesRef str, int number) { + static BytesRef process( + @Fixed(includeInToString = false, scope = THREAD_LOCAL) BreakingBytesRefBuilder scratch, + BytesRef str, + int number + ) { if (number < 0) { throw new IllegalArgumentException("Number parameter cannot be negative, found [" + number + "]"); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Right.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Right.java index b069b984ea81e..e0ebed29cca72 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Right.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Right.java @@ -30,6 +30,7 @@ import java.util.Arrays; import java.util.List; +import static org.elasticsearch.compute.ann.Fixed.Scope.THREAD_LOCAL; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.FIRST; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.SECOND; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isString; @@ -77,8 +78,8 @@ public String getWriteableName() { @Evaluator static BytesRef process( - @Fixed(includeInToString = false, build = true) BytesRef out, - @Fixed(includeInToString = false, build = true) UnicodeUtil.UTF8CodePoint cp, + @Fixed(includeInToString = false, scope = THREAD_LOCAL) BytesRef out, + @Fixed(includeInToString = false, scope = THREAD_LOCAL) UnicodeUtil.UTF8CodePoint cp, BytesRef str, int length ) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Space.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Space.java index 6481ce5764e1f..3b9a466966911 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Space.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Space.java @@ -31,6 +31,7 @@ import java.util.List; import static org.elasticsearch.common.unit.ByteSizeUnit.MB; +import static org.elasticsearch.compute.ann.Fixed.Scope.THREAD_LOCAL; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.DEFAULT; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isType; import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; @@ -82,7 +83,7 @@ protected TypeResolution resolveType() { } @Evaluator(warnExceptions = { IllegalArgumentException.class }) - static BytesRef process(@Fixed(includeInToString = false, build = true) BreakingBytesRefBuilder scratch, int number) { + static BytesRef process(@Fixed(includeInToString = false, scope = THREAD_LOCAL) BreakingBytesRefBuilder scratch, int number) { checkNumber(number); scratch.grow(number); scratch.setLength(number); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Split.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Split.java index b1f5da56d011b..24762122f755b 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Split.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Split.java @@ -29,6 +29,7 @@ import java.io.IOException; +import static org.elasticsearch.compute.ann.Fixed.Scope.THREAD_LOCAL; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.FIRST; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.SECOND; import static org.elasticsearch.xpack.esql.expression.EsqlTypeResolutions.isStringAndExact; @@ -110,7 +111,7 @@ static void process( BytesRefBlock.Builder builder, BytesRef str, @Fixed byte delim, - @Fixed(includeInToString = false, build = true) BytesRef scratch + @Fixed(includeInToString = false, scope = THREAD_LOCAL) BytesRef scratch ) { scratch.bytes = str.bytes; scratch.offset = str.offset; @@ -140,7 +141,7 @@ static void process( BytesRefBlock.Builder builder, BytesRef str, BytesRef delim, - @Fixed(includeInToString = false, build = true) BytesRef scratch + @Fixed(includeInToString = false, scope = THREAD_LOCAL) BytesRef scratch ) { checkDelimiter(delim); process(builder, str, delim.bytes[delim.offset], scratch); From d788761ea985a74aac90c6aee15fe32dea18e2ad Mon Sep 17 00:00:00 2001 From: Artem Prigoda Date: Tue, 17 Dec 2024 18:18:24 +0100 Subject: [PATCH 06/60] [test] Correctly mute MixedClusterClientYamlTestSuiteIT {cat.shards/10_basic/Help} (#116398) The `sync_id` field was removed from the `cat shards` output for 9.0 in #114246, this test shouldn't be run along with other 8.x clusters Resolve #116110 --- muted-tests.yml | 3 --- qa/mixed-cluster/build.gradle | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/muted-tests.yml b/muted-tests.yml index 42845fda82180..93d1a6e6374b7 100644 --- a/muted-tests.yml +++ b/muted-tests.yml @@ -87,9 +87,6 @@ tests: issue: https://github.com/elastic/elasticsearch/issues/115816 - class: org.elasticsearch.xpack.application.connector.ConnectorIndexServiceTests issue: https://github.com/elastic/elasticsearch/issues/116087 -- class: org.elasticsearch.backwards.MixedClusterClientYamlTestSuiteIT - method: test {p0=cat.shards/10_basic/Help} - issue: https://github.com/elastic/elasticsearch/issues/116110 - class: org.elasticsearch.xpack.ml.integration.DatafeedJobsRestIT method: testLookbackWithIndicesOptions issue: https://github.com/elastic/elasticsearch/issues/116127 diff --git a/qa/mixed-cluster/build.gradle b/qa/mixed-cluster/build.gradle index d8f906b23d523..28bcac9f0242d 100644 --- a/qa/mixed-cluster/build.gradle +++ b/qa/mixed-cluster/build.gradle @@ -67,6 +67,9 @@ excludeList.add('indices.resolve_index/20_resolve_system_index/*') // Excluded because the error has changed excludeList.add('aggregations/percentiles_hdr_metric/Negative values test') +// sync_id is removed in 9.0 +excludeList.add("cat.shards/10_basic/Help") + def clusterPath = getPath() buildParams.bwcVersions.withWireCompatible { bwcVersion, baseName -> From 70087e3ded47e905dce9be09a969768345c0fa43 Mon Sep 17 00:00:00 2001 From: "elastic-renovate-prod[bot]" <174716857+elastic-renovate-prod[bot]@users.noreply.github.com> Date: Tue, 17 Dec 2024 17:58:19 +0000 Subject: [PATCH 07/60] Update docker.elastic.co/wolfi/chainguard-base:latest Docker digest to bfdeddb (#118868) Co-authored-by: elastic-renovate-prod[bot] <174716857+elastic-renovate-prod[bot]@users.noreply.github.com> --- .../main/java/org/elasticsearch/gradle/internal/DockerBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/DockerBase.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/DockerBase.java index d54eb798ce783..985c98bcd7883 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/DockerBase.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/DockerBase.java @@ -22,7 +22,7 @@ public enum DockerBase { // Chainguard based wolfi image with latest jdk // This is usually updated via renovatebot // spotless:off - WOLFI("docker.elastic.co/wolfi/chainguard-base:latest@sha256:1b51ff6dba78c98d3e02b0cd64a8ce3238c7a40408d21e3af12a329d44db6f23", + WOLFI("docker.elastic.co/wolfi/chainguard-base:latest@sha256:bfdeddb33330a281950c2a54adef991dbbe6a42832bc505d13b11beaf50ae73f", "-wolfi", "apk" ), From f3a16649068799aabfdafa0bc0bacf71c4409687 Mon Sep 17 00:00:00 2001 From: Tanguy Leroux Date: Tue, 17 Dec 2024 18:59:49 +0100 Subject: [PATCH 08/60] Add min. read-only index version compatible to DiscoveryNode (#118744) #118443 added a new index version for indices that can be opened in read-only mode by Lucene. This change adds this information to the discovery node's VersionInformation and the transport serialization logic. In a short future we'd like to use this information in methods like IndexMetadataVerifier#checkSupportedVersion and NodeJoineExecutor to allow opening indices in N-2 versions as read-only indices on ES V9. --- docs/reference/indices/shard-stores.asciidoc | 6 +- .../org/elasticsearch/TransportVersions.java | 1 + .../cluster/node/DiscoveryNode.java | 21 ++++++- .../cluster/node/DiscoveryNodes.java | 15 +++++ .../cluster/node/VersionInformation.java | 32 ++++++++-- .../HandshakingTransportAddressConnector.java | 1 + .../transport/ProxyConnectionStrategy.java | 1 + .../transport/SniffConnectionStrategy.java | 1 + .../reroute/ClusterRerouteResponseTests.java | 2 + .../cluster/ClusterStateTests.java | 6 ++ .../cluster/node/DiscoveryNodeTests.java | 61 +++++++++++++++++++ .../cluster/node/DiscoveryNodeUtils.java | 15 ++++- .../ClusterStatsMonitoringDocTests.java | 2 + 13 files changed, 152 insertions(+), 12 deletions(-) diff --git a/docs/reference/indices/shard-stores.asciidoc b/docs/reference/indices/shard-stores.asciidoc index 1b001a3175b8c..04b086a758f9d 100644 --- a/docs/reference/indices/shard-stores.asciidoc +++ b/docs/reference/indices/shard-stores.asciidoc @@ -172,8 +172,9 @@ The API returns the following response: "attributes": {}, "roles": [...], "version": "8.10.0", - "min_index_version": 7000099, - "max_index_version": 8100099 + "min_index_version": 8000099, + "min_read_only_index_version": 7000099, + "max_index_version": 9004000 }, "allocation_id": "2iNySv_OQVePRX-yaRH_lQ", <4> "allocation" : "primary|replica|unused" <5> @@ -193,6 +194,7 @@ The API returns the following response: // TESTRESPONSE[s/"roles": \[[^]]*\]/"roles": $body.$_path/] // TESTRESPONSE[s/"8.10.0"/\$node_version/] // TESTRESPONSE[s/"min_index_version": 7000099/"min_index_version": $body.$_path/] +// TESTRESPONSE[s/"min_index_version": 7000099/"min_index_version": $body.$_path/] // TESTRESPONSE[s/"max_index_version": 8100099/"max_index_version": $body.$_path/] diff --git a/server/src/main/java/org/elasticsearch/TransportVersions.java b/server/src/main/java/org/elasticsearch/TransportVersions.java index 371af961720cc..d3e235f1cd82a 100644 --- a/server/src/main/java/org/elasticsearch/TransportVersions.java +++ b/server/src/main/java/org/elasticsearch/TransportVersions.java @@ -139,6 +139,7 @@ static TransportVersion def(int id) { public static final TransportVersion SEMANTIC_QUERY_LENIENT = def(8_807_00_0); public static final TransportVersion ESQL_QUERY_BUILDER_IN_SEARCH_FUNCTIONS = def(8_808_00_0); public static final TransportVersion EQL_ALLOW_PARTIAL_SEARCH_RESULTS = def(8_809_00_0); + public static final TransportVersion NODE_VERSION_INFORMATION_WITH_MIN_READ_ONLY_INDEX_VERSION = def(8_810_00_0); /* * STOP! READ THIS FIRST! No, really, diff --git a/server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNode.java b/server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNode.java index 7bf367f99b929..7c757e7657853 100644 --- a/server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNode.java +++ b/server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNode.java @@ -37,6 +37,7 @@ import java.util.SortedSet; import java.util.TreeSet; +import static org.elasticsearch.TransportVersions.NODE_VERSION_INFORMATION_WITH_MIN_READ_ONLY_INDEX_VERSION; import static org.elasticsearch.node.NodeRoleSettings.NODE_ROLES_SETTING; /** @@ -325,7 +326,17 @@ public DiscoveryNode(StreamInput in) throws IOException { } } this.roles = Collections.unmodifiableSortedSet(roles); - versionInfo = new VersionInformation(Version.readVersion(in), IndexVersion.readVersion(in), IndexVersion.readVersion(in)); + Version version = Version.readVersion(in); + IndexVersion minIndexVersion = IndexVersion.readVersion(in); + IndexVersion minReadOnlyIndexVersion; + if (in.getTransportVersion().onOrAfter(NODE_VERSION_INFORMATION_WITH_MIN_READ_ONLY_INDEX_VERSION)) { + minReadOnlyIndexVersion = IndexVersion.readVersion(in); + } else { + minReadOnlyIndexVersion = minIndexVersion; + + } + IndexVersion maxIndexVersion = IndexVersion.readVersion(in); + versionInfo = new VersionInformation(version, minIndexVersion, minReadOnlyIndexVersion, maxIndexVersion); if (in.getTransportVersion().onOrAfter(EXTERNAL_ID_VERSION)) { this.externalId = readStringLiteral.read(in); } else { @@ -360,6 +371,9 @@ public void writeTo(StreamOutput out) throws IOException { }); Version.writeVersion(versionInfo.nodeVersion(), out); IndexVersion.writeVersion(versionInfo.minIndexVersion(), out); + if (out.getTransportVersion().onOrAfter(NODE_VERSION_INFORMATION_WITH_MIN_READ_ONLY_INDEX_VERSION)) { + IndexVersion.writeVersion(versionInfo.minReadOnlyIndexVersion(), out); + } IndexVersion.writeVersion(versionInfo.maxIndexVersion(), out); if (out.getTransportVersion().onOrAfter(EXTERNAL_ID_VERSION)) { out.writeString(externalId); @@ -478,6 +492,10 @@ public IndexVersion getMinIndexVersion() { return versionInfo.minIndexVersion(); } + public IndexVersion getMinReadOnlyIndexVersion() { + return versionInfo.minReadOnlyIndexVersion(); + } + public IndexVersion getMaxIndexVersion() { return versionInfo.maxIndexVersion(); } @@ -577,6 +595,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.endArray(); builder.field("version", versionInfo.buildVersion().toString()); builder.field("min_index_version", versionInfo.minIndexVersion()); + builder.field("min_read_only_index_version", versionInfo.minReadOnlyIndexVersion()); builder.field("max_index_version", versionInfo.maxIndexVersion()); builder.endObject(); return builder; diff --git a/server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodes.java b/server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodes.java index 5e6dec7b68062..f733ab223fdd1 100644 --- a/server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodes.java +++ b/server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodes.java @@ -69,6 +69,7 @@ public class DiscoveryNodes implements Iterable, SimpleDiffable> tiersToNodeIds; @@ -84,6 +85,7 @@ private DiscoveryNodes( Version minNodeVersion, IndexVersion maxDataNodeCompatibleIndexVersion, IndexVersion minSupportedIndexVersion, + IndexVersion minReadOnlySupportedIndexVersion, Map> tiersToNodeIds ) { this.nodeLeftGeneration = nodeLeftGeneration; @@ -100,6 +102,8 @@ private DiscoveryNodes( this.maxNodeVersion = maxNodeVersion; this.maxDataNodeCompatibleIndexVersion = maxDataNodeCompatibleIndexVersion; this.minSupportedIndexVersion = minSupportedIndexVersion; + this.minReadOnlySupportedIndexVersion = minReadOnlySupportedIndexVersion; + assert minReadOnlySupportedIndexVersion.onOrBefore(minSupportedIndexVersion); assert (localNodeId == null) == (localNode == null); this.tiersToNodeIds = tiersToNodeIds; } @@ -118,6 +122,7 @@ public DiscoveryNodes withMasterNodeId(@Nullable String masterNodeId) { minNodeVersion, maxDataNodeCompatibleIndexVersion, minSupportedIndexVersion, + minReadOnlySupportedIndexVersion, tiersToNodeIds ); } @@ -374,6 +379,13 @@ public IndexVersion getMinSupportedIndexVersion() { return minSupportedIndexVersion; } + /** + * Returns the minimum index version for read-only indices supported by all nodes in the cluster + */ + public IndexVersion getMinReadOnlySupportedIndexVersion() { + return minReadOnlySupportedIndexVersion; + } + /** * Return the node-left generation, which is the number of times the cluster membership has been updated by removing one or more nodes. *

@@ -840,6 +852,7 @@ public DiscoveryNodes build() { Version maxNodeVersion = null; IndexVersion maxDataNodeCompatibleIndexVersion = null; IndexVersion minSupportedIndexVersion = null; + IndexVersion minReadOnlySupportedIndexVersion = null; for (Map.Entry nodeEntry : nodes.entrySet()) { DiscoveryNode discoNode = nodeEntry.getValue(); Version version = discoNode.getVersion(); @@ -849,6 +862,7 @@ public DiscoveryNodes build() { minNodeVersion = min(minNodeVersion, version); maxNodeVersion = max(maxNodeVersion, version); minSupportedIndexVersion = max(minSupportedIndexVersion, discoNode.getMinIndexVersion()); + minReadOnlySupportedIndexVersion = max(minReadOnlySupportedIndexVersion, discoNode.getMinReadOnlyIndexVersion()); } final long newNodeLeftGeneration; @@ -881,6 +895,7 @@ public DiscoveryNodes build() { Objects.requireNonNullElse(minNodeVersion, Version.CURRENT.minimumCompatibilityVersion()), Objects.requireNonNullElse(maxDataNodeCompatibleIndexVersion, IndexVersion.current()), Objects.requireNonNullElse(minSupportedIndexVersion, IndexVersions.MINIMUM_COMPATIBLE), + Objects.requireNonNullElse(minReadOnlySupportedIndexVersion, IndexVersions.MINIMUM_READONLY_COMPATIBLE), computeTiersToNodesMap(dataNodes) ); } diff --git a/server/src/main/java/org/elasticsearch/cluster/node/VersionInformation.java b/server/src/main/java/org/elasticsearch/cluster/node/VersionInformation.java index a4d0ff1eb55e4..852f31db69c92 100644 --- a/server/src/main/java/org/elasticsearch/cluster/node/VersionInformation.java +++ b/server/src/main/java/org/elasticsearch/cluster/node/VersionInformation.java @@ -18,20 +18,23 @@ /** * Represents the versions of various aspects of an Elasticsearch node. - * @param buildVersion The node {@link BuildVersion} - * @param minIndexVersion The minimum {@link IndexVersion} supported by this node - * @param maxIndexVersion The maximum {@link IndexVersion} supported by this node + * @param buildVersion The node {@link BuildVersion} + * @param minIndexVersion The minimum {@link IndexVersion} supported by this node + * @param minReadOnlyIndexVersion The minimum {@link IndexVersion} for read-only indices supported by this node + * @param maxIndexVersion The maximum {@link IndexVersion} supported by this node */ public record VersionInformation( BuildVersion buildVersion, Version nodeVersion, IndexVersion minIndexVersion, + IndexVersion minReadOnlyIndexVersion, IndexVersion maxIndexVersion ) { public static final VersionInformation CURRENT = new VersionInformation( BuildVersion.current(), IndexVersions.MINIMUM_COMPATIBLE, + IndexVersions.MINIMUM_READONLY_COMPATIBLE, IndexVersion.current() ); @@ -39,11 +42,18 @@ public record VersionInformation( Objects.requireNonNull(buildVersion); Objects.requireNonNull(nodeVersion); Objects.requireNonNull(minIndexVersion); + Objects.requireNonNull(minReadOnlyIndexVersion); Objects.requireNonNull(maxIndexVersion); + assert minReadOnlyIndexVersion.onOrBefore(minIndexVersion) : minReadOnlyIndexVersion + " > " + minIndexVersion; } - public VersionInformation(BuildVersion version, IndexVersion minIndexVersion, IndexVersion maxIndexVersion) { - this(version, Version.CURRENT, minIndexVersion, maxIndexVersion); + public VersionInformation( + BuildVersion version, + IndexVersion minIndexVersion, + IndexVersion minReadOnlyIndexVersion, + IndexVersion maxIndexVersion + ) { + this(version, Version.CURRENT, minIndexVersion, minReadOnlyIndexVersion, maxIndexVersion); /* * Whilst DiscoveryNode.getVersion exists, we need to be able to get a Version from VersionInfo * This needs to be consistent - on serverless, BuildVersion has an id of -1, which translates @@ -57,7 +67,17 @@ public VersionInformation(BuildVersion version, IndexVersion minIndexVersion, In @Deprecated public VersionInformation(Version version, IndexVersion minIndexVersion, IndexVersion maxIndexVersion) { - this(BuildVersion.fromVersionId(version.id()), version, minIndexVersion, maxIndexVersion); + this(version, minIndexVersion, minIndexVersion, maxIndexVersion); + } + + @Deprecated + public VersionInformation( + Version version, + IndexVersion minIndexVersion, + IndexVersion minReadOnlyIndexVersion, + IndexVersion maxIndexVersion + ) { + this(BuildVersion.fromVersionId(version.id()), version, minIndexVersion, minReadOnlyIndexVersion, maxIndexVersion); } @Deprecated diff --git a/server/src/main/java/org/elasticsearch/discovery/HandshakingTransportAddressConnector.java b/server/src/main/java/org/elasticsearch/discovery/HandshakingTransportAddressConnector.java index ce849c26ab780..98715127351aa 100644 --- a/server/src/main/java/org/elasticsearch/discovery/HandshakingTransportAddressConnector.java +++ b/server/src/main/java/org/elasticsearch/discovery/HandshakingTransportAddressConnector.java @@ -110,6 +110,7 @@ private void openProbeConnection(ActionListener listener) new VersionInformation( Version.CURRENT.minimumCompatibilityVersion(), IndexVersions.MINIMUM_COMPATIBLE, + IndexVersions.MINIMUM_READONLY_COMPATIBLE, IndexVersion.current() ) ), diff --git a/server/src/main/java/org/elasticsearch/transport/ProxyConnectionStrategy.java b/server/src/main/java/org/elasticsearch/transport/ProxyConnectionStrategy.java index d5047a61e4606..eb2eab75d3fe3 100644 --- a/server/src/main/java/org/elasticsearch/transport/ProxyConnectionStrategy.java +++ b/server/src/main/java/org/elasticsearch/transport/ProxyConnectionStrategy.java @@ -303,6 +303,7 @@ public void onFailure(Exception e) { new VersionInformation( Version.CURRENT.minimumCompatibilityVersion(), IndexVersions.MINIMUM_COMPATIBLE, + IndexVersions.MINIMUM_READONLY_COMPATIBLE, IndexVersion.current() ) ); diff --git a/server/src/main/java/org/elasticsearch/transport/SniffConnectionStrategy.java b/server/src/main/java/org/elasticsearch/transport/SniffConnectionStrategy.java index 2c198caf22354..854072c49e354 100644 --- a/server/src/main/java/org/elasticsearch/transport/SniffConnectionStrategy.java +++ b/server/src/main/java/org/elasticsearch/transport/SniffConnectionStrategy.java @@ -505,6 +505,7 @@ private static DiscoveryNode resolveSeedNode(String clusterAlias, String address var seedVersion = new VersionInformation( Version.CURRENT.minimumCompatibilityVersion(), IndexVersions.MINIMUM_COMPATIBLE, + IndexVersions.MINIMUM_READONLY_COMPATIBLE, IndexVersion.current() ); if (proxyAddress == null || proxyAddress.isEmpty()) { diff --git a/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteResponseTests.java b/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteResponseTests.java index b59cc13a20ff2..69cff0fc45ac3 100644 --- a/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteResponseTests.java +++ b/server/src/test/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteResponseTests.java @@ -127,6 +127,7 @@ public void testToXContentWithDeprecatedClusterState() { ], "version": "%s", "min_index_version": %s, + "min_read_only_index_version": %s, "max_index_version": %s } }, @@ -218,6 +219,7 @@ public void testToXContentWithDeprecatedClusterState() { clusterState.getNodes().get("node0").getEphemeralId(), Version.CURRENT, IndexVersions.MINIMUM_COMPATIBLE, + IndexVersions.MINIMUM_READONLY_COMPATIBLE, IndexVersion.current(), IndexVersion.current(), IndexVersion.current() diff --git a/server/src/test/java/org/elasticsearch/cluster/ClusterStateTests.java b/server/src/test/java/org/elasticsearch/cluster/ClusterStateTests.java index 668aea70c23f2..5f4426b02ce1a 100644 --- a/server/src/test/java/org/elasticsearch/cluster/ClusterStateTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/ClusterStateTests.java @@ -213,6 +213,7 @@ public void testToXContent() throws IOException { ], "version": "%s", "min_index_version":%s, + "min_read_only_index_version":%s, "max_index_version":%s } }, @@ -389,6 +390,7 @@ public void testToXContent() throws IOException { ephemeralId, Version.CURRENT, IndexVersions.MINIMUM_COMPATIBLE, + IndexVersions.MINIMUM_READONLY_COMPATIBLE, IndexVersion.current(), TransportVersion.current(), IndexVersion.current(), @@ -488,6 +490,7 @@ public void testToXContent_FlatSettingTrue_ReduceMappingFalse() throws IOExcepti ], "version" : "%s", "min_index_version" : %s, + "min_read_only_index_version" : %s, "max_index_version" : %s } }, @@ -663,6 +666,7 @@ public void testToXContent_FlatSettingTrue_ReduceMappingFalse() throws IOExcepti ephemeralId, Version.CURRENT, IndexVersions.MINIMUM_COMPATIBLE, + IndexVersions.MINIMUM_READONLY_COMPATIBLE, IndexVersion.current(), TransportVersion.current(), IndexVersion.current(), @@ -762,6 +766,7 @@ public void testToXContent_FlatSettingFalse_ReduceMappingTrue() throws IOExcepti ], "version" : "%s", "min_index_version" : %s, + "min_read_only_index_version" : %s, "max_index_version" : %s } }, @@ -943,6 +948,7 @@ public void testToXContent_FlatSettingFalse_ReduceMappingTrue() throws IOExcepti ephemeralId, Version.CURRENT, IndexVersions.MINIMUM_COMPATIBLE, + IndexVersions.MINIMUM_READONLY_COMPATIBLE, IndexVersion.current(), TransportVersion.current(), IndexVersion.current(), diff --git a/server/src/test/java/org/elasticsearch/cluster/node/DiscoveryNodeTests.java b/server/src/test/java/org/elasticsearch/cluster/node/DiscoveryNodeTests.java index 331b5d92ca94e..fa7633f0eaf75 100644 --- a/server/src/test/java/org/elasticsearch/cluster/node/DiscoveryNodeTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/node/DiscoveryNodeTests.java @@ -31,6 +31,8 @@ import static java.util.Collections.emptySet; import static org.elasticsearch.test.NodeRoles.nonRemoteClusterClientNode; import static org.elasticsearch.test.NodeRoles.remoteClusterClientNode; +import static org.elasticsearch.test.TransportVersionUtils.getPreviousVersion; +import static org.elasticsearch.test.TransportVersionUtils.randomVersionBetween; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; @@ -221,6 +223,7 @@ public void testDiscoveryNodeToXContent() { ], "version" : "%s", "min_index_version" : %s, + "min_read_only_index_version" : %s, "max_index_version" : %s } }""", @@ -228,6 +231,7 @@ public void testDiscoveryNodeToXContent() { withExternalId ? "test-external-id" : "test-name", Version.CURRENT, IndexVersions.MINIMUM_COMPATIBLE, + IndexVersions.MINIMUM_READONLY_COMPATIBLE, IndexVersion.current() ) ) @@ -250,4 +254,61 @@ public void testDiscoveryNodeToString() { assertThat(toString, containsString("{" + node.getBuildVersion() + "}")); assertThat(toString, containsString("{test-attr=val}"));// attributes } + + public void testDiscoveryNodeMinReadOnlyVersionSerialization() throws Exception { + var node = DiscoveryNodeUtils.create("_id", buildNewFakeTransportAddress(), VersionInformation.CURRENT); + + { + try (var out = new BytesStreamOutput()) { + out.setTransportVersion(TransportVersion.current()); + node.writeTo(out); + + try (var in = StreamInput.wrap(out.bytes().array())) { + in.setTransportVersion(TransportVersion.current()); + + var deserialized = new DiscoveryNode(in); + assertThat(deserialized.getId(), equalTo(node.getId())); + assertThat(deserialized.getAddress(), equalTo(node.getAddress())); + assertThat(deserialized.getMinIndexVersion(), equalTo(node.getMinIndexVersion())); + assertThat(deserialized.getMaxIndexVersion(), equalTo(node.getMaxIndexVersion())); + assertThat(deserialized.getMinReadOnlyIndexVersion(), equalTo(node.getMinReadOnlyIndexVersion())); + assertThat(deserialized.getVersionInformation(), equalTo(node.getVersionInformation())); + } + } + } + + { + var oldVersion = randomVersionBetween( + random(), + TransportVersions.MINIMUM_COMPATIBLE, + getPreviousVersion(TransportVersions.NODE_VERSION_INFORMATION_WITH_MIN_READ_ONLY_INDEX_VERSION) + ); + try (var out = new BytesStreamOutput()) { + out.setTransportVersion(oldVersion); + node.writeTo(out); + + try (var in = StreamInput.wrap(out.bytes().array())) { + in.setTransportVersion(oldVersion); + + var deserialized = new DiscoveryNode(in); + assertThat(deserialized.getId(), equalTo(node.getId())); + assertThat(deserialized.getAddress(), equalTo(node.getAddress())); + assertThat(deserialized.getMinIndexVersion(), equalTo(node.getMinIndexVersion())); + assertThat(deserialized.getMaxIndexVersion(), equalTo(node.getMaxIndexVersion())); + assertThat(deserialized.getMinReadOnlyIndexVersion(), equalTo(node.getMinIndexVersion())); + assertThat( + deserialized.getVersionInformation(), + equalTo( + new VersionInformation( + node.getBuildVersion(), + node.getMinIndexVersion(), + node.getMinIndexVersion(), + node.getMaxIndexVersion() + ) + ) + ); + } + } + } + } } diff --git a/test/framework/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodeUtils.java b/test/framework/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodeUtils.java index 64f8fa88762b8..20368753eac1d 100644 --- a/test/framework/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodeUtils.java +++ b/test/framework/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodeUtils.java @@ -76,6 +76,7 @@ public static class Builder { private BuildVersion buildVersion; private Version version; private IndexVersion minIndexVersion; + private IndexVersion minReadOnlyIndexVersion; private IndexVersion maxIndexVersion; private String externalId; @@ -125,16 +126,23 @@ public Builder version(Version version, IndexVersion minIndexVersion, IndexVersi this.buildVersion = BuildVersion.fromVersionId(version.id()); this.version = version; this.minIndexVersion = minIndexVersion; + this.minReadOnlyIndexVersion = minIndexVersion; this.maxIndexVersion = maxIndexVersion; return this; } - public Builder version(BuildVersion version, IndexVersion minIndexVersion, IndexVersion maxIndexVersion) { + public Builder version( + BuildVersion version, + IndexVersion minIndexVersion, + IndexVersion minReadOnlyIndexVersion, + IndexVersion maxIndexVersion + ) { // see comment in VersionInformation assert version.equals(BuildVersion.current()); this.buildVersion = version; this.version = Version.CURRENT; this.minIndexVersion = minIndexVersion; + this.minReadOnlyIndexVersion = minReadOnlyIndexVersion; this.maxIndexVersion = maxIndexVersion; return this; } @@ -143,6 +151,7 @@ public Builder version(VersionInformation versions) { this.buildVersion = versions.buildVersion(); this.version = versions.nodeVersion(); this.minIndexVersion = versions.minIndexVersion(); + this.minReadOnlyIndexVersion = versions.minReadOnlyIndexVersion(); this.maxIndexVersion = versions.maxIndexVersion(); return this; } @@ -170,10 +179,10 @@ public DiscoveryNode build() { } VersionInformation versionInfo; - if (minIndexVersion == null || maxIndexVersion == null) { + if (minIndexVersion == null || minReadOnlyIndexVersion == null || maxIndexVersion == null) { versionInfo = VersionInformation.inferVersions(version); } else { - versionInfo = new VersionInformation(buildVersion, version, minIndexVersion, maxIndexVersion); + versionInfo = new VersionInformation(buildVersion, version, minIndexVersion, minReadOnlyIndexVersion, maxIndexVersion); } return new DiscoveryNode(name, id, ephemeralId, hostName, hostAddress, address, attributes, roles, versionInfo, externalId); diff --git a/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsMonitoringDocTests.java b/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsMonitoringDocTests.java index f4d50df4ff613..35da4abec223a 100644 --- a/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsMonitoringDocTests.java +++ b/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/collector/cluster/ClusterStatsMonitoringDocTests.java @@ -462,6 +462,7 @@ public void testToXContent() throws IOException { pluginEsBuildVersion, Version.CURRENT, IndexVersions.MINIMUM_COMPATIBLE, + IndexVersions.MINIMUM_READONLY_COMPATIBLE, IndexVersion.current(), apmIndicesExist }; final String expectedJson = """ @@ -817,6 +818,7 @@ public void testToXContent() throws IOException { ], "version": "%s", "min_index_version":%s, + "min_read_only_index_version":%s, "max_index_version":%s } }, From a5c57ba966cfd088b8d79fd51fe3fb35163b22a2 Mon Sep 17 00:00:00 2001 From: Benjamin Trent Date: Tue, 17 Dec 2024 13:30:48 -0500 Subject: [PATCH 09/60] Adjust random_score default field to _seq_no field (#118671) In an effort to improve performance and continue to provide unique seeded scores for documents in the same index, we are switching from _id to _seq_no. Requiring a field that is "unique" for a field and to help with random scores is burdensome for the user. So, we should default to a unique field (per index) when the user provides a seed. Using `_seq_no` should be better as: - We don't have to grab stored fields values - Bytes used are generally smaller Additionally this removes the deprecation warning. Marking as "breaking" as it does change the scores & behavior, but the API provide is the same. --- .../src/main/resources/changelog-schema.json | 1 + docs/changelog/118671.yaml | 11 +++++++++++ .../RandomScoreFunctionBuilder.java | 17 ++--------------- .../ScoreFunctionBuilderTests.java | 1 - 4 files changed, 14 insertions(+), 16 deletions(-) create mode 100644 docs/changelog/118671.yaml diff --git a/build-tools-internal/src/main/resources/changelog-schema.json b/build-tools-internal/src/main/resources/changelog-schema.json index 451701d74d690..7d35951eaa2cf 100644 --- a/build-tools-internal/src/main/resources/changelog-schema.json +++ b/build-tools-internal/src/main/resources/changelog-schema.json @@ -295,6 +295,7 @@ "Painless", "REST API", "Rollup", + "Search", "System requirement", "Transform" ] diff --git a/docs/changelog/118671.yaml b/docs/changelog/118671.yaml new file mode 100644 index 0000000000000..3931cc4179037 --- /dev/null +++ b/docs/changelog/118671.yaml @@ -0,0 +1,11 @@ +pr: 118671 +summary: Adjust `random_score` default field to `_seq_no` field +area: Search +type: breaking +issues: [] +breaking: + title: Adjust `random_score` default field to `_seq_no` field + area: Search + details: When providing a 'seed' parameter to a 'random_score' function in the 'function_score' query but NOT providing a 'field', the default 'field' is switched from '_id' to '_seq_no'. + impact: The random scoring and ordering may change when providing a 'seed' and not providing a 'field' to a 'random_score' function. + notable: false diff --git a/server/src/main/java/org/elasticsearch/index/query/functionscore/RandomScoreFunctionBuilder.java b/server/src/main/java/org/elasticsearch/index/query/functionscore/RandomScoreFunctionBuilder.java index 6d4b2dd4ab1f5..88f1ab1ba5c2e 100644 --- a/server/src/main/java/org/elasticsearch/index/query/functionscore/RandomScoreFunctionBuilder.java +++ b/server/src/main/java/org/elasticsearch/index/query/functionscore/RandomScoreFunctionBuilder.java @@ -13,12 +13,10 @@ import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.logging.DeprecationCategory; -import org.elasticsearch.common.logging.DeprecationLogger; import org.elasticsearch.common.lucene.search.function.RandomScoreFunction; import org.elasticsearch.common.lucene.search.function.ScoreFunction; -import org.elasticsearch.index.mapper.IdFieldMapper; import org.elasticsearch.index.mapper.MappedFieldType; +import org.elasticsearch.index.mapper.SeqNoFieldMapper; import org.elasticsearch.index.query.SearchExecutionContext; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentParser; @@ -30,7 +28,6 @@ * A function that computes a random score for the matched documents */ public class RandomScoreFunctionBuilder extends ScoreFunctionBuilder { - private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(RandomScoreFunctionBuilder.class); public static final String NAME = "random_score"; private String field; @@ -140,17 +137,7 @@ protected ScoreFunction doToFunction(SearchExecutionContext context) { // DocID-based random score generation return new RandomScoreFunction(hash(context.nowInMillis()), salt, null); } else { - String fieldName; - if (field == null) { - deprecationLogger.warn( - DeprecationCategory.QUERIES, - "seed_requires_field", - "As of version 7.0 Elasticsearch will require that a [field] parameter is provided when a [seed] is set" - ); - fieldName = IdFieldMapper.NAME; - } else { - fieldName = field; - } + final String fieldName = Objects.requireNonNullElse(field, SeqNoFieldMapper.NAME); if (context.isFieldMapped(fieldName) == false) { if (context.hasMappings() == false) { // no mappings: the index is empty anyway diff --git a/server/src/test/java/org/elasticsearch/index/query/functionscore/ScoreFunctionBuilderTests.java b/server/src/test/java/org/elasticsearch/index/query/functionscore/ScoreFunctionBuilderTests.java index 8d060d94e4c21..b58ac513a6449 100644 --- a/server/src/test/java/org/elasticsearch/index/query/functionscore/ScoreFunctionBuilderTests.java +++ b/server/src/test/java/org/elasticsearch/index/query/functionscore/ScoreFunctionBuilderTests.java @@ -66,7 +66,6 @@ public void testRandomScoreFunctionWithSeedNoField() throws Exception { Mockito.when(context.getFieldType(IdFieldMapper.NAME)).thenReturn(new KeywordFieldMapper.KeywordFieldType(IdFieldMapper.NAME)); Mockito.when(context.isFieldMapped(IdFieldMapper.NAME)).thenReturn(true); builder.toFunction(context); - assertWarnings("As of version 7.0 Elasticsearch will require that a [field] parameter is provided when a [seed] is set"); } public void testRandomScoreFunctionWithSeed() throws Exception { From bac70647260ba0396a904b918a3dd3576c757a0d Mon Sep 17 00:00:00 2001 From: Brian Seeders Date: Tue, 17 Dec 2024 13:34:26 -0500 Subject: [PATCH 10/60] Bump versions after 8.16.2 release --- .buildkite/pipelines/intake.yml | 2 +- .buildkite/pipelines/periodic-packaging.yml | 6 +++--- .buildkite/pipelines/periodic.yml | 10 +++++----- .ci/bwcVersions | 2 +- .ci/snapshotBwcVersions | 2 +- server/src/main/java/org/elasticsearch/Version.java | 1 + .../resources/org/elasticsearch/TransportVersions.csv | 1 + .../org/elasticsearch/index/IndexVersions.csv | 1 + 8 files changed, 14 insertions(+), 11 deletions(-) diff --git a/.buildkite/pipelines/intake.yml b/.buildkite/pipelines/intake.yml index 6e15d64154960..9efb9c8b498aa 100644 --- a/.buildkite/pipelines/intake.yml +++ b/.buildkite/pipelines/intake.yml @@ -56,7 +56,7 @@ steps: timeout_in_minutes: 300 matrix: setup: - BWC_VERSION: ["8.16.2", "8.17.1", "8.18.0", "9.0.0"] + BWC_VERSION: ["8.16.3", "8.17.1", "8.18.0", "9.0.0"] agents: provider: gcp image: family/elasticsearch-ubuntu-2004 diff --git a/.buildkite/pipelines/periodic-packaging.yml b/.buildkite/pipelines/periodic-packaging.yml index abd11068e7a65..b1e5a7bf933c9 100644 --- a/.buildkite/pipelines/periodic-packaging.yml +++ b/.buildkite/pipelines/periodic-packaging.yml @@ -287,8 +287,8 @@ steps: env: BWC_VERSION: 8.15.5 - - label: "{{matrix.image}} / 8.16.2 / packaging-tests-upgrade" - command: ./.ci/scripts/packaging-test.sh -Dbwc.checkout.align=true destructiveDistroUpgradeTest.v8.16.2 + - label: "{{matrix.image}} / 8.16.3 / packaging-tests-upgrade" + command: ./.ci/scripts/packaging-test.sh -Dbwc.checkout.align=true destructiveDistroUpgradeTest.v8.16.3 timeout_in_minutes: 300 matrix: setup: @@ -301,7 +301,7 @@ steps: machineType: custom-16-32768 buildDirectory: /dev/shm/bk env: - BWC_VERSION: 8.16.2 + BWC_VERSION: 8.16.3 - label: "{{matrix.image}} / 8.17.1 / packaging-tests-upgrade" command: ./.ci/scripts/packaging-test.sh -Dbwc.checkout.align=true destructiveDistroUpgradeTest.v8.17.1 diff --git a/.buildkite/pipelines/periodic.yml b/.buildkite/pipelines/periodic.yml index f2d169cd2b30d..4c593bae62d7a 100644 --- a/.buildkite/pipelines/periodic.yml +++ b/.buildkite/pipelines/periodic.yml @@ -306,8 +306,8 @@ steps: - signal_reason: agent_stop limit: 3 - - label: 8.16.2 / bwc - command: .ci/scripts/run-gradle.sh -Dbwc.checkout.align=true v8.16.2#bwcTest + - label: 8.16.3 / bwc + command: .ci/scripts/run-gradle.sh -Dbwc.checkout.align=true v8.16.3#bwcTest timeout_in_minutes: 300 agents: provider: gcp @@ -316,7 +316,7 @@ steps: buildDirectory: /dev/shm/bk preemptible: true env: - BWC_VERSION: 8.16.2 + BWC_VERSION: 8.16.3 retry: automatic: - exit_status: "-1" @@ -448,7 +448,7 @@ steps: setup: ES_RUNTIME_JAVA: - openjdk21 - BWC_VERSION: ["8.16.2", "8.17.1", "8.18.0", "9.0.0"] + BWC_VERSION: ["8.16.3", "8.17.1", "8.18.0", "9.0.0"] agents: provider: gcp image: family/elasticsearch-ubuntu-2004 @@ -490,7 +490,7 @@ steps: ES_RUNTIME_JAVA: - openjdk21 - openjdk23 - BWC_VERSION: ["8.16.2", "8.17.1", "8.18.0", "9.0.0"] + BWC_VERSION: ["8.16.3", "8.17.1", "8.18.0", "9.0.0"] agents: provider: gcp image: family/elasticsearch-ubuntu-2004 diff --git a/.ci/bwcVersions b/.ci/bwcVersions index 3cb983373138f..cf12ee8c15419 100644 --- a/.ci/bwcVersions +++ b/.ci/bwcVersions @@ -15,7 +15,7 @@ BWC_VERSION: - "8.13.4" - "8.14.3" - "8.15.5" - - "8.16.2" + - "8.16.3" - "8.17.1" - "8.18.0" - "9.0.0" diff --git a/.ci/snapshotBwcVersions b/.ci/snapshotBwcVersions index e05c0774c9819..68c6ad5601546 100644 --- a/.ci/snapshotBwcVersions +++ b/.ci/snapshotBwcVersions @@ -1,5 +1,5 @@ BWC_VERSION: - - "8.16.2" + - "8.16.3" - "8.17.1" - "8.18.0" - "9.0.0" diff --git a/server/src/main/java/org/elasticsearch/Version.java b/server/src/main/java/org/elasticsearch/Version.java index 47c43eadcfb03..8873c9b0e281e 100644 --- a/server/src/main/java/org/elasticsearch/Version.java +++ b/server/src/main/java/org/elasticsearch/Version.java @@ -191,6 +191,7 @@ public class Version implements VersionId, ToXContentFragment { public static final Version V_8_16_0 = new Version(8_16_00_99); public static final Version V_8_16_1 = new Version(8_16_01_99); public static final Version V_8_16_2 = new Version(8_16_02_99); + public static final Version V_8_16_3 = new Version(8_16_03_99); public static final Version V_8_17_0 = new Version(8_17_00_99); public static final Version V_8_17_1 = new Version(8_17_01_99); public static final Version V_8_18_0 = new Version(8_18_00_99); diff --git a/server/src/main/resources/org/elasticsearch/TransportVersions.csv b/server/src/main/resources/org/elasticsearch/TransportVersions.csv index 08db0822dfef5..2016f59b58a3e 100644 --- a/server/src/main/resources/org/elasticsearch/TransportVersions.csv +++ b/server/src/main/resources/org/elasticsearch/TransportVersions.csv @@ -135,4 +135,5 @@ 8.15.5,8702003 8.16.0,8772001 8.16.1,8772004 +8.16.2,8772004 8.17.0,8797002 diff --git a/server/src/main/resources/org/elasticsearch/index/IndexVersions.csv b/server/src/main/resources/org/elasticsearch/index/IndexVersions.csv index afe696f31d323..3bfeeded6494c 100644 --- a/server/src/main/resources/org/elasticsearch/index/IndexVersions.csv +++ b/server/src/main/resources/org/elasticsearch/index/IndexVersions.csv @@ -135,4 +135,5 @@ 8.15.5,8512000 8.16.0,8518000 8.16.1,8518000 +8.16.2,8518000 8.17.0,8521000 From 5cb2d280201020c4246afa428095ae2e24c20be2 Mon Sep 17 00:00:00 2001 From: Brian Seeders Date: Tue, 17 Dec 2024 13:35:51 -0500 Subject: [PATCH 11/60] Prune changelogs after 8.16.2 release --- docs/changelog/116358.yaml | 5 ----- docs/changelog/117153.yaml | 5 ----- docs/changelog/118380.yaml | 5 ----- 3 files changed, 15 deletions(-) delete mode 100644 docs/changelog/116358.yaml delete mode 100644 docs/changelog/117153.yaml delete mode 100644 docs/changelog/118380.yaml diff --git a/docs/changelog/116358.yaml b/docs/changelog/116358.yaml deleted file mode 100644 index 58b44a1e9bcf5..0000000000000 --- a/docs/changelog/116358.yaml +++ /dev/null @@ -1,5 +0,0 @@ -pr: 116358 -summary: Update Deberta tokenizer -area: Machine Learning -type: bug -issues: [] diff --git a/docs/changelog/117153.yaml b/docs/changelog/117153.yaml deleted file mode 100644 index f7640c0a7ed6a..0000000000000 --- a/docs/changelog/117153.yaml +++ /dev/null @@ -1,5 +0,0 @@ -pr: 117153 -summary: "ESQL: fix the column position in errors" -area: ES|QL -type: bug -issues: [] diff --git a/docs/changelog/118380.yaml b/docs/changelog/118380.yaml deleted file mode 100644 index 8b26c871fb172..0000000000000 --- a/docs/changelog/118380.yaml +++ /dev/null @@ -1,5 +0,0 @@ -pr: 118380 -summary: Restore original "is within leaf" value in `SparseVectorFieldMapper` -area: Mapping -type: bug -issues: [] From bde485a84520539f98d3f08913af4b8b73434e6b Mon Sep 17 00:00:00 2001 From: Valeriy Khakhutskyy <1292899+valeriy42@users.noreply.github.com> Date: Tue, 17 Dec 2024 20:23:00 +0100 Subject: [PATCH 12/60] [ML] Add dynamic templates for anomalies results index (#118845) This PR enables the resolution of field names containing "." after the rollover of the anomalies results index. This way, the object parts of the field name, e.g., for an influencer, will indeed have the object type and can be resolved in search and filter operations. --- .../ml/anomalydetection/results_index_mappings.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/x-pack/plugin/core/template-resources/src/main/resources/ml/anomalydetection/results_index_mappings.json b/x-pack/plugin/core/template-resources/src/main/resources/ml/anomalydetection/results_index_mappings.json index 4415afe50a998..e0bde4715839e 100644 --- a/x-pack/plugin/core/template-resources/src/main/resources/ml/anomalydetection/results_index_mappings.json +++ b/x-pack/plugin/core/template-resources/src/main/resources/ml/anomalydetection/results_index_mappings.json @@ -5,7 +5,15 @@ }, "dynamic_templates" : [ { - "strings_as_keywords" : { + "map_objects": { + "match_mapping_type": "object", + "mapping": { + "type": "object" + } + } + }, + { + "non_objects_as_keywords" : { "match" : "*", "mapping" : { "type" : "keyword" From 4b90f01b49b820242608d54fae6b624fe950847d Mon Sep 17 00:00:00 2001 From: Mark Tozzi Date: Tue, 17 Dec 2024 14:36:02 -0500 Subject: [PATCH 13/60] Esql - fix some test failures due to results ordering (#118692) fix some failing multi-shard tests. The backport for the PR that added these tests hasn't landed yet, so I'm going to just cherry pick this into there rather than do two back ports with conflict resolution. --- .../src/main/resources/date_nanos.csv-spec | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date_nanos.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date_nanos.csv-spec index f4b5c98d596ae..47191148e0205 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date_nanos.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date_nanos.csv-spec @@ -555,7 +555,8 @@ required_capability: date_nanos_bucket FROM date_nanos | WHERE millis > "2020-01-01" -| STATS ct = count(*) BY yr = BUCKET(nanos, 1 year); +| STATS ct = count(*) BY yr = BUCKET(nanos, 1 year) +| SORT yr DESC; ct:long | yr:date_nanos 8 | 2023-01-01T00:00:00.000000000Z @@ -567,7 +568,8 @@ required_capability: date_nanos_bucket FROM date_nanos | WHERE millis > "2020-01-01" -| STATS ct = count(*) BY yr = BUCKET(nanos, 5, "1999-01-01", NOW()); +| STATS ct = count(*) BY yr = BUCKET(nanos, 5, "1999-01-01", NOW()) +| SORT yr DESC; ct:long | yr:date_nanos 8 | 2023-01-01T00:00:00.000000000Z @@ -579,7 +581,8 @@ required_capability: date_nanos_bucket FROM date_nanos | WHERE millis > "2020-01-01" -| STATS ct = count(*) BY mo = BUCKET(nanos, 1 month); +| STATS ct = count(*) BY mo = BUCKET(nanos, 1 month) +| SORT mo DESC; ct:long | mo:date_nanos 8 | 2023-10-01T00:00:00.000000000Z @@ -591,7 +594,8 @@ required_capability: date_nanos_bucket FROM date_nanos | WHERE millis > "2020-01-01" -| STATS ct = count(*) BY mo = BUCKET(nanos, 20, "2023-01-01", "2023-12-31"); +| STATS ct = count(*) BY mo = BUCKET(nanos, 20, "2023-01-01", "2023-12-31") +| SORT mo DESC; ct:long | mo:date_nanos 8 | 2023-10-01T00:00:00.000000000Z @@ -603,18 +607,21 @@ required_capability: date_nanos_bucket FROM date_nanos | WHERE millis > "2020-01-01" -| STATS ct = count(*) BY mo = BUCKET(nanos, 55, "2023-01-01", "2023-12-31"); +| STATS ct = count(*) BY mo = BUCKET(nanos, 55, "2023-01-01", "2023-12-31") +| SORT mo DESC; ct:long | mo:date_nanos 8 | 2023-10-23T00:00:00.000000000Z ; + Bucket Date nanos by 10 minutes required_capability: date_trunc_date_nanos required_capability: date_nanos_bucket FROM date_nanos | WHERE millis > "2020-01-01" -| STATS ct = count(*) BY mn = BUCKET(nanos, 10 minutes); +| STATS ct = count(*) BY mn = BUCKET(nanos, 10 minutes) +| SORT mn DESC; ct:long | mn:date_nanos 4 | 2023-10-23T13:50:00.000000000Z From 517abe4ffdceb3c7ca771207fe20b0c813181810 Mon Sep 17 00:00:00 2001 From: Dianna Hohensee Date: Tue, 17 Dec 2024 14:51:45 -0500 Subject: [PATCH 14/60] ConnectTransportException returns retryable BAD_GATEWAY (#118681) ConnectTransportException and its subclasses previous translated to a INTERNAL_SERVER_ERROR HTTP 500 code. We are changing it to 502 BAD_GATEWAY so that users may choose to retry it on connectivity issues. Related ES-10214 Closes #118320 --- docs/changelog/118681.yaml | 6 ++++++ .../transport/ConnectTransportException.java | 13 +++++++++++++ .../elasticsearch/ExceptionSerializationTests.java | 1 + 3 files changed, 20 insertions(+) create mode 100644 docs/changelog/118681.yaml diff --git a/docs/changelog/118681.yaml b/docs/changelog/118681.yaml new file mode 100644 index 0000000000000..a186c05e6cd7d --- /dev/null +++ b/docs/changelog/118681.yaml @@ -0,0 +1,6 @@ +pr: 118681 +summary: '`ConnectTransportException` returns retryable BAD_GATEWAY' +area: Network +type: enhancement +issues: + - 118320 diff --git a/server/src/main/java/org/elasticsearch/transport/ConnectTransportException.java b/server/src/main/java/org/elasticsearch/transport/ConnectTransportException.java index 648d27c885843..302175cc4f5a0 100644 --- a/server/src/main/java/org/elasticsearch/transport/ConnectTransportException.java +++ b/server/src/main/java/org/elasticsearch/transport/ConnectTransportException.java @@ -13,6 +13,7 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.rest.RestStatus; import java.io.IOException; @@ -41,6 +42,18 @@ public ConnectTransportException(StreamInput in) throws IOException { } } + /** + * The ES REST API is a gateway to a single or multiple clusters. If there is an error connecting to other servers, then we should + * return a 502 BAD_GATEWAY status code instead of the parent class' 500 INTERNAL_SERVER_ERROR. Clients tend to retry on a 502 but not + * on a 500, and retrying may help on a connection error. + * + * @return a {@link RestStatus#BAD_GATEWAY} code + */ + @Override + public final RestStatus status() { + return RestStatus.BAD_GATEWAY; + } + @Override protected void writeTo(StreamOutput out, Writer nestedExceptionsWriter) throws IOException { super.writeTo(out, nestedExceptionsWriter); diff --git a/server/src/test/java/org/elasticsearch/ExceptionSerializationTests.java b/server/src/test/java/org/elasticsearch/ExceptionSerializationTests.java index 2abe4157583cd..31f54f9a16359 100644 --- a/server/src/test/java/org/elasticsearch/ExceptionSerializationTests.java +++ b/server/src/test/java/org/elasticsearch/ExceptionSerializationTests.java @@ -409,6 +409,7 @@ public void testConnectTransportException() throws IOException { ex = serialize(new ConnectTransportException(node, "msg", "action", new NullPointerException())); assertEquals("[][" + transportAddress + "][action] msg", ex.getMessage()); assertThat(ex.getCause(), instanceOf(NullPointerException.class)); + assertEquals(RestStatus.BAD_GATEWAY, ex.status()); } public void testSearchPhaseExecutionException() throws IOException { From ae3c0d703257996ac4b07dfdc4543eb625ee9a60 Mon Sep 17 00:00:00 2001 From: Mark Tozzi Date: Tue, 17 Dec 2024 14:54:19 -0500 Subject: [PATCH 15/60] Esql implicit casting for date nanos (#118697) resolves #118476 This adds an implicit cast from string to date nanos, much the same as we do for millisecond dates. In the course of working on this, I found and fixed a couple of tests that were creating pre-epoch date nanos, which are not supported in elasticsearch. I also refactored the conversion code to use the standard DateUtils functions where appropriate, which caught some of the above errors in test data. --- docs/changelog/118697.yaml | 6 + .../src/main/resources/date_nanos.csv-spec | 131 ++++++++++++++++++ .../xpack/esql/action/EsqlCapabilities.java | 5 +- .../xpack/esql/analysis/Analyzer.java | 31 +++-- .../esql/type/EsqlDataTypeConverter.java | 14 +- .../esql/action/EsqlQueryResponseTests.java | 2 +- .../esql/type/EsqlDataTypeConverterTests.java | 12 +- 7 files changed, 179 insertions(+), 22 deletions(-) create mode 100644 docs/changelog/118697.yaml diff --git a/docs/changelog/118697.yaml b/docs/changelog/118697.yaml new file mode 100644 index 0000000000000..6e24e6ae4b47f --- /dev/null +++ b/docs/changelog/118697.yaml @@ -0,0 +1,6 @@ +pr: 118697 +summary: Esql implicit casting for date nanos +area: ES|QL +type: enhancement +issues: + - 118476 diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date_nanos.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date_nanos.csv-spec index 47191148e0205..4206d6b48699f 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date_nanos.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/date_nanos.csv-spec @@ -216,6 +216,137 @@ millis:date | nanos:date_nanos | num:long 2023-10-23T13:33:34.937Z | 2023-10-23T13:33:34.937193000Z | 1698068014937193000 ; +implicit casting to nanos, date only +required_capability: date_nanos_type +required_capability: date_nanos_implicit_casting + +FROM date_nanos +| WHERE MV_MIN(nanos) > "2023-10-23" +| SORT nanos DESC +| KEEP millis, nanos; + +millis:date | nanos:date_nanos +2023-10-23T13:55:01.543Z | 2023-10-23T13:55:01.543123456Z +2023-10-23T13:53:55.832Z | 2023-10-23T13:53:55.832987654Z +2023-10-23T13:52:55.015Z | 2023-10-23T13:52:55.015787878Z +2023-10-23T13:51:54.732Z | 2023-10-23T13:51:54.732102837Z +2023-10-23T13:33:34.937Z | 2023-10-23T13:33:34.937193000Z +2023-10-23T12:27:28.948Z | 2023-10-23T12:27:28.948000000Z +2023-10-23T12:15:03.360Z | 2023-10-23T12:15:03.360103847Z +2023-10-23T12:15:03.360Z | 2023-10-23T12:15:03.360103847Z +; + +implicit casting to nanos, date only, equality test +required_capability: date_nanos_type +required_capability: date_nanos_implicit_casting + +FROM date_nanos +| WHERE MV_MIN(nanos) == "2023-10-23" +| SORT nanos DESC +| KEEP millis, nanos; + +millis:date | nanos:date_nanos +; + + +implicit casting to nanos, date plus time to seconds +required_capability: date_nanos_type +required_capability: date_nanos_implicit_casting + +FROM date_nanos +| WHERE MV_MIN(nanos) > "2023-10-23T00:00:00" +| SORT nanos DESC +| KEEP millis, nanos; + +millis:date | nanos:date_nanos +2023-10-23T13:55:01.543Z | 2023-10-23T13:55:01.543123456Z +2023-10-23T13:53:55.832Z | 2023-10-23T13:53:55.832987654Z +2023-10-23T13:52:55.015Z | 2023-10-23T13:52:55.015787878Z +2023-10-23T13:51:54.732Z | 2023-10-23T13:51:54.732102837Z +2023-10-23T13:33:34.937Z | 2023-10-23T13:33:34.937193000Z +2023-10-23T12:27:28.948Z | 2023-10-23T12:27:28.948000000Z +2023-10-23T12:15:03.360Z | 2023-10-23T12:15:03.360103847Z +2023-10-23T12:15:03.360Z | 2023-10-23T12:15:03.360103847Z +; + +implicit casting to nanos, date plus time to seconds, equality test +required_capability: date_nanos_type +required_capability: date_nanos_implicit_casting + +FROM date_nanos +| WHERE MV_MIN(nanos) == "2023-10-23T12:27:28" +| SORT nanos DESC +| KEEP millis, nanos; + +millis:date | nanos:date_nanos +; + +implicit casting to nanos, date plus time to millis +required_capability: date_nanos_type +required_capability: date_nanos_implicit_casting + +FROM date_nanos +| WHERE MV_MIN(nanos) > "2023-10-23T00:00:00.000" +| SORT nanos DESC +| KEEP millis, nanos; + +millis:date | nanos:date_nanos +2023-10-23T13:55:01.543Z | 2023-10-23T13:55:01.543123456Z +2023-10-23T13:53:55.832Z | 2023-10-23T13:53:55.832987654Z +2023-10-23T13:52:55.015Z | 2023-10-23T13:52:55.015787878Z +2023-10-23T13:51:54.732Z | 2023-10-23T13:51:54.732102837Z +2023-10-23T13:33:34.937Z | 2023-10-23T13:33:34.937193000Z +2023-10-23T12:27:28.948Z | 2023-10-23T12:27:28.948000000Z +2023-10-23T12:15:03.360Z | 2023-10-23T12:15:03.360103847Z +2023-10-23T12:15:03.360Z | 2023-10-23T12:15:03.360103847Z +; + +implicit casting to nanos, date plus time to millis, equality test +required_capability: date_nanos_type +required_capability: date_nanos_implicit_casting + +FROM date_nanos +| WHERE MV_MIN(nanos) == "2023-10-23T12:27:28.948" +| SORT nanos DESC +| KEEP millis, nanos; + +millis:date | nanos:date_nanos +2023-10-23T12:27:28.948Z | 2023-10-23T12:27:28.948000000Z +; + +implicit casting to nanos, date plus time to nanos +required_capability: date_nanos_type +required_capability: date_nanos_implicit_casting + +FROM date_nanos +| WHERE MV_MIN(nanos) > "2023-10-23T00:00:00.000000000" +| SORT nanos DESC +| KEEP millis, nanos; + +millis:date | nanos:date_nanos +2023-10-23T13:55:01.543Z | 2023-10-23T13:55:01.543123456Z +2023-10-23T13:53:55.832Z | 2023-10-23T13:53:55.832987654Z +2023-10-23T13:52:55.015Z | 2023-10-23T13:52:55.015787878Z +2023-10-23T13:51:54.732Z | 2023-10-23T13:51:54.732102837Z +2023-10-23T13:33:34.937Z | 2023-10-23T13:33:34.937193000Z +2023-10-23T12:27:28.948Z | 2023-10-23T12:27:28.948000000Z +2023-10-23T12:15:03.360Z | 2023-10-23T12:15:03.360103847Z +2023-10-23T12:15:03.360Z | 2023-10-23T12:15:03.360103847Z +; + +implicit casting to nanos, date plus time to nanos, equality test +required_capability: date_nanos_type +required_capability: date_nanos_implicit_casting + +FROM date_nanos +| WHERE MV_MIN(nanos) == "2023-10-23T12:27:28.948000000" +| SORT nanos DESC +| KEEP millis, nanos; + +millis:date | nanos:date_nanos +2023-10-23T12:27:28.948Z | 2023-10-23T12:27:28.948000000Z +; + date nanos greater than millis required_capability: date_nanos_type required_capability: date_nanos_compare_to_millis diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java index 4fcabb02b2d4f..f766beb76dd3d 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java @@ -352,7 +352,10 @@ public enum Cap { * Support for mixed comparisons between nanosecond and millisecond dates */ DATE_NANOS_COMPARE_TO_MILLIS(), - + /** + * Support implicit casting of strings to date nanos + */ + DATE_NANOS_IMPLICIT_CASTING(), /** * Support Least and Greatest functions on Date Nanos type */ diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java index d59745f03f608..e15731ca79038 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java @@ -118,6 +118,7 @@ import static org.elasticsearch.xpack.core.enrich.EnrichPolicy.GEO_MATCH_TYPE; import static org.elasticsearch.xpack.esql.core.type.DataType.BOOLEAN; import static org.elasticsearch.xpack.esql.core.type.DataType.DATETIME; +import static org.elasticsearch.xpack.esql.core.type.DataType.DATE_NANOS; import static org.elasticsearch.xpack.esql.core.type.DataType.DATE_PERIOD; import static org.elasticsearch.xpack.esql.core.type.DataType.DOUBLE; import static org.elasticsearch.xpack.esql.core.type.DataType.FLOAT; @@ -1050,21 +1051,23 @@ private BitSet gatherPreAnalysisMetrics(LogicalPlan plan, BitSet b) { /** * Cast string literals in ScalarFunction, EsqlArithmeticOperation, BinaryComparison, In and GroupingFunction to desired data types. * For example, the string literals in the following expressions will be cast implicitly to the field data type on the left hand side. - * date > "2024-08-21" - * date in ("2024-08-21", "2024-08-22", "2024-08-23") - * date = "2024-08-21" + 3 days - * ip == "127.0.0.1" - * version != "1.0" - * bucket(dateField, "1 month") - * date_trunc("1 minute", dateField) - * + *

    + *
  • date > "2024-08-21"
  • + *
  • date in ("2024-08-21", "2024-08-22", "2024-08-23")
  • + *
  • date = "2024-08-21" + 3 days
  • + *
  • ip == "127.0.0.1"
  • + *
  • version != "1.0"
  • + *
  • bucket(dateField, "1 month")
  • + *
  • date_trunc("1 minute", dateField)
  • + *
* If the inputs to Coalesce are mixed numeric types, cast the rest of the numeric field or value to the first numeric data type if * applicable. For example, implicit casting converts: - * Coalesce(Long, Int) to Coalesce(Long, Long) - * Coalesce(null, Long, Int) to Coalesce(null, Long, Long) - * Coalesce(Double, Long, Int) to Coalesce(Double, Double, Double) - * Coalesce(null, Double, Long, Int) to Coalesce(null, Double, Double, Double) - * + *
    + *
  • Coalesce(Long, Int) to Coalesce(Long, Long)
  • + *
  • Coalesce(null, Long, Int) to Coalesce(null, Long, Long)
  • + *
  • Coalesce(Double, Long, Int) to Coalesce(Double, Double, Double)
  • + *
  • Coalesce(null, Double, Long, Int) to Coalesce(null, Double, Double, Double)
  • + *
* Coalesce(Int, Long) will NOT be converted to Coalesce(Long, Long) or Coalesce(Int, Int). */ private static class ImplicitCasting extends ParameterizedRule { @@ -1245,7 +1248,7 @@ private static boolean supportsImplicitTemporalCasting(Expression e, BinaryOpera } private static boolean supportsStringImplicitCasting(DataType type) { - return type == DATETIME || type == IP || type == VERSION || type == BOOLEAN; + return type == DATETIME || type == DATE_NANOS || type == IP || type == VERSION || type == BOOLEAN; } private static UnresolvedAttribute unresolvedAttribute(Expression value, String type, Exception e) { diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverter.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverter.java index 6ba2d8451f956..0847f71b1fb01 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverter.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverter.java @@ -13,6 +13,8 @@ import org.elasticsearch.common.logging.LoggerMessageFormat; import org.elasticsearch.common.lucene.BytesRefs; import org.elasticsearch.common.time.DateFormatter; +import org.elasticsearch.common.time.DateFormatters; +import org.elasticsearch.common.time.DateUtils; import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.xpack.esql.core.InvalidArgumentException; import org.elasticsearch.xpack.esql.core.QlIllegalArgumentException; @@ -51,7 +53,6 @@ import java.time.Period; import java.time.ZoneId; import java.time.temporal.ChronoField; -import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAmount; import java.util.List; import java.util.Locale; @@ -200,6 +201,9 @@ public static Converter converterFor(DataType from, DataType to) { if (to == DataType.DATETIME) { return EsqlConverter.STRING_TO_DATETIME; } + if (to == DATE_NANOS) { + return EsqlConverter.STRING_TO_DATE_NANOS; + } if (to == DataType.IP) { return EsqlConverter.STRING_TO_IP; } @@ -514,13 +518,12 @@ public static long dateTimeToLong(String dateTime, DateFormatter formatter) { } public static long dateNanosToLong(String dateNano) { - return dateNanosToLong(dateNano, DateFormatter.forPattern("strict_date_optional_time_nanos")); + return dateNanosToLong(dateNano, DEFAULT_DATE_NANOS_FORMATTER); } public static long dateNanosToLong(String dateNano, DateFormatter formatter) { - TemporalAccessor parsed = formatter.parse(dateNano); - long nanos = parsed.getLong(ChronoField.INSTANT_SECONDS) * 1_000_000_000 + parsed.getLong(ChronoField.NANO_OF_SECOND); - return nanos; + Instant parsed = DateFormatters.from(formatter.parse(dateNano)).toInstant(); + return DateUtils.toLong(parsed); } public static String dateTimeToString(long dateTime) { @@ -639,6 +642,7 @@ public enum EsqlConverter implements Converter { STRING_TO_TIME_DURATION(x -> EsqlDataTypeConverter.parseTemporalAmount(x, DataType.TIME_DURATION)), STRING_TO_CHRONO_FIELD(EsqlDataTypeConverter::stringToChrono), STRING_TO_DATETIME(x -> EsqlDataTypeConverter.dateTimeToLong((String) x)), + STRING_TO_DATE_NANOS(x -> EsqlDataTypeConverter.dateNanosToLong((String) x)), STRING_TO_IP(x -> EsqlDataTypeConverter.stringToIP((String) x)), STRING_TO_VERSION(x -> EsqlDataTypeConverter.stringToVersion((String) x)), STRING_TO_DOUBLE(x -> EsqlDataTypeConverter.stringToDouble((String) x)), diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryResponseTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryResponseTests.java index 35364089127cc..2deedb927331d 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryResponseTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/action/EsqlQueryResponseTests.java @@ -204,7 +204,7 @@ private Page randomPage(List columns) { case BOOLEAN -> ((BooleanBlock.Builder) builder).appendBoolean(randomBoolean()); case UNSUPPORTED -> ((BytesRefBlock.Builder) builder).appendNull(); // TODO - add a random instant thing here? - case DATE_NANOS -> ((LongBlock.Builder) builder).appendLong(randomLong()); + case DATE_NANOS -> ((LongBlock.Builder) builder).appendLong(randomNonNegativeLong()); case VERSION -> ((BytesRefBlock.Builder) builder).appendBytesRef(new Version(randomIdentifier()).toBytesRef()); case GEO_POINT -> ((BytesRefBlock.Builder) builder).appendBytesRef(GEO.asWkb(GeometryTestUtils.randomPoint())); case CARTESIAN_POINT -> ((BytesRefBlock.Builder) builder).appendBytesRef(CARTESIAN.asWkb(ShapeTestUtils.randomPoint())); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverterTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverterTests.java index 8a57dfa968ccd..9a30c2281d742 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverterTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/type/EsqlDataTypeConverterTests.java @@ -7,9 +7,11 @@ package org.elasticsearch.xpack.esql.type; +import org.elasticsearch.common.time.DateUtils; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.esql.core.type.DataType; +import java.time.Instant; import java.util.Arrays; import java.util.List; @@ -50,11 +52,19 @@ public class EsqlDataTypeConverterTests extends ESTestCase { public void testNanoTimeToString() { - long expected = randomLong(); + long expected = randomNonNegativeLong(); long actual = EsqlDataTypeConverter.dateNanosToLong(EsqlDataTypeConverter.nanoTimeToString(expected)); assertEquals(expected, actual); } + public void testStringToDateNanos() { + assertEquals( + DateUtils.toLong(Instant.parse("2023-01-01T00:00:00.000Z")), + EsqlDataTypeConverter.convert("2023-01-01T00:00:00.000000000", DATE_NANOS) + ); + assertEquals(DateUtils.toLong(Instant.parse("2023-01-01T00:00:00.000Z")), EsqlDataTypeConverter.convert("2023-01-01", DATE_NANOS)); + } + public void testCommonTypeNull() { for (DataType dataType : DataType.values()) { assertEqualsCommonType(dataType, NULL, dataType); From 5d9c3a26631fa21ae72630fd76eec2b4eaea945f Mon Sep 17 00:00:00 2001 From: Mark Tozzi Date: Tue, 17 Dec 2024 15:56:51 -0500 Subject: [PATCH 16/60] Remove date histogram boolean support (#118484) This removes support for running date aggregations over boolean fields. This has never been useful, was deprecated in 7.x, and is finally being disabled for 9.0. --- .../src/main/resources/changelog-schema.json | 1 + docs/changelog/118484.yaml | 14 ++++++ .../DateHistogramAggregatorFactory.java | 44 ------------------- .../DateHistogramAggregatorTests.java | 8 ++-- 4 files changed, 19 insertions(+), 48 deletions(-) create mode 100644 docs/changelog/118484.yaml diff --git a/build-tools-internal/src/main/resources/changelog-schema.json b/build-tools-internal/src/main/resources/changelog-schema.json index 7d35951eaa2cf..9692af7adc5e6 100644 --- a/build-tools-internal/src/main/resources/changelog-schema.json +++ b/build-tools-internal/src/main/resources/changelog-schema.json @@ -279,6 +279,7 @@ "compatibilityChangeArea": { "type": "string", "enum": [ + "Aggregations", "Analysis", "Authorization", "Cluster and node setting", diff --git a/docs/changelog/118484.yaml b/docs/changelog/118484.yaml new file mode 100644 index 0000000000000..41db476a42523 --- /dev/null +++ b/docs/changelog/118484.yaml @@ -0,0 +1,14 @@ +pr: 118484 +summary: Remove date histogram boolean support +area: Aggregations +type: breaking +issues: [] +breaking: + title: Remove date histogram boolean support + area: Aggregations + details: Elasticsearch no longer allows running Date Histogram aggregations + over boolean fields. Instead, use Terms aggregation for boolean + fields. + impact: We expect the impact to be minimal, as this never produced good + results, and has been deprecated for years. + notable: false diff --git a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/DateHistogramAggregatorFactory.java b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/DateHistogramAggregatorFactory.java index a8ccd1c76d031..4d0f58756b11c 100644 --- a/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/DateHistogramAggregatorFactory.java +++ b/server/src/main/java/org/elasticsearch/search/aggregations/bucket/histogram/DateHistogramAggregatorFactory.java @@ -11,7 +11,6 @@ import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.common.Rounding; -import org.elasticsearch.common.logging.DeprecationCategory; import org.elasticsearch.common.logging.DeprecationLogger; import org.elasticsearch.rest.RestStatus; import org.elasticsearch.search.aggregations.Aggregator; @@ -42,49 +41,6 @@ public static void registerAggregators(ValuesSourceRegistry.Builder builder) { ); builder.register(DateHistogramAggregationBuilder.REGISTRY_KEY, CoreValuesSourceType.RANGE, DateRangeHistogramAggregator::new, true); - - builder.register( - DateHistogramAggregationBuilder.REGISTRY_KEY, - CoreValuesSourceType.BOOLEAN, - ( - name, - factories, - rounding, - order, - keyed, - minDocCount, - downsampledResultsOffset, - extendedBounds, - hardBounds, - valuesSourceConfig, - context, - parent, - cardinality, - metadata) -> { - DEPRECATION_LOGGER.warn( - DeprecationCategory.AGGREGATIONS, - "date-histogram-boolean", - "Running DateHistogram aggregations on [boolean] fields is deprecated" - ); - return DateHistogramAggregator.build( - name, - factories, - rounding, - order, - keyed, - minDocCount, - downsampledResultsOffset, - extendedBounds, - hardBounds, - valuesSourceConfig, - context, - parent, - cardinality, - metadata - ); - }, - true - ); } private final DateHistogramAggregationSupplier aggregatorSupplier; diff --git a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/histogram/DateHistogramAggregatorTests.java b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/histogram/DateHistogramAggregatorTests.java index 38294fb030ed4..bf26326abafbf 100644 --- a/server/src/test/java/org/elasticsearch/search/aggregations/bucket/histogram/DateHistogramAggregatorTests.java +++ b/server/src/test/java/org/elasticsearch/search/aggregations/bucket/histogram/DateHistogramAggregatorTests.java @@ -83,9 +83,9 @@ public class DateHistogramAggregatorTests extends DateHistogramAggregatorTestCas "2017-12-12T22:55:46" ); - public void testBooleanFieldDeprecated() throws IOException { + public void testBooleanFieldUnsupported() throws IOException { final String fieldName = "bogusBoolean"; - testCase(iw -> { + IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> testCase(iw -> { Document d = new Document(); d.add(new SortedNumericDocValuesField(fieldName, 0)); iw.addDocument(d); @@ -95,8 +95,8 @@ public void testBooleanFieldDeprecated() throws IOException { new DateHistogramAggregationBuilder("name").calendarInterval(DateHistogramInterval.HOUR).field(fieldName), new BooleanFieldMapper.BooleanFieldType(fieldName) ) - ); - assertWarnings("Running DateHistogram aggregations on [boolean] fields is deprecated"); + )); + assertThat(e.getMessage(), equalTo("Field [bogusBoolean] of type [boolean] is not supported for aggregation [date_histogram]")); } public void testMatchNoDocs() throws IOException { From 1054503ba8d42b8f592c20149eaf131a129576d3 Mon Sep 17 00:00:00 2001 From: Pius Fung Date: Tue, 17 Dec 2024 13:03:28 -0800 Subject: [PATCH 17/60] Update start-trained-model-deployment.asciidoc (#118887) Updating with changes in https://github.com/elastic/elasticsearch/pull/115041 --- .../apis/start-trained-model-deployment.asciidoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/reference/ml/trained-models/apis/start-trained-model-deployment.asciidoc b/docs/reference/ml/trained-models/apis/start-trained-model-deployment.asciidoc index 6f7e2a4d9f988..bf9c4d14db290 100644 --- a/docs/reference/ml/trained-models/apis/start-trained-model-deployment.asciidoc +++ b/docs/reference/ml/trained-models/apis/start-trained-model-deployment.asciidoc @@ -138,8 +138,8 @@ normal priority deployments. Controls how many inference requests are allowed in the queue at a time. Every machine learning node in the cluster where the model can be allocated has a queue of this size; when the number of requests exceeds the total value, -new requests are rejected with a 429 error. Defaults to 1024. Max allowed value -is 1000000. +new requests are rejected with a 429 error. Defaults to 10000. Max allowed value +is 100000. `threads_per_allocation`:: (Optional, integer) @@ -173,7 +173,7 @@ The API returns the following results: "model_bytes": 265632637, "threads_per_allocation" : 1, "number_of_allocations" : 1, - "queue_capacity" : 1024, + "queue_capacity" : 10000, "priority": "normal" }, "routing_table": { @@ -229,4 +229,4 @@ POST _ml/trained_models/my_model/deployment/_start?deployment_id=my_model_for_se } } -------------------------------------------------- -// TEST[skip:TBD] \ No newline at end of file +// TEST[skip:TBD] From 9c3d6ca9ec390b163ce8b5c6aaa46854152a87c7 Mon Sep 17 00:00:00 2001 From: Mike Pellegrini Date: Tue, 17 Dec 2024 17:48:37 -0500 Subject: [PATCH 18/60] Mute test (#118897) See https://github.com/elastic/elasticsearch/issues/118896 --- muted-tests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/muted-tests.yml b/muted-tests.yml index 93d1a6e6374b7..b5712b22fe583 100644 --- a/muted-tests.yml +++ b/muted-tests.yml @@ -302,6 +302,9 @@ tests: - class: org.elasticsearch.index.engine.RecoverySourcePruneMergePolicyTests method: testPruneSome issue: https://github.com/elastic/elasticsearch/issues/118728 +- class: org.elasticsearch.smoketest.DocsClientYamlTestSuiteIT + method: test {yaml=reference/indices/shard-stores/line_150} + issue: https://github.com/elastic/elasticsearch/issues/118896 # Examples: # From 127fa2782a4b40cf4b47de3529df0b2308fbddc6 Mon Sep 17 00:00:00 2001 From: Rene Groeschke Date: Tue, 17 Dec 2024 23:53:24 +0100 Subject: [PATCH 19/60] [Build] Add 8.16 and 8.17 as base branches for wolfi updates (#118726) Furthermore add auto-merge label to PRs created by renovate --- renovate.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/renovate.json b/renovate.json index c1637ae651c1c..71c6301f8e0c2 100644 --- a/renovate.json +++ b/renovate.json @@ -7,8 +7,8 @@ "schedule": [ "after 1pm on tuesday" ], - "labels": [">non-issue", ":Delivery/Packaging", "Team:Delivery"], - "baseBranches": ["main", "8.x"], + "labels": [">non-issue", ":Delivery/Packaging", "Team:Delivery", "auto-merge-without-approval"], + "baseBranches": ["main", "8.x", "8.17", "8.16"], "packageRules": [ { "groupName": "wolfi (versioned)", From 41c3dde414c35bca765be46b90b43f918381e315 Mon Sep 17 00:00:00 2001 From: Satyam Mishra Date: Wed, 18 Dec 2024 05:02:39 +0530 Subject: [PATCH 20/60] Updated ilm docs as per the issue (#118148) This PR updates the Elasticsearch ILM tutorial for the newer screenshot and the primary shard update in the text. --- .../example-index-lifecycle-policy.asciidoc | 4 ++-- .../tutorial-ilm-hotphaserollover-default.png | Bin 219715 -> 1427109 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reference/ilm/example-index-lifecycle-policy.asciidoc b/docs/reference/ilm/example-index-lifecycle-policy.asciidoc index 6ec261fabc448..0b3c17fb2caae 100644 --- a/docs/reference/ilm/example-index-lifecycle-policy.asciidoc +++ b/docs/reference/ilm/example-index-lifecycle-policy.asciidoc @@ -24,7 +24,7 @@ and retention requirements. You want to send log files to an {es} cluster so you can visualize and analyze the data. This data has the following retention requirements: -* When the write index reaches 50GB or is 30 days old, roll over to a new index. +* When the primary shard size of the write index reaches 50GB or the index is 30 days old, roll over to a new index. * After rollover, keep indices in the hot data tier for 30 days. * 30 days after rollover: ** Move indices to the warm data tier. @@ -84,7 +84,7 @@ To save the `logs@lifecycle` policy as a new policy in {kib}: . On the **Edit policy logs** page, toggle **Save as new policy**, and then provide a new name for the policy, for example, `logs-custom`. The `logs@lifecycle` policy uses the recommended rollover defaults: Start writing to a new -index when the current write index reaches 50GB or becomes 30 days old. +index when the primary shard size of the current write index reaches 50GB or the index becomes 30 days old. To view or change the rollover settings, click **Advanced settings** for the hot phase. Then disable **Use recommended defaults** to display the rollover diff --git a/docs/reference/images/ilm/tutorial-ilm-hotphaserollover-default.png b/docs/reference/images/ilm/tutorial-ilm-hotphaserollover-default.png index 14ff66e4108354f16240ca60b7f16dce8fc6b963..d7f314cedb2612b1a9f4b534e697328ef86f8296 100644 GIT binary patch literal 1427109 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%0D4jeX~+XO(&AF&d+ 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

n5%juiXyO41NIclHzj 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 z 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

Oh7{y`iCDyY)(6 zw@nz7kKTR`RR^Imy+M(Sz%vS2sxuI@fXi09+IaK*heFDhmCa1qT9wuI}zNzAtP^%m#8mg9pxNne@qwGs~r{ zKN&(U!TL<%;{j1o?z+0VC#eFsOOdQ>91>jYV$wd)8wM93;f$^qSm4!p&%5aprfuXE z4(gX$GW6kuw@@bZsJ1uW_j+96eqQqbLS9`x1>NisJ=UH0D=QWIB_u=s+%IIDzR^+s z4W>hlLLX24uJ)Stt7V5`rTz=Y|GC(IsL5b$Bog7er|oik$^Rlbg~LfKXYC1Ht+(Y4 zn+8iBBv+t^^K)?Ozw=FYKT&=_{?Y$8EzL$$T;3M`>WwKvw+g)gYOMqvl}HU~0VTw1&@bc>YIL;yfS2Ze7YqX%&M z$5+KM%qny~^M&f5vr;WtVfWu9Xe&cnkYMKQ)p=8S<^1{XRi$4S2&!M6UD+(F;wf*ZQW;+Kvw{bu z`1saP#553Fxzon#LC$4R-xSC#Q`nZDsWV>L%FQ->7%uR(9u7mABJ9Bhx?mSDrI!6m zweD*mPp1EQyHEQQs*-V{p@C!Xt#kE{K2(ukt&YV|6c9um2~j8#apwUQOmZ}Hu$#*v z$5SchSgP@78hCHDq6nisIulXSP_Kccq*X@VBfJ`BYvg%a3 zryX@R;iXD+Aad_p?N1*~d-bgk~d&JauotIgT9Io`?%b}BfHO}U2AKaEES0MXg%xZR&YB1ka8sN z`krCTkV?O*ZKoKC$WxWG@5R%LXt!_rTJc{jy8rdl&QSQy3`0m%mf7O? zN&o#@`Qc3T?HN%& z`xkl^ec;qKf+MZ~2Xa_oj0s|?QbLq(-xiZ&`@TY3BxI~R!_0exO9&aBcav)%Pw zsl(qzHb+x z_6sW)EJvc+QR-A-R-KHEx!8$3a%X5{A=8PGh;*x37a}R6s+b432i#ie*nhG#Tnk5A zn`X-rVE4-lOpMQ%!r+7sy_#%JpDXM4apneDBN!NE<(EZh#LW~2jAephU#mBAY}lZv zgR39Jf(>}`ik(yqDoL3nZ3Q-)y0J@%F``TA$mR&N&7@|_bJGZ#S{YV*GuDRqrsgpN z=r_3vxx)QMGNm3J^)0X@{BLlPb1ShH$u5)*UXB z#8A)}Zw9bl70JbTH^B`ozJ-l?16Jh^escIvz*&xApQ%0D5^S8g^4~5G!?nj6Cr%!UF~p^sHikJL^o!H_c+7x8r4k zuw93@U4P~4>p9Owl+{xd+tT{#PNZ%dNV-*-}B#oV@sG)z3)XW9t@?+ zt<;4#Z&&_ftELy)gHvWPy#wX2xlz$xMM**>iE}^6lH?7x0$`{>@9i|~AE)fGa=LHN zJKxkmyu{VH4O;pX+mN3ga`zb;t=?BRQxqldiXD;)x~kA;&V^iTe%{((!*yHy^GOM78%NtkOu_j=yxyo<~9 zm)3UJb+m!W`yj2ew`TL=Om`9lR9Lx65+56-=8yz0Tm(~Z5`0H6&1Y+8rw6*^w6<6Y zb_4m9L;jInDDgOTkZ+(=a`BY^_@`1rFAF9|9;k`RbGki?pf{^)8Zfpme6_=Ctk6oW{ z`S&LvfLV}meRtLz@m%)iE88RjbsA|tGz=EX$FxGk?GEuYg4QThZ6!a3d0Lo541}>w zQ~>RZK(R?#sbxG`*+#Q)SZZ)7sg7b>EBM_05N zXR^|lNw}*n_euyeuglMuF+vM(13mpwMZY>-UhLcBg$UbJ3CIb zM~5|r5N$?-1uHv+Gye}FVb5o11Z3o!ZffDl?2ni1=}j&F5qH#Bd#j%*pvIP#{hd}MH#ciM zyjje%KL5u~vG4eRQf97);D2&0PkMvl-{9H^^z9IqV{CdQNpL0(aPSBQLkD6yK~jIL zQt2-?!0G$HH_6xM+uNc2w#2Q4$s2=^3~v158Z**9><;Aj&h5j4z?xOsnVO zn@!^st8I8^EFA&SXAipX!B*D*Xr3N6dwW?|{?PWjNcM|$FS>2iH3{p59)o!=apfd>jD4<*|mANUB3XvDd;A`QW% zP*j2;2{R=Ck-`5($ulJbJSpV4()%z$jyEm5^wU3eSMDEov7pp1EaAI_8Aac)43^Oq zrTPfP10o_t#TjtwPD7<=%#89u(Z+@F)4{~3*#KeYrCf!EorPuiS|v$mys(y4(bl#e zZj(zXGh9@zwCbv%10(zt50WHN0Yy0wAhnWY{dO?p&rIWEh~ha!?*%hdTBA3m?!y8z zz}k|$=I5i3C@1vdt6I$~6e^LyN5}#YDEU>Kyb1lCC4A+eTY*ppq%&Ld76$g@nv9x1 z{5BhRk}2-nCQ>cAalJX)qe(zYAT)4a`~P&~{8uWh)`TW~XLv?^JVWr0&b7l|zbru8 z-&9NfR|BKp+U)ap#wYZa@Nc{^UP9%Y8*tf;vJb{>yDydA@qNe{a6u0+3ZvH&$56E5 z&=RB?zfkpv3cSBWtX>BLSYq&FqUfx$d|G-nC(SyO`n=~EAB0~y83`^Jax(}TA)^bi zDYIb&AjBu|0;T0dUpGYbm`z|821zzXVSTmDP~IiDg$v5xhK|X$?QX@@MC&pwgu@!{ z$_|X+P?IoEzN_+{-@1R?SQ#LwuDYjX5*6AeN8e(`de7{|SjtH1{Y!LQ()fFe8+};_ z;@j)&m7`W*Kr`^6l`A#qCn!My`v2*Cz!4>`it+0QX_j&BcI4}#BQhmD8KM>nN;zt! zTCIR3$(^(9B~|~nT5&pHxob>BLM_rfmQ-aF-o~{?-Ww6cvFc0cV*sD=0utzJL=CrO zTFjQ8^q~pUSk7+2mM!2jGnPf)7>{bfc(Q7!i%B@1>ReEio%AKB0s(x3W%eWaNQz>G zIVNjv1{d$dqiC}TtFXBq0=lv@gF4~q6Rc%aM$|lf8$1QlO9NINB}j#vM!ZRpT9Zzv zBr(EqN48Fc2Ff##OU|a8{5+K5a@x0L9$5>qifayya;!tEf|?5pUR=oWXJ@woejMNK zEYc@>>PIz4QS-#m>LqBC0W<-TX0ab3zvWcz*|kgY#!A9CaAHnkA$P3Xx2^VJh0%ei1TsAv`2#6=-^ITT$OO#(RsN`5LYD)2XTq`1cCoIt%-6yXUPf7@UQRKO*TP^86nEQG#u_*W~-t}VMUG`QF>S=f)A z_)+LA{t|SMK=j>ay6(7?IS;J>>F;k&Q1c6yYo43p+PMpvbq<>=dv7DHn#!ry()iO3 zXWA(85J1P0A%d&2E~y0vd}1ACI*d!AuPm=xTyxi|wEt(*ucMdKzD_k4cc`e&M~*8c z`3Yr%qZ4D%2By5sPZd28PQu4hCA6?-bAf;5DYZucpldmLVA7Hb^gUKO((;1|mt7 zO>&wq@RpTpwqx{>SSb_|DXiI-aFxMPDL)NMLipjNa8l046rO>(>s8!XpeR(CWOZnz zwwjnQ#`oi)nBay!<`c}hK+rC{?MN|m9mwg;riDhp+jsZioujX!^U1_Bw$(~=CYwZZ zJ}9+dY{M`{&-Zjxyy^F@6^NBRb;+aQp~3Q{omFss zbp?DWL-_sDC4ibztbQvA)8b zVRkl(x&-qrC7_6qHLOA^YrJzlGce@6_(ynrHj9L&HVOxVzwZ25z-qt>WSQ|}LR9w< z7-BZ^_MU;omZn`OB0nvlevphMhbmUOuk$!EJY>ok+AkGMkn`HT!RajC8wOQbB2Y1k z@OYYM>vw{x`d+VUfp0`0#bZF(?=au@#zUBx=S*LYIoT#Y;KS`nKF0S7Myuv2I47G~ zY>c6EflDG8azH#vZ_BQLiK?&gXRT0c2A3g|olvI+zRC~QuJ*f5?uRYMh@)TDTlt#@Bu$Ia>QSZ;GdiaV2#podkhgMd!3}dOI>!c9Z7}WjFBq z332voO}FJ=d(EKzH=W;I^CvVSBI2_j@A_mKJPI(G3nyJEBEDGZE>-zUU?_@^3S=h- zSz&m(-UgVbF(e%3pauh=rd`Z9d0AWMTzWjs{q$M9E%o(S1%D9QINHnr(n9ZF_UCt*CwssjtDC3^?PwC7PA)AqZ^%HG-HzUI zg9YmotKln=K^srud*2og3M=U^n+sJH(e-KULF{bm!EF!-1V$kT#)pYrX(Rgcnij+h za%g$@zRJIP-)iZAk=n`qzF@C0^~bkr`0G7#%VIAnGXeow{l4yfg!mKu$^ZD$Y3b+* zveU6z6dQjHu=Dl`&*MGb8Q*%`GJWk^Y_H)?7I19naK8R#c%0S zAygl%T@ElFO}DDJ(!f?VFhoea^Lc2BfDT=Jll1)X??8@`8rmDiIDQlyb>VgGZA$M> z2K~jl<@Zg@-JTrG-%GF7j!_HD!;|ocixd~0%HettSC8k??kLRjs&NG&!MOl7}6rlnxjaI2x%M=>GaL;d7(=AfM zRnQ-ucPY|(SY0&44-C8t++F}eQw*QGC?g#;V27?;=)BP<5JYRiGO#yXu_=i-&?yl(F# ziiFu!0`DxrEVHSVl1z(Su|mC;R>Cx5_+g;RH-xDeH4WAz6mNzTO~d3;vI5Rr z$p@3D1^l91Ks(C?a!_eW!L!t4;+G>y5ryv+=jc*!ro);3u?Xa$K3pLH`hvn?0b6%S zEs!76HC2V&9Z|iA?c0TK)joGaBxHp_ovz%05ptz`dBBdIQ{t+MZ!duE9;f$sZaHrn zQKPL=4tKn^8kz3stLCE29cDlqy=hUr!cW^a8wQdmWz>5Lw;Sp{X8T)!GzV*Cbj?Ph z8cc&|>70msQ4y_qN$P4<6Y|4r$0%mtRZ!5wg;2$O2yDOcAcR^nY*yzZ{X>gft7KzIO(~4|7xDC zLG~)7aRh486mdj*QJ!Ms3Hdk{k)9@pjl2wbXH| zth!=hPo@Q9HJ~Y#C#SGn;H`R08L&t>5Nn+K6Dus74{MdmE>*Efwjt5hctUjNpGw1o z_qQD$_9F;%lDTVyRKBQuU(-N`Yy^9)hvdfYZ%^p+50*4(2*1_KoLj|Ri8arHel?vg zvrIU&;bI0<^{vom$cqt{;PJ^$xdcp{G>WYl$yiqiN7$s7+FF&1hekNGGIRvoHcR2* zH6e)EioFp9W@5&~Ew*jWPEUgrl!$k^dJ}D_eX$$uPo+`i@x|0!%)hzR-fL<@c*it@`g{VYd2`RitKP zWM*eHupN*UB-M9>VHfSL_W~C4i3momi*AegL~u*~oVEU|a#=xw>V>Ow;ynPZsJ9e> zq)=7)W=Pc72cE{wq_1yI-A-bD$>sbks*YlU`VNA9N16ASTK+GcwcnU)f@+vWU?jQc zO%i5xU`RJ>1$6A42%vZL{c4aaT05^mEx(q{L#R=&Vyy#xZkeo;6gI1Io_@GSpI^&w zcgHJHd!6X-Qk!L4w~tT1LPCJhv|vz@XcRK?4HRQ>3_qH<^xS=BTzv+M-^Mdig?-Q2 zEsHFzJ?)g+eC(Qs$mNsPwVLfKo477_>C_5jeuH7hEdM1$M($pFdeS?ym?TDx#pOQJ z`bcVqyz#2`b91yX1AT1jJ!xr5Nc!F=cLw_3Zhav?4@(Qfk@fy$`IESSO2Z)n1B0Qk z3*OoN8^mIEFe+%7zkFiYJ1c1v=zQ%JpJ))leVOikNAPr_QJKW6 z2y^ns@Lw8Qv#7mWdP?`XjVv5>C3FYTdA(4*V;k*9cr?jKGV&5fLo!^*VM|sp9B@r5De$zB ze0>_QgbF@BIbnLWY0HXJ@zpL;X9(6=b14*Y#k8$&5B2c2|M@nWg7Rz;w5FVNmVepY zbv1%wqF#L$M)mKnU^RGq=hE#MkA!<>RduA8^Id7QJop;^w4HH8SY{Us>#`f5gh{CQ zmNPd?Z;oneYq9u6$mP$xEue#MxSi-hkmTq)oT#1NmcahwSxjR=!gLekYSIvRsX38SGe5Wn8V_k=#$*xZfNXwA7xbhC-7K;kc}i5q90HN@w2AMxN(*E3~? zo=*3u)i-WKe{zSe11u3=uUeRZr8+}f$3T*${d8Vz(a9i+>PUP+BG1hECFj>m2}+-= zBgJ3H5N%n^-@G?chAgAO$t{P9k7lh)1iC{1`57JSZv90rb@9t~&_zH=u|4{OI1Ay@`|sL$s&QDNKaAc&M|+cmK&b=!$Jbuf5k;;H~#D)&-Y z!0uZNH=u7d^z_?LkqtyiQ;h!bo!(Qp*oA)nsD?L2ejuRdbAJ;uArV@-^9g!iK4!J1 zJ;L`>gg1HrNR9BtDH&2aYUeuOQ;RN?wPBQad^mrP79DZ|HB0@E*HN!}XW}BIbxdlU z@afL>H!|3BSv-Zjw)Yji$fQ(@qDdW-F*k01FzP~eA@|uUdXKKHp)L8D=<)`Czn?VG zfehw-4dsSzrtJ6lKCmxu-gW`L?pZu)6f$e?E9JiGloX$mTC>;GvGChhhbQF7dijL> zO=d&;aBsQ{b!E#9xJ?yvZqC3zHNZa@i~K=j$AT?yi$CgB`8aQ-#wkLg!3CTc};- zdSQ1YResk>+*Iogx0>IAd%>%!BR_gH-uh}5I~mm*-L&0{AEm3}f)}GYJE>w1?1{^& zm19rVC&!ir(k?<<6KY{C)H*)t_*?*HB~9OKaaBj%!Zlq5?3>!iGBlc`7`9$X7cHPKmvgG0F4NLw4 z`&d@Wg~q?Dx^Wa%9gX5$0L$~{Ej_dVhRWWRRLX5)sSqv84X9ydZAe+P$r8l{iIU=b z=BM-+nL)YRFh(h~Ur>+gD_3gzeIx8(Eth*_iKBu^g22Bin8&ffUW83=u;(!pkjjHm z5pHJCO1ev>v5{me8+CUMw&?r+DE86CljH@sr)^DlDToT-6tXkf5^2$wP!p`_{T3U+ z)tAIKp!9zu^fZ*;fRdI{Q`HEx0($n=?#lBw+3H z#7waIALo=Y@d?fHsn65?)tHPAtlMm;zO;q9GW#&~!Qk!0#t(@W++2Jp*c&PS=0mDh zI^vE$7be4N`(1F7G?HQmVoST^Lf`0&;sa0>dfUG`GD3Lw)G!pmS>P*7>YNq?oyVWM zZnC^1Z_u2FBlY^>nHcZf>An>Nou=0 zv9Yqo6d=F6O`K<#(x1t!Cf+BP-^+$K#tRJQ)td!Of4A_FTX5A7d8M4}Fi!S7;#?f3 zW&VcS{0>t^q+M2rAf8G67W;%wF-d(^g1G24d&l%uLz)8|xiMQR=1^~|dwJxkVbXKy)=gGME*O9?kev>VEe0c~BN?B>o`CY&&pZezz631@-#v z!upHxBCn?I~BBVN_h6r zZfND7e+sa3*xEmCH;8zUy2V?~?9#QtbN(G4UJH7fX8C&wKVG!qT257L3x5?y?~bQR za^!;3kPHTDLBgSnkmlebu;3s#U5?WUz0N4_t+%klz$~{t@%e5;5_g}E|6;yDA%>e<apI+wy?YZSg20~AUo_eFJo9mqHv77kS%AaZ?g8z9) zU=J%SP9YmMH})ThM&~|EZdud-x=^mrm5PqnBVJ`~eGVKYmO>pRu*+ z_t$COc&E%;sJ*;^`dAhvH?q7(8FY*HN|Az)+{fKAXXycfcQYIlHDy)WNv2Wg1qm7Q^H5=88gn1K#R8Or(6_t0zG{ru*G8`;we@OEx~k^qL&@PsHVl!+C>M zuTi71*rC?>r6x`JiAU|HO7nU2l)}2RI&gDf_p0h!#ZXaedo_}vyVdjq&LKwH8GSa5 zn~$F3kRuQj9OOSJb^|!721k8&wh9wZ9}s6 zdYV+&UX4L`qN}%%S4NexZMjmyNdtssdYuOQq?m*Kp~qXZHNC>^lFzhz*e<=Aqh(rB zUPoAmK7dr{A<^$Y|9#fU4(viXd-Ttjq#~C}bW7{Lnx0E4Ou0eJ^5s3!XseQ1(!5LF zg@VtyhDr}{KzCzF*S0v%eg4dOT{zh0T{oeqVUB7= zdLgahPAfI;ytTp->6kkp1yJ&rh3o*!Sf1yrO(nq~39&WWe~tI2xBV@9~f1 zMTKhDSrcRPS_1qJz7s#8;-sa(jCRqID{jn0wMO8h8zZf&ocT}`x$xgsZTvy)4J356 zhM)>kDy28*T?v>2!(T>{cQS?lp0mwg4E2ZX4S&@sklIMjFZ5dxXXNDECw6Vog(q8$ zHcO-5%I44mn03k)7Xqy+qvU0c+s*~3Uv30TlwI*NBuFWvU<0D2A_k(urxN+3K5tb2 zcD^%<`q89^3dF8wFZY*fHK-V#lh^;kbBZv^u(#A=0Tt26Irf8P23@qfGWho0(s zrb|jDPwPQQv%oT8fzJzg-*xx{&P#SUWg zY5ULfN%pHODCj~&;*Cpo1J}Fo8#5sJj0-*|4Ta1(ACSxZgwST)H?3OnCJ2+!9TGuF!V5mi*?o^I!?t@{tfTdd9At-_?t ztl(ZCHQZO2574VZ9!Gi+W+(1W!q|j+MNrE4|E}$@N|yz$pgtz9+&bXCRZ!@cM8t_0 zCR)7l-hf@5vByKo%stx{7@|{>gk;>A>-cZe+ET%qG+z`>DG@LvCraQ!$%UHVnd`S? z?YYAyP(0(rH7G5VD$q4Sz=qnbzdx6m*;X3SP|xlFKl+qyl22vbJ5uk+|M8y$4kh05 zwAL?X*4E-)bayf`dS=-zcd-%~+aJE?0%`)DgYp{H*8ugjTn7X(2E;xepEO^5rgi0j z(~5ecOaUw}oz&4_*7QK7TI=#q_XeR+TAc3&9b9Eg>$MCOXSQV_ zkdDlY@W7H)D>~q^R?AN5mU_+D?6%W7U4eMoUY1L8@an;NcWH=C#Lqy@#1ICG%kF(s zHCk2{Csrqon-dT!Bd4xpI<2Y}Y%$7DwyG7!;9B#jYarGU?R%1%7`1Tri}n}^e!(6l z;Oe9?7q_}B(K_a(gr7ad45bx$u2Z~oia?mFp1%Ru@y`rKAo-9_pFi$(wtI65@0+Qq zhfEqz;L%_7Ul`y9unW0+d5*4sE1ga*;vjx|D=?^oEksL>~O;8Js2)wYr9 zfv0qWyb(Q}#|w*Ycb+Ep9@1JDFmW7`QPTGD3bRq1!Rkg22R__C8IZSREe?T&*PTz$C4`WEZjARd7g%s3Mki0u$r?kx}Uik9Z9TYLh?QOR3<6rz*Jo6$_ zz6K>SawrNj#t!82yqR`Nl_rSp&z1jR0fFLPduPa^zuCmc%uoT zHzR@k`aP$ka9Y~hKQGrIu#%ImQ0AKnIyN z|H%3=mGM$lCXd@Gfl{V!|E^m9+>}5FHK?K-)O;VBKNP)lf5OfKd__Pa;)_T&+Kk?M zQSJ)yzgPaG%>sT(+HKXs_gNrac|AStVt+1fb-xk48*(7}&kR%x68`r=_CE&hp_Vk6 zOviliqa>`K4koz#9v2Lvk9hIjGq6-50Uq(+F`-@tRCl{W(4fdCz$i?u5%rBV(ZWc+ z;Z5g&qrdPwn<^tUO!J|u;K;-Ul^6nSUks&XNklLxjOCzz{N`#wO@B1+Wvc)RXniJUTE!7ztkiAIl$Z}HwJ{^s`#3Y#nG`OH0fkEyn}-@# z{vwD%7%bMbRLxmWli=dVvs2MW%kG{3n^(cUqieh?_~`{?xNR~JZydY>#5Gmf7ur?i zOl`M1ZA@RL8yCTns&4q5$~FNPJ{+(B=;L^$7g-!fHAVL;^V&uC_mC-dS>9!F+&ZtV zBj%>i*4&FsCn2u*8+(+^OT~04Jk6YWk0xWe#p9zQ8}rI{Ox&)Db~3rNZdZ z_k~5_>(_M~+t&Lly~=YB-~}W43~qkH32o_RG6&9b&1sqiNr7e(#BPuw5Sv z(#kq}PFfMNUw`BIP$*D?>@!&3(zeB_q+d%c10Rx|ZknhXx3_f@wRzh>(3M)&)HBTe zpBGMTd`&6e7n%MtrEgUNLXys)EV}N5WHo0Y|L{04QoqIoQipTrRa?qs?02u` zo-su8CD2fRpK%96X((uAI&w>D zOxTl!D3ed0#kcl1_5Z=#J_NqaegS<3>wyzN zb7(My3A5z%mKAVTzC+Kkm}C?>pSXhEsvs!^FaKt0J$OW4Ai&YoEX(T9OyFKEk_iIpe5y-ZJd(V|SgI>ppcN3UB~yA&FWiTJ!ir0H1UO zw@4gCaPlO`)*lc#p?))1uK-*&L;r^T@LHkB8!qrj{mt zSut2%sRH4)IL+`!)z{rs0l)gG=sGOi#`+9=Qo!~tSR5c=%uDeH@j+*$Nh|47Z-6TS z8O3*0`eAo-183BJA=Zbol}i`V8RjMO6%ijS75@J3L?N#d2V-e808L(p>Q=k43Vz|_ z8w-3FfA{nQPhgr*Ty5X;zs}h8I zNQ0PFjlDxrJ9H7Ff^agVoZBk?kP{O>mFMhR@%uor?${P zuOst$oS%7`9M=Li_}zCe+Z=kC-yJ`xh+eyWrlC4nr_+gsoHDr4S*1`=4gEh@I`50O zx~YY3s6qI0qJdEKAr|)Z8v8SZM}scp<}E+^w4$ESJy3edWomE!gk8tbu>U7ZNcQJR z_TYbtRQEoRJMi_I5hUufng6%5uyy;H3rQ=Kc6Ym$oX2mM!J*?p3qb)4JhmUjN<$Qa zdW__S(~4=h>#)2lW%VUgZTA=CrA}7EAG8C~w~FYt*$M=~tqGKmRek@Flr<{}-=*LL zyBxA;=`Q+Y(-%t9w+-G;A%g@HX9?vdgAu^?G@P5E+&eWYbOQJW6gpvDW#Vlsv(69E z^WBSCv)_Z9wX4*P6Kocpr>&98v2hELiRrw(UAMe`mk-(Bsl2Jw`FA~v)PjbvLbxeAFyo4=#4 z<>HxG+ZMX%Ra4-Q^Y@r6j5!Xmy^){VbPxuaj#UyiRq&e@Et+3U%Oj>sNQ}95E$Xf1 z?u{%tlG$I(KQ1O&*^&J0Rw-3kfZa|1pOkZnoA(fvADU|Zw@#aTuew)#KVTHK8?#X8D9T|ny0d9AJjOtw3Y;sw5x zq#tqcUSEMyRVASjc2^t!ff8*g$Tu2*m)fJq$6faFS^?|E1O9jYO;Jqa&?V=j_f_U2 zlTc$JGS%W;zifrw`;x|=TK$w-HVqa9Rhu5nPQhYb?r<2qCKj0o^Sji!0fjdPLF$%dRSE`TIp0yxgrF7J9S}^Vr z@K?AX>P>MMdWAWR>ezVx$eh^DXgBbCtI_3NIKx{KKUr!Vav7p&Z_%hZOVXzeWA|(}BXOOLCuj zgOeL>MkM`Wn@Y#}qBfaTj!g8mS*@R7O(BKfv=;Nx4W>y z1V?b>5IGp47}tZjF3;n|U4hDek9VG@Bh*gM%cK#jnhZ>tgOS{ue+Ab(cF#}hmpk3) z4=s*rYJMX9=NS2XWPZnf4j_IfX|ltGaIQV&iMlJI4%oVuCFtJdKs4mP#``?zdiQvq zjGx+#G29AZ~e7yy_&HcPPb+4F( z01Xd9OIz!v>Zud@>+S3CYS-Y(8#+zO;j)~W;eRM;|Cg|)k0|pO5^O(^xLAp4w4FP0j zbY9QPFRsoU)n0VxFKm45QW>w}_3+!&TGLKv8^?6Cv+a*@laovkTXY9cvo#!~7n-Zh zlbl{I7yc|Bi2%tB_BmiwrDrUG&6aVyW**+9j6})jclhH63JI5-;D2;e_66`{;_QYy z>CW+k;^?wVB7{7C?|n-wA4B8W>{8|THZwlg8m1^K0jf=DS1MmjUzkWU(a? zh5W+_rhQ!B7ZHLcg7%iXN8^6{+@glg==!1S?%H*)EkjfNl`)*ZtXjp3P7*5mcixbQ zpL-v8DUL2uV)U&;3o}~;&E}Yh+EW$ZQyyTn9EIkIeBHy`lJ_m$v*zJ3nIW`468v z6$O-&i!5AR1hl+Sd+bFumkd(-F0a`dgZq1v*3e=P-#C)U;6`ln?d5ZU*Gv2ubsxIE zb505Is4hTz`K=B1F}kNN;Fk+MJ&&6^EEuVZh}b@FemC$$U*=1f8%WBUk&rt?@_z_> z%c!>Eu6qz`fws821usyvxLeTT4#gz|iUbed0>$0k-Q8Qz$b|SvTw6PgyzVp1ptj?A_k0N=3zEO6cw3Jk1R_uP}r#s(vdPecP~c3842M_nEhK z6=;2%(Z~KV2*k*ZPeWk+DdS}^lOiRxCw^x$PL?{E>ynbkLwuyg1@$UK|A#nF9S-fj z+@j18$+E5xqR`lBDy(e%M)7WSY4YNeL#0&uU0H7Pl;U2Cqh7hPPs5Q{zT%Efd?GBg zzURA%Nvr{d%10u`h;OH`%!=WfPnusBV+MFUx_94n?&X1s5HRfrjskWq=G3qz#=z+yq?eC4mG}eT#}#ZN>dgBA{$+a2bIW(*3h8AyQv(2s(r|;Joi9jn ze^OZqlRM@`_3>hfjBR$CIK8djdvARlaHsSBJ?G0D2wrNj7I{ra+cMtfzaieW-+!~2 zf74CTy6O?x^>w6I`@d8C|5syjD2hNdwLe?nV46=uSCdhnGh zkl$5vr0m%)Po4@B@aSrG=3AD(tG;n^MVCv2u=ubR?|`Bma;i_DyB_crJT{Ss$NXJg zw*-Vl!C%~k2I240l@b!lJOm@fILm)^wm-MY!kOZ6gbp^UgbvFZhg>z0vdw(E4eFqc zruL;j6I!g_IjYbqeh`K2fkc2Q7FXp@YdM`!%jPOGCp@7ET}8&H8MI*4E!!CS>W2Lo z`|G@h^2TJrrK!2qS8)at974vSh#c%?`*TiN`WnDM}Hc1}+ zCh+UrFmk14=Wm9OB+i${z=^ID5ytAoX1ZqpaodrtJoLJB_$V041TjPvYtgv$QYF)1x6RI>GqQ)%lEvRkbdzzj!h}IMWWD5e5S# zt~^`*jY7LR>VxNA$64bZJ?dkwoTl{54rOuE1zPxv-k_$} zPm~Pq`ZHow|NDuzYR2Lk7!+Cns!*|@m5xeCdNr~yC@ql8FDJAZAqke1{lUWc4juJ) ztsd)V321nCh`?WPibzFCQb|LtAar*jJT)f(b6Wf#eH^}1&mGgm)Wl|nSm&3Mo^H}F z#v*0_ZDzR_Sl3GYSVF@1yvffO#KlJNXDleh>!c4P2suZ48O6T9!L63l{IJh9{^57a z$eKwwY)_&`f>TDg{tReH82iL2FToRB+qEniA((agG)v{bKy_TyLHF(mr z4kW_{%z=dMJnQVlp9=DeoYUCm?NyEx`<8ad2YC!6XMYEsqG(bUqnV$Z*_L%t&K z%lIcI$MvB~R|u?^TJE^fvyiNUj|6H}y`4?PC{i0Uw~l+*q^>sQkeenw;=UebX{M5^ zp*RKm!o)9?%0cM8&QTV|z$$yaIn^))!sIv>lB2r3py-ZW+v; zGhL2$-Pb?Lj6CH5h{|_~PGq(NKX=gG{bKqvGPp;JFnE}4LU)jf0$-DShK^HYydS=f zPqsEovh_XFI7J3IMgU29U%_?Oi78w^_$p!0QZu~byW*x@Y97xl4jdd4OAe@QK|JqN%O9VtH;?1L}IVK5WeqH~#Uy~p%2$bJ%{sdLSKj4b_4Y$kgYFJNX zn%C}jFw5Z@>-a7qcqh{?QB9eC6`gw#htGm0OAwY47w1(!MxV?B#4dQA1FOBMxF5ht zAZ1|2k8cmlAt}ge=l>mY`wEvP^2ulF_n|r2+MZj5$Joxp7nFo+-} zYUjqGc@cbl0*7}-53>&^Q_x;RPJ}30(a5OMu@LWG8d37p_sYA3^PIN6Qv}s81%BLy z+vZh%Nd_s|ReF@nKDJ_b{cSxwyT)^p8m{_H<8j`y$AF;RCstYvX~A-w5u|DBUw%u* z(lZMGzLex>+;KpcP$aOI6^ce}w(0(%qJk3CVTNC1hq5XPeW9>Ttf600O1D0u?85rz z2;z--0lM)|)dr;&k)h!WXz$Qvj@R0WWFF|DuQvaK@7VftW*!vJrS~JmU)b#XbPwui zRyw&!P1|+S7d@GGB+p4!1Y}<1|C&1fTPrZ0Y^om&l0mPptNWhm)WeFd4e4Q(GNd;f zp6?8ERR>M z^-rpxwesmFa10P?@X_E3+CK$(SQ%`I?NCeCb~9TP>3>gP)7`fsF^BdRd2dYlV{fk z?x?oVO$>qiY*;)PM;dMbm`1Z>sapIKp06z6$s5sJ)4z`EE|;amJg!Dr4Rzu5cvaod z6VQf1y1iR4X}RmugPK%nY)o4>vY71l`(T-%Q}0ul1>cP3D9!1R6{ug?mU_ zo2E&i9)=CQvhCOTy8^eSH((Kdu8MYDTkGO$=aXZEx;0jwZ^mc*9bs`2@-6t`wF>MiHP^FW> zh=+b>ky@k<69|C)W#5X%x{7jh<4P>H)%{b|QNfd;a$*P^lUpi2v+!?90)1+^swjC3saRnw8(S*lf{RIRIpa_7 z=^Iev9vVf_9YZt9EYI$9K#7>zdfq34*xWZNbD2zj7{Vw$X76OvGRX?;%T^_Illr_C z87Y=OHGe#d%*ZKTwqMaJfyM)GXNN++S$P0{OG3>QMJ3l~ufWI6H+_$6%o>lzpR;Ow zl-sF=g*Qae+belUXR!=Wy_amB;&07{%K*vD-5LwB)W$YXxjQuQp$-DUWknS~9Mic^ zb-z~)&+cTnjfX}~7N}2ZZv|_EVtAGC-#z#T57to0Q@vPBcUxHs&wb!6AC ztClb`rue~!6}jR=cmg$V4j5E zSYOTfrM#!CF6mo(0$<2y7bZ*R)BhJ<*JWL$2^^`1(;Kr}97^Hb6%>%x8iPDjM0roe zmvDA0AI~7IbS}~bnF$rWxZw)bezmfD)|ie&UQs~r8mRg4%MS}wwd0$e1Wa8#WN7QE=k2Gn!NpIIVWcn`!@o?KV|)$iyv8947wlH*M1$_lSRq=6ZU;UwRCxQKM@=B#u2+xcOR)NhC^F= z;d-FH+T3l;=KF!*+>*zv5SNk92}?*>SeX%HO8B7;udWlLPge75;86UH?`v&Pc_L<9 z2lKA+D=K#FsZ$sLh?{2vZ}Zg3x|vOkDx?so?Ad{Wh5;0W*?J9_s}6MWn@9f9Ezzd2 zkdwK}Vb|^<_&E%)b?^>rL}Zsgz|Umi<#$bT5c#f^@IG`k+H_naejk&XSKiXMShbyr zQy{6*xM0A8l&+;PGp?|NSFOJAw)%3xKIbi1g!Sk)8@(Sk_(GX9se|c)MX^Pk%3<}M z_&a3;*36@Q-~u9u{Aq2Ee_5hnnsD)L?})61+@7vfn1)&Ak~q&YjkOtitz~8A&U3W$ zJT`lkkB+!h!cQbu=R}U5?Zu2)Ci-#&;RH6}Qmp+G)l-u7FC_X&2vh$Yi-On2f`Z(8% zXJ|e{P9iswav^akiSBI7il_&@8c+P0vhP7?TPFC_bcF#qp{ZD;7oW zY8|A-=D-vDVhcC!q2!3F@&ozW4Q4ND+EVVcVS?V=J@`7M-s6v(ZJW2MP5m3j9ew(b$c9EM9nA}7EwY_jh)=gnh! zSfzjv@Z>X!w01yaYRkj-`#^TnEy=F~};dxhyxd_?|}^&tlHc^e&9I z&1snU9fkNXqE5j2=+(e~5Jcu1@vJ+5TlzHTOI_;`BHE8C*2};A_rvP{CKg}kS#nN~ zUcoc<-sX>zNB&Rh&OfEDI|s6_pHM#V)k(4^VqPjT1{Mr3jP$5RnFkXD9{Kj+C*`Nj z3{PDw>1|YnFXf_=IX0KK7CnZ&0z0R~P`FA)D5ZZECN49wB9oSEIG-y|UIb$w9eg`b zlST;j>4oqS1RqT+4G({`DUXr~6Dl{onir2Wv238e>xc97d zwp@v9s{4>$GOAPzE0L%T5pcBHRpE)BO7DV+o|@}eu`GBAZHUO3jfsP~N&_~`N3+o3 zV9?o{!+HcNwKId5fJ0KuqpzWMFHw(cxz)7@clhFhb@Q|M{Z7f@8GG#wqQPDO-qGV@ zq?>9<)sbv}!j!yle?NYtyUoLh`^%Vpha9_l{@zD+`^vZ`0Kv^dURSPf_E||pyS7+! z{;=J0kdVQh?^jyMM-Q%a9!sBSUq>N?r9E8!fo(FXx0t7OY!q3xJ>0`lCyJ`WsFSHQ zwJbP*o6c#ehjY&x4;@ca%}e@#yFy)0;5*g<2nHH%Gt3{3$yllRn~h(S&Fi>RXBGeX ztye6_Q4B{pmMD3ld#ct5g5-eqj^l6_G3Nohzx z8hfv_Mn6?e;gPT(72{g)14312DZje7hu2*ztU@&bAf7E=?5S85(8k4)*PRy~3CLIUT6VmN0NEeq-DQHoFeOAJYNAYk< zA71@3Ltr(%l$^m_Fq8!1$-bxd#NQTcFiVwZ$THQJg3G6~LohrAN(9jNNizBE_m)P( zy)sKPNZw2zT1~H5e%J+&AZZ+^y5?cxNeIkO4QWg)IwpFO!}ba%AxbX#za>hjw%^7t48(NR4;g`>Ior=f7y*Ybd=1R z_}y4EhH1AfyK-Rx5>`V(^g;y?9aBl}$q&yRnkJ|BG^lIO+#(&=|Ki<8Gqn{RWh?b( z`y&{wKH(vz+j*_s)|eyf@}#6QL2R~DuVg`@F}g1=7Hgl7lTfFy+b9wR^;031s4Mp< z`r7sU*^kwIvD6L`H5`*~xM5(UQq6P;r2VcB7WzGGn)nCRCwsy9obhML#D7jLq;9^> zzEonraBbU;mf-&^EBRlQx?dd;@diVdln={7iD@Q}Vj&I{6Ca)K3oXhxNHSDF!}S(3 z+3tf7zf;ml~oVf8i>1?6beW^ zBCXF{rCJl<_JPtg*`C4~hF?;PAx$ZX>1J!EzATB?;Pe&emW#CevPW*LgPm~DJo-DmWQlQemd?BlzJF@hJoEUunpe6 zXCr0=UiYK2rM;{olITcd`A!1<&UjNsgxNmMoD{^WJ(2&Q64{BLxSt2vC$k+Ld&CF6 zWGf+a7uW{_79)kcBpAPJda8V`4<)@@m$#nBUgyN#ZW-)J!r(>$JK`CgG8BiW(Oc}; zE@URW&Z>0cUc_FK+%pZlxe~38U`Z$vt5@4QnPNwev_VH?p_sr}U5z^I-C6tqcpJa) z=F_*wE}Xo|lS;HgIT!W)h+axf9&ai#`_g-DfyzA|dKXQ;+OI&fgWxFj ztGejN_l?Eh%6dn+KC(rPzL6aWl;h0kJeKtmlE}{g#1; zVd1#aNU!_{wW1B3V<~ouCmv>d^k}!IpUTbvl~OI*yH?_tSt}4*vPKAr#)!`{@~Y`S zdoAC0t`|p3iQtxm4V(hn>kP7Ta|)dr0BKTZrED%C}~{Jyn>|>Bm|V z-e*5Gikr-pWKGW#MyD*Uz9T$)vkGoTA+E!}uvwj$@zt5J>GtRu!%ii!Tgg|wlz_tgZJVgQhYyl!|m0|^BX^ojhvC5n}b-Ro3)+^;L_Cd?6| z;n_1OEI8$iBLW|zJSc_Aq#u$czf&5S%g}r;Y!IcpN$!&p*9eiIwd9*z@Le%YvhIyX zTPial$0!g3b>b5<{loXnGpBo>nQ5ztn&X%s1V*rquM!c(m58@x?K_emg*j$|<1W>`?T}&(sJy`{KOB(S7$QJy z2U%8ON$1#$$e__T?KFQ~hEu4IAbglam9X&Y%mG6Im7mxqqZc1viCnKhbYCN8tREUX z97NnV#^&8VJruNzYTm$Go&Tx%Txv{7s=#8LvYk{L7OpjJOeF5pidsLc8=@kbniT(} zJb@6(pGxTLr3$p;uq=1(y{}98W3^DYz!Q9GBau7FXs% zPOq}r)5KMYYhW#o=&6t=ogGIBIo}(8IDVA&jFmxioYcdDu7}a^G8K_>Qt!K6iKD{v z@6w7GmbG7tnIDAFX2<^>6&kcwca1qflV_^P)u~37Yja0?@Lv6T40oES;NXP&u-c!n zeA|Z>RJO0m>5~{pIRbtp$XAcdtTrP=U!+)tiWz~yI`Sk3pdAyM@qQIi-HuHgy-ednhA#ZM#kTdFPF5hg3;(SUX;FWk;o66OwPx+~sMHG|$ zyBqC2g{jZ35)+oh*#@muB)lb#)3R-AOZcBWwUEMb&-*KU+5;9<^Kh+1vt*?S0$wzG zq5MZUCl!|lL%`51+9FENy~k?t6z{2D70)a`Il~%8E(BU2M}FVP48GLTC9F7%gj=6VFuz`7B8Ol^e;QKi46w9 z*qWnT8gdGDbt>2;$aIPWv|-{)G)%Tsl-qs1C7=*0&88svT~>`PD>_P6dJhMEtbg}z zfsf~POD5ENBoWQYBd@Uh58q~dCK&g?9;tqgc$N&Mg@&^$A=S=~Dq@u0(%yT)U_M)L^DE&_z{Igl+5b`u7;bCiP{r#se8U@e;pts92$BB+sRYe-JNikRh; zX0|3Y$@1seB^dUQcyM&eP6N|OJv1od)HCQbfi>DbEb`WpG*>zqwH_RuwCIe|Ydw4D zMNL7n=aH#SqLS-?XpT6B1s--3FD?Nxtxf)`!P2c~4bq4&1DZeQEe|Zj^4<9zz<)vZ zKcV)qNAbY*_Y5t~yWdMdKydP0d}1iJi969qvo>dQ%x|m&i9ybm)s>GWJ(eL;L3mZ@ z3EYd9Xz}=Cpr{H`Ez1X7Zw{rZmM%4WPly6EJV(vQQmf@>7xp5|hpj1yQ)J1z0^tC! zQkB!)i}va~D2$PNKi&VcooiMPZVI3C&Hfdyh1J2?LEc&W-XVRd0@Qxm)TyOt;d%Yl z0pFXTH^;a6!gxS<8sc1$JIrZ|JSi9GdQ!u^U|0iWYg^a>$X9}aspj(urBund~l?BI#=J`=vx*eiYULMhY(yYo;Cxaj7x&Nh!&O;NJBGL70NO@BA4|V_CzA_M;MXgdrKa?v5#Vv z-0-hLoa^I%SiS!bp#Q&ac`N^l;El_}!Q%T3%_kU`!Lpmp!^N6oL8c`C)7Ot)5d!#x ziZ56Q!1BWgl?@HY-zLpi{q<_oSOAMx0exqZ6iKd~R z2F5HH;TU+7q?Anp}u*YV+h`-KD+#@=Iy}Ednj)*b45*=v|$W;96uIEp8d=OJ=3NyBRIE3$oVeN8p zAOcdH><`BsIG&=NNgTxPTi3TwPJ3&pJUZDcBh7Z*r^OwOs?VtTp3c_-*2tX})>^Gi zI?ju^swrT4J561+y@oADMol-hs4qdDH*K=~hFII+Vc*jf1CdLj1jN1Jb-q9>uhXzq zQ%z35;uPI{OOATmwV8y2$w|=ZdYdfGqOBqQuIm~fP+^#0Ep1&hcSgvG6cM{hfxb2V zliD5_a$dTmT}$$iHLfZJW@)*!7EQ3;SRl)A1Z>>*|6ng?k@gQ!S}NPUFXu5)+^Z`xBaGm>P#>VyIG z=Y1RfxEMZCwEwHpK8;mM4a`yxUlJ$?&AWLYZg>8O7t9A}o?ItTO8A=9^#M+M!z??e zmO#DYCY?b0q>WF1?bS*vbLa@$^60Jgr>dJ=NgAfaSl0bUVocvohL!L|dar_)OL&d- zFL$K_iU==Ws)kwyCadil-IsG^5%-*bt~3=rli7H1+gyO?Ui~i_~&~ z_?j4^t5qb5tmlnod*-P-m`G>vdNyMwOFZZi7W9lZ0!NlV?+iIy!mS`=YBX@TA4lyE zvcd5E3W?T_aC-W|7;wf&qS-%v;pt?+*6}T&Xz7aD1n2Z?==9*x0SE8Nan~WahG4u} zy-+yRK>Ti)DM+Et)7G-RMx^SWYRgFJup`(y;crZVD|YcFS^c zc;6Lj2BdKeNkJU#6{WA}U5!-s_n2m!OJ*H2+L0lwmK$D{3aLy24pvj!KV`O=E=tEi z*g$Eea`zgZ1PwVc5(CVJ+0CBE6~{?0nc1r9a*hr+X8W(WFN8N*)*wTEG8 z1B>ecRCY;)S3p!sWBbu*>gax z7*h#CpwUOL_hmk!b?Jw0krGL|W#IvAyW}{Q3WuQTu(2J1BUbCNd*TMp6w0*GuHn>c ztC^39ZPcG#C=_R7B_4a{3T$=CI`vwP;VF^MjhQP!oY^;Ym}pI>6^rcIyYKhZPToUI z1RVn&-+)i70%|unJ6BEw&Qc4_=R)=)Tic?}%{Uu}bDiwFSE^xnYb{ELmB*gdo5U}0 z%*AK-H2igT}RV0!+3J`;8cdBoDOx+F5H~MO}RG@4U zHs21DKc**%;tr`Q789=%k!Dg#t)9R>0;vtVFFw<9t}#SZS5FweuZ39AoITO!_CKz{ z6cU12TaoT^ifdYBw6#n588?28_z#;5g!~$R6pc{|O|<#2YT7i~jpNeuI;AvJGAl3e z46-DH>}p1f{8;f-ZtM=7B|;={<}VR5?WRJHzapL@BNUjF2kDNF%W2nyqhk1&r9oWq zk?2+B^TcN#hE+B1E~N88^3zM0uI~?g)ctb5qs6Ve+qgw#<%~v*TaT$o_6lJysYVH; zwy;KU@N^SO|K-A)3rxfTY=u$_TQ2va$*RheX&thwi!7iflww8Z_Q1!rr|CFNP%*^d z`7O}mh#Hm^bU$jJIEsNGOeMZ zy`crJXd0%-aE|)2dmFLGpW~6EFjvz4HRE}HL7$qwlispGSAQ7#L!R+kLq)=7$P*^D zxj4T*dh#6%L5E0oJ>4G~1&n^`9giRVdcKZ-W-sK)XtUE^wJ%tUN2Zhh#gb=Yli-1S zA3$YYm(r{q0jy_A0&jGMXS-1YcHe3{>N8()&;%%^LhZb7p_;VMAjrfx#DMkIbBqG zr9VN6i07r@PDaJB9hd@`0?YsNkc@#rKAK$Ko4T^Y0RhE7Xc&Yj=v8R}itlT=DVhyC zYvC)s1K=IAFN>3+=aiHTSakj5-mCJuH*zgGsp4?Lt(qZmHM4PbVFgBQXW{1O40{1X z2eVXzR_G-t!+4Ari~t!dP8M5tf`G06@Qsspqcxj7C%DAiW~JB~CjjQZq)b61sFk-C z*Nw=W$yhD9KHZ!2%d;@`Nt^oP#W2e}3>6;POY2ANC^=fRjFG&F&FsCP@ ze@5dm&vO}bsn6^uRVITpLWDjQ(=*$@?4x4guO)aYdO6Qp8zVW)V!JHh`T?*L$8Kv) zp^_x_Vh-o4W#=E0U;la=NL+zJ*Es1eez9D2$?cx!Yt`H<>!6%xrE0|1221C1EYcX} zPFPR0^$xY;UR~z{nx!ms`IlfVqaxqzpA2XKia$PT&Dx@?d~h()gR2=Xp(p#h_96)m zO0~wHE_1Vs$%&dl%o)=l9+AU}S~aKy9WWZJ#W-rABWl&hR} zUpn{5XMDL+7J8Z5Oq1#jfo}=~fHUpn)frVdNlEw?-?NbDhO*q{=w@XoBd4rarU2g@ zwWOmo_A*~30x30bD%~Gbs04z1P%er{(;*g}bm1}j_$nzGr*eFMC!PL&)gWX<4v|J; zQS$XJDTDKbEte)JN{%H?K{RZW#>74bmJNq7EkkK?d=!>w9 zb4wX9-W!r@?fF+2p{4TCWL}*f{ST?TqX|xOcNr=yV&bV$KMs-!p4?8>s~@-*+*fTS zvF=(0P~mMaso%ejXPROaAK5NBjjYKqew^E7}0@o5qmad7=M$=)W$eteKEm zTPVSK8;`Z(BgzrmSi;B{8cxaWdRpeMXX+{KXl~ zv24u!Axs?~{Vx(F8lm)v6z{UBMqj(nNd{C@274*#<rZ+hy`#h->oVtm5s8pU+iqIGxd+_*FXsOgb&-EaF8!pDQQwMa{9=I4I z*e;uo#$dxjHw(=j&PF$2IB=R0yBxlKLI_tosT0?55NWESPKAE6FBLc_ENNj+zMYBy z3&>zsd@M6_phyxAa7@~w=pkn9m{I_ximN92*$$6iJ$m|yH+R{Q<(fUT!Z(U~9&R3r zhQVw-$1%0NS5`Ea@#ncN_lw~v5U7yGD@*obIvshY>I(GQr*t(f;*^f^Y?5<*f^!Jy zwB~|G;#R;?F4scWPvIg9DF5^=V9U;}Axee(Q^lbW38(=)iOmzoy6 zjipK+ml^bwCJS~H5(|5ML_o*P70$YgxR=d{KvvY)C9q8^e2>8Rf(dgzW8qp;XOvY=bIFJ>E63)|b+KJ+b zlj-3?1Y@H`w`li|)JRaltpzE% zhHZTo;dOM@O$Fd7C<*1us(m)ks3+59zReEA6?6$P;dCv?%cDM~ezCbh1M>Zt!uvP& z7}~cDvlj^X&cJ(Jq`wZE<#tan8!?jZFusMxpO(4nE-OtP4W5mYV%pn66Y&4llSAG# z`m^ol85dQu#lMR|O5o3E%1N9&^5(PLFB1v(lUQ%JsXZ$%S9A@g%J!_+8pbrpHKeiD z9*RvLi_x@BjIhfWGaU!nsKP8$snu_P|2N`Y@68LO_#ZrXV%&fcNGo{%3aVaX{88{; zGc(x*V=8|@ekXaSvsEU=LLNkik9Jyy7I(;{s{BV4B{*Vlb~FAw-h${L4)8-NfNlXT zX@GRr;Y)lJS8-@dG-)%#Gtn+f%Fc+TZbn6T$Z2iexIT*Q{iZg(=oBG?;axIau2@YpkGWTO)dH-kBcr^*2COsK zy^F9e1b<|6UUr1{K)l6~fr);Lu<5U#H3L#6FRS!>CG|BgT~@ zzL6}RC|CZ?xT34Ihq#n<#VjIheLADfQL&W`di^O#;d*A4P)CSi@67_jt9jyDPV9Nc zRU|eA2wCjawFQTzELgsCy&=Z zrBJ1%DHIgLhhqH_2XEZ*0MLY0iiKKa!Zxm+f26$^^$(D>3>Am2Zv}@7!cx1>dGmHA ztm8|Ag&_Yb=<V#qAs`Qx zOo%JG)dMdKe9B0ZzG9S3QBSZNUayo+^!tK&Q#}lY<+9Z>6g=kO++u|plS@KUs<7EW ztye3Gen#17?$KXq@$aB`#A6;Kjbc$ez;(~~yRirmVWuFXk(s0B+jxQ)Z5g};2Q8hS z>MKm;YBluUYUidJV-<{URbB!{c~H}FOrHprBBzIjor zaniU7G%z!c1^m~nT*FzD?wib8-Z_OW-!p2New0OmrSB!?86iX7~hdsi0AKA#gyJ5da%t{BWL$)u#xnrDr zha4fu0^C*#_NT25!aPURP!jg{l8TbPyM-lu{3B$UWY)fChG4`!OxuB3LfY^p;*rqa zoU;#wGX1IDzpl?PjFM-dMOOV4h|heLmv*aAfjUfB4;mcS2>#CJ9dR4}w%X%5zo1q4X@1nGJMKtwgdoGppV2XQFV|2dWx-Hm~)sQ{t}hU8?;|MSW*b>7x(Xb&Cw0^OP>;(|?k9#!n=p$9y*r=Y5;MIMxt0isonW?7GWGpX zuc=5<2XwNCd+|yCNE~sU($gWHoi?*x;ISawT&3Ym-(=!X04jeilS8^?4dtjQ$DiGHuFSX-W|%(Kf!pdpPTra30_6o06Y)Je>8S_ zJLXO0YM;GGTBsSDyrcd^wNyh1QrlZGLO4J@O1E)3%?ZetejABkAPI8QJ16(HxS;($ zUT)MUldF#tQ7ot`OGMbWx9mN?h$*v*0=;qxQ2un227S4nAfps>ec8UslKRf^?I)Sz zvT*FnKgSYrO_jFM@JjNB-MkVU>67%95mWm=)VLk&7{SltVcwuEl*3poCV=Yaz}F%z zQ=e@-X2fcIsU(mgkxrH;9*O%YPfD`-#wPuTZsXw*XP@#+fQ$4E%Yb54>Gt-hgvaQ`*vGz2C(o)w{{=lR1940PZ!h{$yolExm=HY!fYkqXrAJjNBLaBXD zWDe%jS$1a5R%*7&I2bZ>7X}tQlYZk;fG|)}C|_PY0(U=h_OJdLt6U;lu;AUd^`GNu zG8kPgma=FM>EV)ev?$@_lQ(OFB(5*QIbQ%!@eLA2_+}`*s6x;gqC6|nBFdW+1t=D{ z^nG128}M-#icf8eAruCs1ri_{D;)=AtsBe4 zT~k+-ZB798$5nUsz5V@}IJ6>M^i;qW5;{dJ64sF-Car3-h9c|V+DnHj;PYt}ljBU_ zo3uPG?7eV$_4BVrYPbD(A2B5zgl6)QnKv+0Lzr+=R>F6SiTIH7NbxMC;W2=vpoe#= zs7Pt)>4T4txZEf%eA0FUYCe_mG`aXSXi9`S^upz|^QwT;`%X7R_M3?u-MGCF)x{Mb-Wy5 z`EHf>Ej2ll9VXq*hai!NtC7!GBJZI!rp`2o{6+rB6!t{%aaaggZ~8}ZQHzWL=&MSC z-u;n-2}S8?^71idRcudltOH*MIG5wUSB)1!zq&3D|%y{(%B6=WkUh`@hhNj6!jMJnz=g z;}VU&{D@s%mP&5Q%c#1l)3_6N`745S7f^O3 zv}E>J*2%pRn%;rk#2FlzB`7`5@JUi7UQbpn2?;IHE05CC&rB)7k&aQ-YZOT8m3_3b z<(`nQblvwl`34)m&vHf2ZG;Z;m(_C}{7%(@@keh6In5^Nz45W4+% zqZayeR6GtpQOYhTwO8?rGmoNhtXTCXA-Z;28f3jyR-~=u6!K^>72Bp+FeO<2__6?}6c(9G zM0UMchVgwPa+hD5q60vYF#K3$Fbig?O2#~?6i==-VOO<(NY2lR2jdUhyE|$yN_(@t0Z!1qI!3QQjG%W@}n_B`jI+YCoP>u&cc@M*>%l)M1O~E3#O8| zz0PpwDR@+1seKiLngshb)w4A|@V_^U_IcykvnJyo9}Dhl#(kl`Y-e8i{Bmq;jnz8g zgWQ*F*&Mq6g6#{(-2`}dR%8y@tT@)h{}1vXW3hu9ywsG`Kl3l9EPF;yKOa{q$)6rI z{WVeo*fW&;KE){F<{Q7465Yh1=l>Jz$tcL7m?w>f&Y{>B+=2{P!mP+el{nr{u3rem z!d4XWyCr?Gxw7tZxrI;)`4NJZ?BK+O8j-uZI#o3-b_|u7xtYTgU&6b6Yx}Q!Z$87W zy;q^I>bAon#B7W_<7S97cFk|EchUqX^4#?DKiV7j|NKy{-7L4w`RT^h6$-A-Y=3akSKE6zu9^3UR-G~Sw(DJIR$nnfF7*Vn)kPPvFaJ!olHk~=FbH3i^omk0j z=Ik_cw)}qF)R3_vchq8d!{^Z17IkyW1!_h%;s;&zmsukcPv>lR<(C|Lr{oRBf9;DT zruds&RmvH(C*D^fPFx12?^Df6`2<_U=>f+4XUj;6Ed}$Q*6D_3s)uIQkXn$hdB>2; z+eI4&a7P1${T*>h06k3oWY1?Kh25IW#8lvO7`A=J?dy3}^90nl_fIlCdYhniwCSnTUs>kUtd^yOZ>NthU$(3&#Dxe78W>BDP{Or+ryAvOtHOJ{%qLVJPuH3r@%4A@!rD4 zg^c&7!3%mMYHVy&EPpkKHcExOKzW{#P{CI_ANRi2cA zZI+6{`cM2!@Ap|V0z)YqB=}Dq*cU6mZp!f=GOWOLa;p+}G=+~7XW(+;917DgSy#%2 zR{gN4AeH)S_+PLsN6NOrJ|mq4A;IfOB;OY2{?!lRZWEHS`@4NFlK&VtZ*FE-^9Zw& zuk=)M$M3H6w$HVn?t>;7i!3`0I#Us^HvW%hs%YmGu$l zp6q`k>n+2gjJvNH0XC8V1{0R;u5L%Kn_ySqa|L`1pW!=f%yQ}%r)HC@80*`YpuQ3=HwY)uGfR-lFxa0MqakOEb)(&jhD~;jTBam zVp-^`=2sK$ZdeqR2X;!fWgG9-Xqs;8xbNS++T~tk3&Fs5LhlH~`ykO1!?8M$xPgd; zA=D6;hL0*a624S#qob9Au~hg`hznwEMPK8a*iPh2^IP&rNddBl~x z=9i2N4aIzrH@JDW3fk0i-y)Ah$9X$kia4s}-nf2TWk#GRN<;|}(8*-u1b33*Su_~A znuUyG=ry|&u6V*0PoWP(hMj~D9l>+;z5$wcYQ!1I!TDdt#bo>@rC!0iXnG0*Qx2LA zWT*7N#JaNU@}lUUJ4o4XtehYU!5%R!vG~=3abJlbh|d zEb;hk^%wC&>nN`5`ry6fPv!RppS``$EfZGFUALtA&*fTm(XJ@YUx>_v>x1;IBZz8c1zvL}@`iaHz+V61N+TSK%U?yNN<7(sk z#J^S|>IPLcHU{kE`qRZroV|X@&9yPwd?dG6VbULW*mzzc>U1#hLG1L9{p1#2Y3f>DWkU^MXo&lh@TNK)<9h(@;x><{ zE!(Z@at5IO&S<1~2aHj)Ya?C63pk#w^@BnJ35MHbtT#atHZ_4u3J09m{@7` zY=1(H7-14=a5_=DVG;@cUrTmo@|4SY=J;@ZPE_~d9^k&72q0>%gkm~7;~&`GFm@9jRM!a3c8g$&@l6fsiFbv zzUCuW!g~$5M+1zVX9G)nmSeCntJS(ruZAJr=tZ;fi#9Grh zurFaPH##;t6XR)ISJ_G)^z>4ulw9bwvww~Ks}%A7j9R0qy%#nz=LFNwxSY+0W2;tQCcw?=aks z=0eRoaJk>)RSt2_rU};Mu{{6z#KZ<6x*~E~_Y8UCPuD zc3sC&r4tX?=#O770PLQ_SFRb-($aY?(PR>&$Z>lZtjCq!k2JL3>))w8?x&w*w_keC zJ?=~YAmzbB$FNRdVvJ+bOiy>Zi0wx7F~hosE5+h{k@mf9)Rp~^Kd6h9(%Q3%;(3bJ ziT4MMBwv|R0yu-CE@uK$KWus1%Z^j#%EjsLJ$f`@r)9mG8Z%$eQ=cYJEfAL%#|*P_ zC8y;7mj2AObE_)UH{a$_X6}8wxj4y)v4iW==Cs@Wx*s;~?Oz(g{f4SxP#5>g%Cup` zab0fHm367t-IPV)z;9Lo!5}}|xA4T%w5ie1nEF5P<_hvMI>^*fdZM%LPtl+S;)?oK zRl3vAfL7N(RT7*lO(~Y~o&GlAJ08!X@RrSKp>-nJKh#msinX0$NbT^Ce!Mgu<`Peb z(e69brqX7nPT1*I@?A9<(!Usv|DL&NBEe>4W)_-En&kQE-NNMaiK|HVm!SbT3?O53 zP*qJ$(0%1WKa}1ZZ)fz?>QOT+j?iay%*fszt6|BRf913TJpHnnnJ9p zsa0Lq5>;z4wiXLD=suf#akcCyZf;=#GUWunV?pG+`;KJ;Y$AOv{o`zJ9?;n#_u!EB z8xHYr+OEsM^Yse<)8bb!@!;i8o{)fh?)D(qKHtR30x|F58Ok4|5LB)!VQGPLxCXS%az! zJuHJV0wP!ef;B?(1}ZgZ3`%F%CP-(QsGrg@GJr1xKYK7}8Dv@{Hpi)vnPtu+g%it? zvHF8fI;o;cS%k0$sOd^I0WsgEQ@+q=;V^-bKU`QOR_lj125LA^rS}u0@ELc#QvET& z>xmw%KpcRE!F5iV{5{885u{{wr)T+Z?}VMH-PCHUaylVpCh$kjTeBZUDw70^BprM@ zYJA5z0>vrO8FM-x6GVC?vImwyxPZLSXb9Hkn! zeo~(>`#*#`?JT>Snt4(JpK)hX?>Tb!v=L)X6S%a69Vf;V*n&r26)exF}shnSPn88J7C- ze&gzEk)1wAph)eztWcfVBVEbqdtK2edmEdH_q!DnlgA$M@}p@s?U0otUE6Oni_kW| zi@{Tu>Vk>}WE$8xdDF(4-ac$0tm#0;=zemC5J?5Kh%c)2{abfybvOg?Yg%H-F_pu& zn`}9BwHf8bu?87s@wS>{9ANlwkK?Cri*zf6COD2(gnk*j`i@>p{~i!rZNKDc?q0a7 z)^Di2h1=LMQ1^7oTwYB}9J)mHLoTy2BT(os1hjG0(+IiajuB5Nql z$|0lykTvgblqeBI4lNH@xrk8`VejpiE6BF+s^eSgaRF4tc-qc8NO|K!6TGUiB_{LF z=Yx3{eEY^V1t9OK9O#+)N;Ha{c2A6R^o4`}bb^o-uyEiGw`J~V2)LPvO8>A*30M<% zj5zgx(QsU9W%05eq%K`+12?|sHcLd{*hOj6#e$gGmBx{Zn@0z>+aC#P%$0*sCVvn! z<&t1xq(y&Q!ssPzQHY4Y`2i*DfqqJ=3lu(PliXYp{6(dL0Fk&I%mp$l#;ub0UvP-s zY)(M{(fSCpF+9}S&| z-*dcOXI>|L4puL~%L?FfsTFRh3hGvjTbn!G(55Okvj0g#SO#>M0PhBbcV@9U1|{y_ zlTBW~QQ8jlkhXkmiu)Rq)hG|+4iwkhLVO3EA=wAoNZVQTg8@AafupK|$@|4~q;l4s z?Cta==A;}ws%203Z>gle+swSDKRr}viu+a2F!yA)Bay3uERp)^{a7WYp6I7y~j9*~UfM&WMGB5=_H}dnt;wKp`bkj~JR{rMR z4^+FRoMTFp{XvylA${q0_3p&t8yUYW-c>CKUECNL&{taC9<-@v2y@#wg8P1ucQ4Ri zR;H^EbULBvt6w(p*Y*SkINnZNHjD>G;Nb?l%<>gQnn zZTO`%BKhK-X*s+`=;`hD(a)T(uZ^}HZN*zY_urBIJQhh{MTcfum)cs92)060Y~mk@(OX(x#=-RJgFFS3 z-lXz00f`Ll!Y^^fJH%^>Y9x~k^JodMwBt}85$%s!2>Qo0$xLV74}_0s7Go8_xccna7b<${kC1#2@_;tOBG(vjb# zb|HEn)NPAU$bIq6(o^|oQgh-Dx|+YvF9*HsLOyeq@|P^S&ZmagJIY?*U&=@)xV8}t z&oZvJc#6P^g#P$8{FI2YE618jJx?scpm08HjM4A9vmOWbZ+3N$W`9n~XoO8`s@Bv3 zUTA9H&g~B4eZmC1^@h`?3y+4NUy=J))0MG%(4W)H+Vs8bQ@WL7VSj6h?l|cauGP4nu^@*{Z<#;b zifGTPRZ9}Q-P-y?SP%@^cha-zZ1hSsi6%W)hl{6^Pr28~A1}GrnCb5^sH`2QVujY1 zk3HERCeN%oMsRYd`jz+9BEVt;fi@!88^fYdi% zGJsd!j<@B%@kGbX!TV7VKq?|1R&n+rDxG1)_N(7n8B*Tz6d^`KK z1M}}#*Fp{C6&%~~F>N!yp-KTyq_Nd%fLHD731?;b zkp}(Mc8w`wP*1O^k~1Q25UFG^<)Ld!)cRfgk#+sNdXh3&KwVsH_5cm#z=clt6s!>M z;+coLUKkScVbO$#!elJYE`wf)ieuuhT{QQr*MGYSCGQ;dcZK6j)%~9Cr6}J%p z(ukY}VK8iNc^YoBu!?!F@P*xp@vEMkpv}sg#Sih%KV6$$itF6#O=;OXFyHQT+03+m zuD&*P5LD`iHmv4wWwp2}X*AGg}H%Kgzs_;DHKw+z&YU z>~7?By0<;3gn&*p{P+4#{2%=v#FzZ~V;k4{;8m`}Vqx8kSiu1yI6uhpBYxsi;QiBR ztY?XP^9V_XONDeY5k(R&%}W`>*{^(C54lUn6c!Kp1tU#x$P{&@?f!&>1nrosWF{*AiLd1wn>ryGT;AJLIo03RHr=8 zM7KD{{sDf|LMg7PVp8q}Y%IQp*PGVHz#GJ4p>E?QuD^-$#@CZvB;2O$;J#d?!^k1Q zAUj?7?`ykE-;2Sk!^(7>M+N%dg|lYYHf%G{CLtXdd!bqKFEjR;`P-(JisNLssN~EW zt|o^(c-wwWTa#C_1B?%>*6L8rcPX1G;OBes?a)U5(o|gg9#C8C>8cqf4?$%g9SRJ+ zMlJB*X5zkOirc?UC((YBo3<`rpXsHmP4cRkGuuLzZ{A;iJ|bxvl)y>S?iff_Fk1>4 z0!)HupD%v=qj;dvQ@2p zc>>poLW;J`dU|l#V@TDRSlWDFm?f04rhq_FDdPb8(Ys^VV^i4{CJsI5TwL+vCL8_M z+u4l`49_uZBOoD|Gr!yMe6Y*T=o;d5Bf_o+@Y@ZTunghS-FBK%5!wKLDeQM33=j=Q z!W1U3HaM@4P`Dt(T==SN;q)D3eC2f*h(}bkBma+wg{h4^^n30lt125)%mUeP;fKq6 z>$cJjZ=qKc)95G#R>IO49#n~6RU1Fd<|*lBu55V>?Qs;T92xTUY^LdO_p@#Ky&1^D zAq71LPRL2C84g7~QFuH}@7Wn2ozJ!C>AC-w#p$Sf3%V|3#8{Zdh{sZyiD>frNdRdg zi2)184+g?h`J_!8vohR}0Wia+hY>%sq(F7Br5P4k3?;3KHgV_}=_70bg<^W9EY z?4g|f? z$R0mH>`^;*xB22Eb^@m%Wg_pS3uTkKiM2^b>nrtLMyp62w#TL((iw!T?cPqtIN zlX&_%36E_cBbhCeYeO!d+SmJ+G~x)njm2wW4&LV1ET#bhRB<$t#Y?iQhJwX5LyhAr3onU0JxciCfVbybjr4Y*|C3wxN4W~x4)^!14{GvdHFPwrxc8+u<6{9H%{U)-O=gAx}mDwBlqEFLV8Vpbtk$H0c*J~sBB7yfJ=?O4OQIIKz&_phl+wU^upv8KgTn-2ya9lEuMB@zC3jNEdcoMcIaon(Qroz5`-I#QYAp@A5G+ zct~+v&iUtR?C2Vnokc!7xW?QVs5kI70Q<~WD;*DS8-hqu5Z`Cbw+oDzQ zf7i>D*sK3tFBg1&L!dRKv#@LJ_?B|nF}~kB_LHVr@ARP!Fm^&y*~9pz_$E936)j1t z#UbnV**Kk*NvImkRL57}0$GntYw|6xwYRxc@%~i-KD6~zDIebNNpaiVqfb3x@t?k* zw!6*vxT0wHXg+5vy2JPVY5A+}6#1WvZch8P`bw`|CE?P9LG@oNpL)w(ewcB+-F(wJ z`mTv9@HPqi$8@RT<+>~FwyqN`-#g_9iD40pw&^*E{fCd%HJqPiHhz3k2umAw{_}CV z>7#A^}0_NvG+X9Be z*USFgZbwUzZUSBZn2qrQ<_Hd^_n>BQ67AeY;6V&=_$$=&Bpe3KjaG^|k$NPgEcoTF z{Wr=FFPgm^N;_|Pt%FchQr-jO^BdLi{9EB_nV~^}j_ck)7MCCv9)`9&9O)w`j?FJP zM7ZUCVU8wJ;G)W_bi;JI20b}WGB>%NX! zAP0AWo}e0!=UZXr2uNei#Oc(PGWWOvp%8r`f(mujshbS8gs4(V`5o8yfx^aEj0L>7 zVw4LvA_-*Pe}ZE{*mrwC!y&?Y9U zCgh4CMA)AvW-kiLmqD1Xm_6(#KnlEPUYKM0@5)&|;pVeB@{zA^a<-7+l-Ti7#a6wc zGOoAdoxG&M1+VBT5m}NHU>dU&vp?}Udn&y`9azR(va!*Zv-qVP-RC9CWbG3$6~&3S zb|N;V*)l3_Fo=hSKp3}_P8UqPfF)tiH0RHtN}2@HrpK&1qf5)xAwlIpAtJJ~_S8&f zQISR?Mt*2gOgh(*TbJWk2?nub+T(1gU=N0Mo=vpbo_Wg5wy~|Qm2mezC2oI%;q+y5 zYV=tsV6{)fZmQ-?kle#feHyEmbn?`9WkBuzBR7GDnUED!VXtjB^*(xjr|3Jsq!#0) z&sVzos`E5CXqUYH4*A>4e;OCP0^7SH?sh7zMKZ3u3+<<+k18^UHT8NQhG$-tz`f{7 zieEOsa9oiR_oEb-t#(N@!&}_m4n>gZsRhNfa=JK|l{wcaq+fB}G=HO^l{(X7 zu4a}(`+m1y6_)Ygp~TqohoM$DM$MK-@-1i4*&1cK72@qgK~18+GdZ@QD1etsV3+0g z*&*H5TaW#uSTuR96-9V)bhXjegr66!bpSmJ8g_9=$DpLJR1i9|NsPx<(LEwr@`gAp z7&R+{r`;@|{f^upt=aupA*P&V*b=pl0i~M_#j@IF=hfXz`z=3?C9jZV4}*ZmW~pKK zl$vCJpv~>mw$(O~)wjgi1KbVP0op60ou9 zssT`Wu{!+MF#92Ns~*3pT~qX(rAEBGukqIHZfWW8{=Ed-&G4U~z3e$JRKVT(g$+G< zukcj9VGRN&{aE^rM6Tl~^`z}pn$c9w-%-Xs;Ay#rL9g3@ zresO=$6vV&9!6c!&wzKj5Qy$^Uk{yt5C#7ngh(BX;BuY0lg;;G7|4>`dlQu)r(eI< zXyE{peGv$hvC95RleO9%m&`uT){82z7x;WU_W4X8387^YsviglTSxut7-7zX5jg%c zL=ctqUkc!Be2{RU{OF^M6mz6Bn($ud2!jz269#-Y>Xn;Oqtv!pRBg{@?sGJKb|MO!4M0^yIdslJ-P_(M2$OfQFl7N!!smfz|4 zvlC#``T1o-q`Tq8xR#OQY(}5d?Jd{k+O*8W!$2r#z<6c12r&kQMcB!RDl2hS>Z(R1 zoI3`g#dEN`CT!BF;P@PXhHJPBmkilMfEpt}0jhKbvHRf2QKDao zA=D<>aYd8@mSN}u{I&T2QY_*mM?wV(8u@_oYY@&%1XAx}Kv6*nV&TGVdKn4&B~39B zki}?%0VvcJA``~*<)wy21Oj@%2Kkk^j0^(!XsjTnEGY_sKv+0#K?|0WNqkBYOZ7O* zs~nWn9qpvg1CR?8Km|mNk{=NgGNA?Hi{!3 zl7RReN55#JEcHE%WCf#Zq^k2Be}@!oae`Ux0vmim{2YbXStkB2Xg~+N!q2o`pMwOy z=-;{#FU$vP_cSt83{GbKx*qEMr`ACq7__q+8a!T4GK~D)Khv)>yW=&#N}j1>{bs?O z-;Uj>;6g94>@|lLQS15FKxmMQG5Ds>`)=+qyS5D=14O-Eb-q#K10vo2CB-ER-Zkkw z9d4E-89a{o6mK<0eqaBEc4uF<(vzE#T4EI17eB&DbDr5FP$!X>S*jsW;DeK&m%959 zx+=5p{C|MZ{|I_4f-}bAg}*Q!r@YAi6}$;G-Xb?NZrhP>GG&k*KT^omCOf{FC|R^qBAAftz9L za>G_K#6}#lLdWFmWwZZav;5li(RDHQeM9;6p^dzuzw0-yTGwB9>hSW0Pd{f%2)$qI zPZdo=F6T8GN*A?7Y&4eBiz-Ty<9tPQW1rlzeBtlaNWI9$dbg9f60E-2cHwYV{DlX< zBT=I;=A3n^)EicH_Rn*5{oLA4R)42+Khq62d-^`}lCYq65tyTs!> zr6jMfZF9ZShZv5;Xea?}ybL`Md43ubVVdOv>xK#i!8V8)b_@bL`mv=2 z7KNk;7)P?iRDYk!@kT9a{%m8=ti(j3oD(J6SLUbKrl#qHI|99Dz{MBfka~x+PclJ| zs}xA$Rn`~r!8TF7t11(~%4weCRXs7{;g9aTqfuZqB1Kc5LYYRxs(B8E9p%}Tk zQueFmNKFX<(beSaArXZws0-rypbFvE!Alfwk>C^(r4SjICJ5hqoBcxFK1+WQPo$}HIrX;}=%MM`;x&y9^eLsD_-NXG^7yNn{t&B^#{UFP^2Fai43*?#?; zuzjp^r-04LIWea$NFZ53I20dx15ck$E4UZg`!%3Y)B3?l? zs*42E&oFkzDS4?%)_JKb`y_e8%nr1v!&m7CU|GSHVZfA>{~dT0N8mg&x< zhVR48wgqjcv)0pP-Rz^1)4zNQK;5(OwLQ9Q@vE;wPVEbJ-$2}RIP>sX#dyGb&mR+? zHd%S?b{USj-MUxky-SK~3!hzlEmQN#i%n$o1I-xsZ~j{dkE zJdUeF;gY9{h`VCR*vvK1H4G_^h@^jv&RB*#v(v-;z${If)5EMpon#oeB_Vsgs6nNz za7SIHf6GZTAUiq6Q+>mMxaKQRO-Al`v!b3rUKfXy52j2N|A=WYImDz>sk7u&Q&pfMtReuu2~2!S*fHvRPMGtKFu^ldW5JU?t4a0 zIvZ2*!qgj=fw-TOX|Z&rrVba2+1c8nFBbbC$SVM<9JctdZ?W8v7aB|X8@b&HpBu0Z z(P;-%hwyMNe-h^+yi!Q_5mcjQmYH6V0v9{n0@3+O9G^c1V;w;@tJF4)f!&p{Ahe$d6RLN^Iv|P}c0%Y%pSwiT(VFa*v%39;$LV&s6bi3sCU9T&CA4qZV;dP64G?}7sLcY#@1>f= z;5EI@IyeNOZJUQ#Qng(-X-`k_5vi~-;&N*$a3%BzPNqb7wQ~#-_3R8>7XT@<9H?2- zvi+6ka!H#X>@|sTSR@#L){ZeO>8si45*k6<>6={tBTq5pfs4m&Gxz#naUP)BZ;R3> zP6H{1@Zik75sLpa&xpkU47@LbNTua0O=YI=PA=T@I)Thsj`wIQj}PIFe~*?eb-^++ zt38Yy1(*rXjaad0L_NtIXvD&_3_NMaB(9lqy|3hfuryAOnVUdu!z8E=!X})Mg{;L zz*cT=uFduOtmtuvkvUc=Cm;bxciNt2ipvv@CSf04ogU=Z*0W7CK`ZDr>HrIw3=gs; z;8d#!JKYHzc;CCWJlq=R2s=@wP~l;R{KU09^IF58#BfwkSbM3?(j&Nj(8U)=BObM5 z;DKv+J0;os4-fEJkC%vb@JE7wko`vkkH%qa=84O$`VB)0k=xLU57n#1#?9F@7NA09 z0NNa$oK7R*U<&j&I`O!FQRF*qNSa))v;Wa7c&ravoU9LHJKjz+k&RUZg>@_ek4qMT zq@^I@VrvzSKq`no4+X#hqqC^SIbX~kLG%+?XEJpeQd3 zBKG);sT%j)!9PJ_F2w&;JyK2x6PrKl?`n1=o&x0_d#YD(5t^CliigB$7%<+dJTOeSf{(5EMni1bl|O6f34NNaN+biZW!p2=f!sXX$?8Gk9!eb z22OWgbDr?(-0RlcxW&u5(!Hr#B0$%k^HdSm%=~|&v)UK;2!LP|J6)=6+<=Jkit;D> z4+=0#D{QrT6I=zbz>UQ3?0#UNDZ*1w2<$u0A|w1~UWXfJgwU&JMW9m!-E>F^FbDFG zpsD7HhPOWwKIq;pR6bBa{yKE3-S@y5v=p;w5xv+0bvALl}i02D4* zfALgv-$aJ5JWA7ueWenGIP@l(DxMCG`4CH9SkP@67GwI~2!@w#8VOCLjf~YOgA|Wc z1aWA30&mH?Sl`De`JHN&gsIff7v(XyeU+%2IMic{6;>^u%h`;_Dv5kWi#678Q~$ZX zQ{eFZb!E)F2IRcrlu%$o@wFRoeT){|S|s{#u|_kq-i6rr%z@~3$-StGZgGDvtM1)w z@XSmD&Bumv#d!R*gMKrf{zb%W{|MTHy$?P7kfFHe$|cB z_xf)8@+FJOIq$jgSfwkT6&dG^MotGMzk%Vo_9x@%P7N5?!e8At;X2!W(i*J)n1?&K z2`PMmN?YK(_$7GssVFCq?6-1iWTx0J;NrX3sb}$5k1l-EVHhX)BST zZ)IIa$y6~bBD=C)c9lTq4>#wYq=2>o_L$B`*ulHtiC?L5q*4?ot*VgM3Uc#|@7o&Q zaxjJjq!2GaFgw6xCQ%V~>v9w~T{%6(fhV z-e+Rh2elr1H{_@LoY;=5GxtD6Vin9}~ve_XxXkMdQ^68dX@*dMi zv>khMUmdMP3R_p#G!3=UOiuGNLyZ`;BTM7ZQlZ9-k$#Ah;w*=58d_bx<{4v8gkR-m?;nr_%T@A6jLTG3J# zT{$EK>--$poHV05_JX#0oP4`p8x^(hqHS1?;X1DcIv?QpZcXoC4~zb2 z<1f?5(jDzj1?-zQ2*eO8?#9p~T0qD~s!AgnR8;ioWn~!?1Xsnf3YoR+aoyZbPVey; z+;|9~1_4)+teoXu*mGTg?q-1*(F%Ly3F{VF^4N&=SfxGgz?MY#>9xBP5?k1<{b7^A z!Ot>}=hCb(s-ZnN7@N@au@u|!09XVR_oGlGpzBNQ4(AnWr*&WP6e6H~6N6q! z+jHO;;Z_%vy7g?yZP5-P`Z&YAS_yc2M(a1b8S(u43Z!UQDku?-s~wC!=eqG5x-cJ_ z%62~xyIO8nX6;jLJKY{KDGC55I&8ez&OWj5-$kC}UW*05uaCMQH;f?W^$khz|YYY4hO1RS=mcdVG5)Et8a~av)PXKD>eX+DG_ij zd0}9?+!UG|AaFLSxPGIGVv=$#esCH%up^T6g~PdG)l?>)T7`;*-9p0gw`nYiAB~5r zq#qDmuj>P+hV>oXxg9h=n2Vish@J#XA}kyq(P6<{x;p_q{XC38Ogv2aDn8EJQ|2bH z_h=pctl25!D8gR5JP!!|yj}}QWWTWQK8Ahsz1!WA;f<%*#Y6bn=_os;Z+lrzcp`D0 zVdv*J9*2&T%q)KK%2>VqQ3xqmvU(ohS>O98ie3zBtVZ*GvJpaR3GY3yLc-Jn>;F3^ zeB;cs;_geg;T3T}tC*`d9m~)vOVlFV@8Z}=cP6 zW`G^a^wzYq;k6?(!vCNb3m3gc=oz?@1^%IJmQ(Fsc}v&<^~)f9XzVzC3(d1)Zp7Ox z+X~(Li+xS&#=GDznaH#MMq6^CpP~Y%R`}}yh1>B;EI`t^CV8J=E7Qn*SO9@Lf|Z;Z z!r0oMm%D(12R1u`X-L^!&uGh-mhWFG2aBjP0a8II0exrq!%3mX)u2VSUH|L3dZf9} z7$8{y?u(ugN38BOQ1BY)uTj8H%6uy-U{)L#h~O=-Q{)Q+w>u7*g%i?uN+K;DNuFb1 zuq?TbEh9wzciMYiLl1ayB`-AaXP6hK1D*pUjK>jBM`9J*L%DPtR(q;tJr);_dV>ku zp7M92E~NQ?`b_V8wM*k@q|c!`!|mptzpiz0`$_rhEBOSa;KLZbq$nCO(`_!!O(_bb zvH2`#pv|(5!Y7UOXG!$mbtO4pzb!F3I7%sbRg%6pGSe#BWY1`c*93$JvK^iZr70r`|XpC%*WZ;Ug{nDXq4 zf!LArP_OB^8t|e%8&u_&cEivyrea!)`%k_{@eVF?SHGtwA-d93J_PwHAwXR~A^xQ*m4t#& z4N4ky-sU$*=@e9vA`uQ$Bthijt_HZ^S3&>a2TCzkW!bvmYC^rUQkY<(7|ke+&$7Re zzZGHExWXMK21bW)%Pdvpp=jmT`1)U7V&unirD-WzGUD=!suGDLRfEQ|<3y3*9Zd{Hc#xkG&CeABmsFC~$f_^lF{#sreJMBNyA_$9&IR5VM8x z8@(2WJ%RVwj=S|xr-N}K8c}Cb_BfjU>TX4+%~c{A5f4yh%LTE4=N_xr&0+uPbTX{- z5_-_*z2Zv0y|WGMaYUssMWBW8*9v>Pq2}Ecj;*`|{i(K| zUI#w%${1M6;Emz}BJHsXI_F(1PD020f$cBdM@sJ27WztBk7tU6blu|au+VJ#m2jz? zGT=5=!nMSb?ZFVcxtKx}8Qwngx!cI=U^cv`qC+lh2s@vE;^^N*xS3%>4ZQJ>+K`6` z7s)$Q6f}cne-sqZxDg0TTU!{I#MIURhNBx;vFkk;dC5*gi^s#yAHD&AN!NbYgeSV~ z=iZ33box&BJWn$2b{~}fxZIwudHEcX+JFs3wbfO4<;Eq{u-m4xJ&dG3&NSnna#3`9 z$3i$V{$~|#&hzz9a>G7)zg=d;H`whM5PYTN}+nvZetla56EATOo_ z{d{m*-6N78u#Cuhe4PcFv; z4C?`V5vP2STql$oJLdxd9)|3w6HvS-IZNRFlHj!BgB^_bI2n1ACUXNw!#>IPl7?7f zYyH^?!}S?CrFo^MdwR5*2G!mFWwnRMhP^}R(dxl7o7ee&w->@1Rz{eFxIF3pkO9;Z?aQz{T zN__T1nnwMVG}Ybk%tuVmUwSt(RC{?n($C~jQ;4%bCwG8YsGI&4!$8szXAxo;&i|Av z*K6O(XJ?QdIO$`nJ(0;uINI9UJ!fZ607Y|fx}hg#X(16HGYC}Z6QQzNkAF~O`}dB! zGw#PH0OU!8wuXM}kK=z+4EV!C>{C%7r!4GEV{dN$*pW!w6~r5xn-fGowW!`%fS+_r z-l5MyT%RfwYND+vFUI|}mZ%9A;0-6+TqU1>HdO{$P!6E2lnl#eMmryiej5-mXMD*i z$NE{Z;wZ5sx?IfRT3aiPw!b-bo#0YJU@3G2TlZ`vFF5OUF`=8(Rk%KJZ{HK$g8Pdn zPkdb=BMXb{NHTf-iJhc2zIPmzpWjyG(jkADjTFoktUzld^k4h(0gl#ohMBKQvvjV# zHrWQBLsld-)E2>uQ`!#H6>w#3(F4D{nB|7COE<&JeXX)M007JTs0r6#tFIkPo;3@! z>2n?Qn?HDi<3dBtl0HLP$o%YM9^QQ<88 zTw2-I)IfKcj%eopV6gk4bysT>PFFPPl3HUh3}uF%Mu=#O+WiFw?VC2e$iM5?b5VIS zPdQuj369*{uW`xi^< zbke*@9A&zDz>+dd1h24R)GWAcJKl}Y2ib5UaP49MkGh^YrlKBP(GEe!Gxx7jMD>vjwyQr(y3 zac6MlpjUK5k$M3=k*GD23CAR!;g299ndhkYIq+a#nk`RPCrZT?;UGz%|L#}xdzAG! zJ3U_AT`Sbq*XcVjBCG9YlzB%13IvT;Kr(3Yqyhm=q0!m}N6Xz=bbiK(ssGxTDSVbo zTgM>j3relW;bkxa(JvVYpfk9jfac>S5<>9{26HU*x@vh6svKSIj^l@7Sa;=PxM9B# z{XLc{jdZofZfMhWwgGXr5s1ESU zxM~N6frI`_WJR~=ijyS7?py!R5Fc^C&AdpSGfR68-G|UP>!ihfGMIQ-^y`! zoKfs-pb)r8yY?ratau#0UUKU{Y&?GO=9QETpX+D3nhcv5vGzrh+o_WH4H(v@IfvZE4UNX zjYT0yqzn1G0lcXXsJ+12&6-gJP@u(b2TT$5kC&3Gr~U20TcNCVr9>R4wZT|QTxn^e z-|ZABKvGsAh2aEisem+eLbku!2C2Gq4$(`?yz)ycDPThnND8S(io6hWY#12U7vDoDU+X~ykcGa*pu+6al=jGi8{sy z5#3$S=WHrEEEb^iroWzCn=G9Dc$+jo`k!@Fs&TMN&=2`a=7j=lNiL1R)3K_t3h1?4 zfajaq>Op2QaQQk8M#S6_Y};NIPbPl zZB0!A$=Y(!HJp#pf?PiCRC_!aTl)!QrBmyMw@Z%v6g}0yK&DY%{Y{L+JHAMFhB?=ALX=n{`DEMvpnIeBE7dQzpAfwf@5yau|`2xFM`C~Gc=H|Abk?dlmAinmhmmR}zTcrvt8##iqn|)|ooaEiT+WJLF z2(9Qf6ND?*@0RjzkGwsmQv3?v=h6n&1#Q2v^ErKM*b4>b|29M~_nIvIEl%4hV#DLI z!w)!z7~Ykwbh?mHCn=mc`?t!t@#0smce4)nSP%I-yORj9?-^xMm!Ise>3ak`*A5-{}(QgG7sf3wvv=# zYMl&6-dXxU*UPlauk94YfqZfyEYj7Q4ffk8WHrk2nxB#?vX$Qn?mI9hK+>z#hWmlK#uE{} zMUNUR(FsEIAbJa;x9CJCdW#;t_ZHD2SfY0c(R=T`thQEPtX;oPzRy4J^Zwo$Wel@+ zhCTP(d(OF++Qk?@t6%QN?h#T#M9cJ5Ihan@c)iIq!_J4k(VuDkP(P-%Lp<}P^DPbw~u?JEPeb*FVK>~Wp?P^xVi@+ z-dHhBI5&`-i>W&5Z#-TG8`>KetXi#ORL*-?wXN|idknkIrDt;T+d1f>QH+)@ZMGQU zxOW5uRD+>++|itQhp#P#2Eu0r$KJs|ECa^!a`?beVjgI`7|ti))O_;ug!NpfKH*HH1IAeY%FHT@g!=R~82vLO z%s=;(>Dju%4{o*bKl5;dLWFMti}>S5Ap{C&6Z}yR3Kg2*Cr=*XDEti|?@FhRrnyn) z!*Im-l8xbB_eAlAK~V2bZ6U`pIa|%A@wr~qzYZqvY4SIT@RbzO@zbNi8=YiobewMy zPi_`T#3=9;u8E~dc(KBIf$c<*L8lD&YcLd@iI1zK+%UEs>15c~e>l7h>!gLR`B9v7 zJfXl zd^fE|#_(KW0nR-INEEF9y@V}cb=&xH3!0_{ebr&EvWNyw1ZW#PeBk8)^);%Oo+Te7@YYk-m@iag` zLTsJ=CEVS{Wm^?-x(4sSZ1Z&JKc8Y`B(}DJxSVd7`Cr$W{vIT;d1es zyN^fku8r!b)g`Y4Oe9Y+G;uk({zc8jy-)wZH(ERVcnyqY6XA*gnReaZFuU&yx>psu zxa5C33|Jhm8<)?Tf;OGEAb}{Gvm(i}B5#Q3dhjx^z-ZpM4%hU4iphJ2Bf;z~zK*V3 zv(tLRO@$2HX_t6KPB>bvv4l~1|BtTnp zg)N^#P%H3lAn1g7(t^-gaY330kh-2PXuOYo<9EnO&=L5kuIDjo1l~nx*fho@XHo}< z?=qN#+mgs@*oLy{4GB6C2E&U64%=?5HZP}MU{2DVpC|fCQYdt{L^kZVvl3ne|IJ1L z^2JH}ktdM>=$-o-gM`nJAD;io%(fzdlWbD>xu!Yz0 zO8mb#b$1K@8~+>Lv3!Z}X&bfek;SLQlr;ee!Q+)*_`vog;jAQpZyVf4@!x z9oi%ibV&%@*}gf{rRzDWrk8%QvAT}vxXCI&>bGC`tp^ifsmj=X9e2I$mAZmh7VnB_ z9zy~zvKI1n|3J*uo@tH^f}9u^?MR4z{7DBiKh=TVMyV!ecrk{3sMVH?GuRl0p}Nf;MVW2=SP)-ES$Kz zj*7&L^aSXrB)c%u$H`yN55RHHdZa?f{rA*Q5nXUhJp-}OtQK0p)-JlY2LXJUbR%Pq zz0{Zq8@CYCZmn^#NSpjXI(11Tr-^rptdzUk5Nd z@Nj?hu)~(Ts*?=OabAgRbbNL>Z(vWan+Ur9(#oso5Gz)j6Bpl}Ma!msE$TAsbtU|* zdSLOFOGg#I$j|sXAdqm~q6mq)N&A>$?kfIp&??FUDoISp0GCn^oFWJ*M_hUs9*>sY6G;BjG{P zFNn^0(3SkUXZ`0%-HOM_aZF>9z!I}^dV@ium0>!5I@dDgGUp$bO0!oWkPm~;#qd$s zqhNF_bYfm*EOflCkAfC>-c8JlOK@W)NJyTY*Q;%6?yk$|9 z-JDwTpxCR{!~RWv@QI~cH^Kuak`zIKGiGrTvw|^Av3`V3LH0T|#3PSZ=%tB88kPFY zTpR~=@B6mwK8vf=X*6zEsQRQK7+E#9j1tU`O@* zGV9V^T)-;Ww2KMRzk=NobNI>cSUeT&E|gBG#eBNYsCqf6d8|Pi*Ad+DS^;_@ZuGmQ z9?rDKxUiN-Y1kl#>pmVbm-gG=EF}S0#k6$DCq!U?73&kSp+>TKV&-5N_p54xnYl_% zDZ4q0{&g&?gh8btj>o2Hokc$$-g)fWi)y8>W?heLp_-L%9Hz*RSCoSJ;&~qwM>;}h zKvBgET6BIp&jOE{0%M@+PGzf~7zJ{@#uisDpc007x; zwXfbgb|2fwDl6FA_!GLLAFmUgwfMXf*#R>{-ZfnMiJu!yJ2m;(&2vk@TX;@a;%QY> z)!fcxDO`}$)n!?wJ3eY%>ySm8g58Jvvwpod{$bWjrHi%~hr`?(t1uL~lP|>3d)Tmg zJEEyQSg7+r1l)0g18%u?0|!9Ka($P`=>l$E#nT9zC;KH{WLH#gEFFPMXFny{JYTvC zGIvY1X@YIgKcJ@Dn=gbLoy5bvI=8Ds?K@BnI3VSVYWL+wR)#!aMpP<~Hj!k3}9cyFMoasK_7YooyWFU*$B z2qCx823?m``|8c_F=LQ!UE|-+ZF2k8IuMIN8!xm{rY~D#DzkHT8|IB8=Wy7bR_Ub7 zR_ILH3i_M|N9tutN;5gue6o(VH}zvKb69jp{;BX-nz3Z36G68@_^_X#pDih!zw5Bl z96=bkUvSz%e@9f7|0~>@U)D~wdfB49;^y!AJuOgpU&Pf*rC)ikdgz{4Kg>q@T;#0( zZh<&h_wZ0)o z6x)hxHS~5g*HA_OR;(Mi2l!pZ+-$jJTe~%kzIzDEk5r#_Dqp@nf|DAEU&>jC}JALKg3&Lt^Q*Nd0NGxJ{ZL567%?=)gQaD&*NU6*IB$Gc4GJ z>iDF{<~z}ocl#GkV4d@`X4DrdZfbal1{KBej365`SoFCj%*}D#I zOK(lC$@_$c6Pc0}K<9DezXHm_b(K(o-ml4qWH%^{G$ht5xAL93a@$vsvL>%)jN$!| z&!#~OUXNu8w){2W*sfN=Muj{?k_P?_u0FDiz@rdHz572toi`NSjY#@G*iSBetkyIj zefZ!(3QG%#T+{EcKUAEsp-mHe(?&M;Ely!0g@N+&1oXnx9ek7fly6X^*n=I=^) zg6TPF{N}G^(Vr#l3cE7=J7wj|csvE!(03*K!ItZtGWUl;2p`mN5VD#^LM(ykn^9^m z^SHYwY)Ph0Sg~mGg(_9O0rXtAPWOwuDwC>So#$&!+xqv%t6qstO*WRP*qKkZ>9uU( zTq52!khS4vFLu=Nn+$GvU+0wUFN^x8t2w4)4TgIeKP#ZCH26&%0ULXB>zoTb|;+d*W>CzEItzCKKR+n2DW)@o-X?EDz2s?q$pmHV2rl z*?bUvsP37k7`n4U1-?m8i)35=H|tgH<=;KT>tE6 zZ}%_k_=(=X=|)<)5JY}zo4_U$ZhJoDkN;+o1-&PN${E48Y1$uc10tFMSISALYAEXI z3kCIm)uKIQZT&o-*7>DL-2BaZcSrrpUE`p(7Y?60zDMUe8b0r|d8_J9_;R0Ep3-hp zTbLxe7HzrcXr}RXN$}>iuOVCbP%xvTyzu^1fb3uKrHCW@l9(`-wF#Us{56Wk;5n+Q zv|qCJFz%u)=H=#AKd~8A-Ddi9GB`mdVvA1^_u4hoZ@WcZ}i1i?&}v#D;MTeu}-M-%-e#vIXrdK4N1S=TFuA zj1a$uF3QZoQdpAZ_;+LL1kaF?m*V$-yY4mC5GXJA+1I+i9GCTTJ(tMUggtN#)g;4l zdEO*6bwJ~C-BJ1qk2N#>hUJQ)6k-X}=4|tFa=&Bwc5vsF_)MYCf%CR!_|?pM?p|XF z=%-KG;xsynrUKt|7wyzq*c!JRp>`WYn27sm8E?I`#Qn}$kZLCy2Q^})} z_eu=mAK}WPi)~)?U&91c2QOlkc{;+H0)`D2efyqQ>WlYhH`u>{-8;4)iNiJ!fj2S^ zdR^oUuN9ZRO+&wZh#!K=?<$aD!eKUMfx+)sE)n7^WlQal<+Yx!2lzuiFl2#k8w;(E zh&l&i!U6!*?jQ(Jefw~KsSY%>fgF&$Ai+^jrBW453NN}x1CN;<_b}t0#~3GY2S*CN zM01ZOMq^N&!kv&cC&FiC+83wcbqt#Tp-ugz%R}RC-uGX-I`MMpiF4i>sVZZd1iY*l z{s$LLrwKuDA3C2MY;tl@tR%+iRHK{=Jtjq45I({2Vt(90I?1z{(mw@9(-;C`w; z(=WE*_pPw=@UDuZx~>9z%!&=0XI!Tty`TkmXw2lT$0w2eVE^Bx;=iv3_^@8(R+{av zzHN4XCX1!>Jn`ciPb&TjPkbw7?AF6n-5&|tMCt4=Y>#b&ldb8^QdAVAl0lD*JVq;S z2Mg{LJK>1H)SPu6Cg-kAb|?Rf+4i%z>diiC(_v9(Uy}7ZuK9~9q0anyQv?-v%c;>^ zbsiJFC2&9?(y2^_N%gjyLZZK_Dex)L6}IH{vANr)WKf!Ixt)L^h(qnBP`M2I&)z8Y z{?#3bkzv?(N8kEqvA`LZMRElKT-`k9=cS9S_qhWB^Ug(Ot2wlixonx_sxWB%y@+B& zMy}%H)j#yueC1UV2v#{@Y=h$Pc3mGq5w_zUSKf{>9yZu;8TM^`IWd|C);~2t1>Yop zBnjj6wU+elWZ=Fs*V{ZjDiy5vNzFgy|0$M=?GXm;_JzAP#;2UQB0Qk}eX|-x>$gQ< zW8+07EX0qVjOQ;QS}%2l3gly|y>dH6{CaWJa0%AuJubZKJ!jIwcO^WoI#p5Yts(^) z$l0_=3s;ZA^;~uTpPSLlfs$rHW*tn&<4rxA2`xXTXTp$Sf;ko0nu4i>aJCS^NaQv}gQ zF82MB7;?9apDp&4_T7do;+2h z_&(K%#odp^S~WRDFt)~Ti!Xv%qU~y0*nrJDzl84bQm#T3^+rrD$Ru|i{dV6kCM68E zr@_tR3JK!3_8K>wqhe0G+KihGV9G?;Z7UoF6i2*!%LpnbrP0^hxL$THYnmyXw5@6O z4ijoW^Js@Juk|in9qoIFer~(??00dAseD<-?7K*e3@n&83VcpNqFS6-tT?TbH#CZ= z4f^aLm{V`SH3ec&)SQ?|#9nop2aUgv2F5pqY0{)exk}sP3Mp9rEbAni7w9$_fWy>&zlHy4PyQb^` z(9^1s)gN=8MPeL8toTz>NG|=1Yo*j|%4H;YquB3|bnN4k2CoK4Ljxm-h}oD)s<6kp zPW|Vq4CMv)r;ogzY4Q&6$8*wIKl~BDtfO-dKp3`MH_W^2Z!i$h8*HHb=r_QkFmpTC zB(d=WxX5QjKxt`d^Yv22LbDldoLtJSOyoir{1KHbBeQ`$F&l7IfLC3-p$9aU1hDBr zfaOO_kG)A#^NKRsRlwHVRcTm0UT#YW?}^OH&o7x&&~I|WhvfPRl8|uKYvKVlE%Y(_ zxWc>WF|syK=+;JI&kIdpi5kWnc=h+pC7!+ml%ke^%|=2(B9Mchs>A6)Zr5lqGNx8Hb5H~S{n%uwBgY2F@=rt0 z!Cvj51<00%-+rA?@%oobpWCcYVs0tW>>!%9W?g%#ngo$Vd$;2gY;UvOb&}rnsUCIh3h?D^9_FvN@bbr)I^C@CAW zop}MRU0k9dTco%y=;YWeW$KG6#+C%x?YVqu4?iB*KYttBp#oFev{P%6J08$*TNsJIW%Y%((2NsM$;|`d}KeaPH4>_U};ui zav;WM2t#VygzE@$j$)+m`VhPYlTnzs2uj|B!XS_!RM}13!)?s{kn;m^*X^X~ZUPD} ze+wj0v;%LukS_zTbRS6Qk^9vbqFo4Tz%2cMCW)Mu{DUcZNo(ZVYxNeRb?{`>@AjOl z$<5L=NmrZnnd{+;4sR@8O}#u8IH0I0I!Mxl7_UD6Z0xWqwgnn+Debx9ee+s{T@`nSIdzF+4D%%(TaW%$NT#D$mG#>Mjlc&2>Pe!e!5d=X+86^ z3Ym-&J*44etu{s~n?CzY7SCq+A%pA_@o%i3%2mxKm&d1)dbinylq*xTkke;YV+5Pm z9U}9kV@T#bk;Rq3gRMK-!sAY_RYRldwhBK(oALpiVDcppye4C7sZk2IUdPIfP$*0A zm%=L?eAbla?iIpJgov3VZ`JWttDqu%1ONIGbEPxKAci`lQ~dB*eBWr)nLeA{(h|bl zkAH8kH}3+cYZ;w>tRKyen0{dglUPbdshH^4*Og)%<{gjv7MU7iUD4YxZ!~;|PyHOv z*Ea2O$U7E=q{Of2Z0L$V7wZF=;;eBWE3hdXi#HF7=USEr&ekR-oLE@g{Sumh={bMhQdqt$Ef zQq|Z$LCW6%kjA`zc{~Y-DL4R^z5{U zu+G~u_yZQklOy;Cw^fgMmm#*CtnA#62Lr^IaQYX+qPcW2K_Wn*N+Cd9Y$~Durj~K%q>eZ9{hPXzCU9+%KzP>*7?P$bCppv3YWC z6s-AK#29$3$#+ecB{e28%3>)tEnAtHC2@{NU!ti`<_ZVuc?fD`J*S^ItMgnTVrk_y! zF#~}0t8`!14f{yp?yf-dTfIMjOPZ*#EX`*$DD?O&X%i7!aAdB zeB#sAZr}f0e$LSmEfi0xwVO8J?mE}@-$!)DnBF!NY>%Vv30v;6D+W^KUbJk-i#Ega z{T{y`k`pDft=GKt3rL*;UO^XV+wps&z;!aBZWI;Y1S|*0-QX1a$y!lkm#%mwv^jtd2|%b*;+LJ?T$I`uc-O+>pb>k}!>Y%gng z(L^pY6dg(9TT7-^U+A}(Vrb-aY+lE=o~Jd?$lK-B{q;Ze2oF9g{IIG=TQu~%u9l{> zK%)*qxf*EId@WzppX1(@wd`pfF-_u0)`)+N+$&_4XVn6h3O|+?p0UD;q~ZH{uZL~C z$HbcAP5QuNYHN|H!t_CUwV@zVNZn}~cI3@kT3H%IyJYobP@b{Ue^tZ<5!mri{%5b3 z11^6MF*(EzXX>*%5m^D@{SIs9a7^aMGGna3b>(Lzp>(p06ZGSO3^fRQ8<~@P_528D z(OP1m`qh*10*Uz3E$8J~`xxoTDQ$lYEzq|ARQ&4ieUYPFbZe9tcC*PRF_RJ^0nMdV z3JU_9LKVh-^D4WH{i*ub*lfJm5@7=G&&&_iEZiQFxtz zv~aRA5x(`M^UzwWVe+{u;}}wx)6-{-k{4pQxG}|cDImoG3}Mmy06=c`Vto2-BiDU= zcMF&2yU;#^LpM1uw))c==XDeEc+SkfY>GoGKcAPDy&O!lPK3;Pp;f6QPjL?Ke-;_2 z|Fg0}1D!)}A#ZO!V)ldvCYc2NeldPPi19hS)v`qzdjR7}Vu(&#lnO{$S=qManP&h< zy2f=|4%~UiZi37n7DlYp={1?*1E)A%cHIwm{e8GClH9s5Z4H;F4~p*3_mA!`@DIVH z4@?~oI#3qt2oQx{qgU+h*$UZ7UnufW{Ix7KDYSEe*f!`PbQKUOZ# zH^&an+MoXeZ)fvp*zeOezGjvy$?)cvhUNY(*!Y!o79RpwMZw^B4c~;|Gy&5nyx1BJ zPTYP2-4ks>=*&Pk=^fxE&x3QfLx`yYE$QsANAIDu2E`bS~Jz?6z%BQc|7e3*+Y!BOtCGzsEVA& zG59)F0h8M_f7FI_Y2x+pMbxaH^2h(I>}sanZFH8;L)Gw@29|`0$aJHmZ(V|{KIk5L z(`pBW71TIcy&2T-#G_XP%NiGWSVbJ($2U5AkI8S&sTda&9kZ1?8*b4zm@jVsMP4=0 z_CO<^b8Rngg7NNaT^;c~1jAaHc@roD(UB%G=D<}xeS{5lmdBO&!Egz$Y*M2u{J(N(n((e|n`kp<7ihn4n>e5;;oi(|%|GonCj;#?* zRwb65&|G-y>PYfRfj{+BqDtY>_gGkcxeElZiea9rgsg>}waM9oEobG=>b4o|ahQe^ z>~^T|2F%Jy(I{`VL=~{Tw{IVsaWN4qrNz?n+mO)ni_&5-y3!&j1JK^khuTd2I4o;P z9}zPUhY<--IW9r5sp3+l((8PopA1GLpjzLKb8V{zFIHIoPFRMCg^u| zhCqK$VZC80iJFWgDX{>hOvJ}f$jbE5&aR()`^0Vvq{@toE3bF#sR&X48DuHy41qwr z+hJnE`g%svb}D&9mwr$9-RwgXrz**ET--0-~I9*RS9%DR_or4vfkFbai4A!o! zgrX^CyWO0M#o)$#2_R3hKVJa}Do%$5b|nyDj|!A5!xF8s4yM8SO?&m4JNg)J{oF!~ ztoE{gYeug6!IN#CD<&^IW#1>{OH7__%9koyL`MhgBs4tGCG`q%sk+yHfdi@t5wJij7+`&Dr& zV^T5@F)SvkG;K-(uDFFtCCJkUqyq1`GLevj&wiGnxq(4%ofCi6&y*}vzmP@4@?Fi> zr(Y7Qo45wmnO(@4JVea9PcN_c89Mtj!TkG|TXv>mye~H+0ekf=>%+-9$}n&bi0`2; zErR;!kub^4CRD%knHR9&9=O*;DNjzWC@Y<|n&R~}k^^v5Yl_%1iu9CjKL*2{D zsV|zTpA+P_#uh&^C3$URQcpt6KthUU+1)~sJB*Mxg|6HKgMCzsO%lt*5$E|rPr@lA z=-$TvejJr7i7b-bg*{x;FLwD!j)JU4f9eCa0G!V4wzcus)g8%Eo+P~e3Hqwmj%~%@ zC1$TQ!C$exdDIp3eu3N=Hl*Yb2d@=U5eFGv-MQuntmC4QspWIn7|_{I4|z%VJBaU6r<=AJU9zM>W!_}yvYA`)Htrwvnbryk3M zC^PX91C-~np?en_S#o%%<@bLopO*Yt3HGPiz7wCEx!N5%JoHb$NJ=>M z-$eX%q!uqMJ8aNZj;z8m3`fLfQP{}q>(0W4jP3GHY8~2*V{0C(dw%F(s<#mK>5CQr zdr*}j#9Va$iqmv!J}&*D!xrWKCs1OOCbpJoMQC}~#A7&vokT45I`S8IjG$nXuTIxS zURzC9?)}oUyCS#JCgzgSLUD$xfXLJaRAs88GVUQTrx<=Emi-AfhNflhfQ8(wr^MFM zxka%yO4|=ZC+0Lmon>MQhj<=6dbm`4C-p%aT;I;gb2RF3BiJl%nm|2#+MbF;San*> zPO*2&?uq&}j~x&OP#tnyci{Xvy;9NGOKU?a{aSWuUGegq@MLag39K^^ZNE#bLH^ok zss@iI*CezC;x32YMLR4E^c18F2?|QR%X783)No%t9FlLSI5G#l?(XTA#z(8i8XxEh zlb}?L%QckQQ@AG56#Ek6xaTVC8;^V!%YJ>m zH?|g&^~DGA>;>`k9Eg@R<&B8n?^Tl4w64!tgm-7SjQr1h+5y|) z%^1v^Uh-mEa`AEE+1z3=xw?`7*qapVB$x#fs9v ztla_RuvVMo+;ULmzwEc(>jTN{eODpnb;b)s_udrT{e9Vdg==cLz80X;Q1<2`mfstO z=!_$L*hz4^YRE_ev6!hPFIX&peh<>u{34xVk&Gg}fD{P1E}smr9TltgZL1OQ<$g+z z`l6c7G#Vv``#yg-Rp&=-j6r(2gx%jTdO&d{i@ZJm5vU_=oZ})1Fxt)}{j*!}URcX_ z&;OZDt5NpOyWDj6GfK{mZg#2*NEK|B$<;4_Q-t-yJgauJfIb+Gy_;@P;>KXsB|mKg zlmfvOWij~4y9K_2^VdC-S~UG&!s;%I+5brT|Ap8)w$B6EP0@`O)R_l{=1Big^zsMR zRmXgZJ9jkE(49OM;d{)!s~q|1i~MBwkqk~$YOO<=)Y1lf6mQoOyX9F-*Q0WL1N}Bn z{5pRAVnv*{Wy`;asd$48?U<~N^bHT-n3tHs(m>A^Vm6m6JhQ=+#%OtWOFRnSV& zL(ICJTl(c+O3OZNFnN>NQY%+claA_JTc6eIXi}dr-}{Cex0+<9%S3oW-h1^oGa`P6 zLx)%%aovEmMN?jw*(A}L?J7oV|JtcB-c>{R_=-l)>(bG|N?KMj7Qf zhnnh?98YJsr#dPHz3EObI(`HXINUir{$XzEe>6Px$*-ubeidn>H2mnZ=}){3nz{GT z$+T2m^mwzb48hcNoqp#}ksUi&{h}(f)P?xmVzUR>DKn`a;7V}Q-R*NL!@Tt&)RAN# zv3wTGZyxGZCJ#a1r?M}qdyx;IaGKrD>L8<_m!UPz1-sWhx4;6A0m;W;i5cZMV-LO} zy>f@D0QqUX%&zQg&xWCXt>bkxC@#xk=ut*KYTfeSg*C z-Bm;UD|3qbiG~NF(kEuMzLesElq*j|D2A%Q(mCJ6BA$Y-*AzLdlCfB=i0LyGJW}3D z+Y?(n|CXpnzZm>Uo5k|9KIfIKS5VnxrX>-}Ls*jLi5Nt+m|V^PefQ-PXJ4E?AG&Ry zN83l{e_GI)S;}Q!1$dei3t+Pw{|<~gqqqK9NpPX7GoK%TP?t4gD@ zB}N(3YbI9Y0)&)&kAm{jueki%qCeim;xA-jZ{K9&m>;Sehpg`r)c0=Dfq1;$^Ulv zc(sEt>K&W5$^4=XvBB~?j%#m?AyDR-Wb^dfUyku_y*dfT(@q?0&T$8~4hM6CNe$R5 zL|=Sl2;l=&RToEgr=kt9qm zx2jCb0jOCV*bi$LwtX#{E&rU4krIC(Ur5S1{+l2FZ-^bhaV6Y`n!>@ncv-yI^ys!` zp~OQk^q9=y4lh!$Raj--;#)62b^3s2ty=WW#?iv*m`8rO_0PBQ7vl<35!ksntwi1E z^4JucH8?h%&~%_h|>@|zf8V1mpcgmwssgA$!R060H7*M`tzKM3yPoe0v`^ueuBlLG8!``)O$^uXE|0fS{TCHAd<43L*W`c5 z2o@cjS>@hX%!qL9O;-?9cZ9EdF_8K@Jb^5A^V%o#Y~D?@e&FQACQ9Qa<6bfTp&2>1 zmtVGMJ7HU_z@U&!%0@f|lEsy>P6_&$AU>Z|(-d)%ZEPQ|GSZPT6|J+x=qT{sAc-TK zJ=t`@z3946Kx}9VQ##ucBfN)WOWTGXbLr=0*>5Pt2Nrx$azAy46vj+aYC)Ivr>JE| z`OLq+>pi4Py{bl=QWaSkGWA~%_i^QDv|w=Q=^dUe6sgy^>|g=f9VGkD3weB%tpv_# z7CU9I@EghT7rHwJDHV8CQoAh&TG@Ut>^XhX7e!LOyse;N7)|>+7d=>xZBRun4f+b& zOgHT825i`bSgBK%`f7p$&xH4BK076IeD-}po}R8E{j6%B7O#ZNE}5}JS%fi>uWER z7|t?|`MFj3KUHtZ9wL?87Dn>O;G3Il-6U`oz{m5%KM62+B+rN$zMZhGAGpXBYg#|; z29f9G81|NO^JcsjEyx>g7k~M#25+nvYkq9D9K5_mYz~$JxayScEx)P|p zRzDJ7D;#N6kt#uU41RfACaEolPkG%2H0G+S3C2qiDE zOk1`+O%_^Gdc&E4xY_d`vE>JBV82z5`;o3&ulqY^6qR!`>Z($|A!4u(op|sG;abl% zRGoi7H5nhc4qC89rTfS>bwGn%NVnJo4e!`hD}Q~+VwlEj?}k$i|KvrZBD2bQ>3Qo2 zO$m;y6YA4NI|xu%Ra;KADb8ruuL8lXhqC}@zcu>2>0{(EyXy}l4ERcqN}}KJsP0M! z?znt#il+!u)-#tYd0bpiZxboJS2Bvy7-mD+Wds0uq6ROaGtC;L*<`Jmu|IkRT3l-2buj3UppITRw2!`HTRZ8CKNQo zFaJ^Jxdk|3HRV>ztN#ZKJEQ+pzi;4TH_r}3mSHvW6{7vb3V7XhXVl(Jl)1rY7ebpl z!SY@Ki|AVShvT;p-0WxEdMepXb%NyhVMwwM=nA$1R9FmI4(d~%8sD=EMc~*G$2Gsj zE}MROSmPU*iH;>?j_hHmaVV6@EhFv4gNZct( zJdBk9_^R#XJEdS1YNLQF?Mf31;y}uBvi3){$mR_bA$iSgb~7XG<7RJ4#~@+BGjsBo z>-;s>SW-3zcIN1-_u1zDu%XaLWT7d1v6phs-U?5Br~0{cpC21w^>N~Tm;7X$zPTgC*7{xmEk{b*95n%)(?8Ft$FyJT;Q=;(fd1>^(Ky)*YULlo3F{Qx3L_rm&4CH zJ8Q-?pw9KQ9$|uE(0jL#R*{avDzi41~>}vu>HMzg7dU{rEC{1Oi=3RWKD@pHJ=S2 zO2G7hv*6*_2JrZpeuP|%7d_5WaC0P9!+VS~r_KBc(lU#2SmiuTuFj0u6CGDaf&Z~jev!LX za@@z{RuCV9BS=N1-cDWZOCpHTYCb;z_}>lXq&Y|e;h%Fp@#Cqk7lcFjHaCJpX++w; z@KME}^HRmB6sykI5tDpQ7a18JFG?%T63oocwz~Q${Mo7Y>kp%p-Ds)Of%A5nFXTHo z^{gp@pXwFSlS}KVRO_bzNfC^B>>ro``1Mo1yvy2_#Z@dNwJZ8(h4MZhgns#!B$%0< zy_2dXSmy~fxC?#UGB*4U7mI3?CBxX0&3+Edl5{$gqJFwK?w{UuH>~cqT;&z4vVYm8 zqN;uhWUQEzuv>;=W?z<^g_DLDvDN2&cPdlQ|C7{9z|(n|tcb;=1w0c)EzKzb*(Y@s z*0znrtsMl?Sfyp9!th-8g?b+nX(fR2SLwvaRfLbdjuQZaQ`}qa7h@K_*3mi@!E=3H z3c)HsT{e5@3|Mg+<^qUt)7f#|xa;XDgGh(O#RV=f1|bR=9AqffsNj0+I{F2CGeZ2 zXJFJdN^rcop6r8CO3|o0N6w9`+1$j)F=us9&(S|aGsS&O5OVxBE9heS{zmfQRp%Ad zd3VIoW+K}*xwt%uXK$T(;#Yr?@p@D`%VhFYVn%54RNl1F6ibd}nF6}G+{4IC;jwCw&gKNelT?~)) z*}&CFH%`a+tEAaqmt_C+Iy|^N_Wukv{*Rc?KfHdKv=tCW(MHs1Mb5BCrky=TOl-<((d3lO%_dCw!M^REiUmkV(LW}|P9Fp*)4Z%>X@_s0s z=gqM3$58C=M1pI7p8kfecNK&)U9ggB7FQbECp)w52D;8s3Ia8I=Tg96SAdG`A`&4+OM#CHa8C!VeWMOL6mH3BpHrLm3 zW6c(+m4!2{#AtpTe%iTfyOuO-Gul{IE2gGi#`MEi;_T7mQS}s*tS!rnvjhBOmR|(fJkHYMlwWi*y10$A7 z(`adRPuXQN2oFh`lT74o6m$C)!>1+fc*-Vyp}udGdMP?Kn^YARwjHh4g6~(Fn)J%l ze)E5zh+=YZbZsk{90K_~BI?fTSFxGGXz^+j|Nq!J%cv;Bcil@$r-+n8Nl15h4k@4@ zEe+BjAUQ}1NOy~r_(3`dLVu#VaWoJRR`*OblN=uIafnkq*Rbi<_b7)^ENll31 zn$2VVcHsJs020khcCKI9Qe zUF?+p@ajdGd`BbPVQV6Sok3@SKCQyGt1Osa6?kfcU$y3Aqhop%9>-EyUM|m5iKt&h z%45$d+SI5ZW7TX|4YHe^7vOHbm9apn;l@;TNlfix3zNlC4Dvjq%{RYXe9P~!tT?X- zoEd^4u@>mvlN@%(8V}$s5@@%#^a5 zhumcJ3%^dZeERwCw@`QuzlCD%Oa?KU9=6^ge_^I4da|LPP_m&X*}{leGHyEmgkAj~ z2DWiMT{_7DRIn+r`>d^a{7jcYgpl_^%#tz9kWgnHjC23>@olOE`_pYa_?hX5Fp(>J zatFOcJHrb?%`{h~*!<}ozx@AwT>n4g2_Gr~alJDMx2@g)TdV9_z<}8|^SsyltTW@H z#p-izQ=~O~-{?tLa{MzNc!EFs?(a&q z?TkasW9_U7G~rkSkokM8+)@MLc*bFEr8I^NuRR8}xfV>DKvUG|QND02kRGUk`x?9M zV|L>+n&g|#wdMO8`(Vs71gFK|ySidXL#Xhr<}U*f z;#D#EP~ExZ@6jn8=FWHfMI-mt(#kkJcv|8IgrOzS$<^Q0x#gvJ#;&uB<*Au~=}(&)90lrN zO{v!AK%Hx+A7+B5er28Zt+fE>;iG~49yMZ4V+On=xVMR#QbUfu5?LVH@<7Ge! zrZBiU-2SYx(^6UfD$YHO()M?HI&qNxG)VyR;ZdmQy#X?|0OPjb+z`0(Sw=A}p+7TW z$58S_8l@q0vLIG31Mpo-qX$~7|Rem2{wm+CssLP)Q(>n~23dwPEu zv+Ts`Z6-&R;}ep3+yrP7rz#`tir!|v;+#50ItI=lq)@U%trPB-RXMxw^wkfE<_-9* z4S#y6QFWT@hy;Zya^BF$i1U-!_31yp2T+BhTzH{WNy+Dq7c6}qS4`)nuz!iiF$TK$ zAyLyPp?)CNq*<)k<3G*dESrTAAgV(t=;UwMd_8Wh`Vx~L@W7W@rW?UVWlL0P(e!Ne z${5Z=@trsO2;==by+m}#^Is@o23g11_9IXLOJYPlAhakPx69?laq0fM`69BWzpQ?F z#MtM77|1<{;GIBc67=1-F>u@ZU`?$$N!y5wVNUx_*lORV@MI+2aXkQglo5=^(RPD8 zDtiAyi6!V=sj)z>zQb2yS6iL*%5=0q5epK9wh;MTB-%HFNU=^kCxif6=JjjO9WHX4 zbb1?LuoEf&c{(Fu(Wx`N@u+qth9NCKUyc{p^?RlP24S5?*YRcs1enO`IH zmfo7$11wl0i5`|RaQ@-MLN9}5Kr1YJZ0d~=7yL{7Md$9+JiVI>To)*N&I_w%aE^k` zvFI2czW=vF_*S^xTTRCVC=XZnE241$5B??v`IA(e_m|_kh-47oLU-qrlf+lV@x{%Z z^W6bs4b8)U`#ex||Et7r=S{NKo~s`i{`uyeL*DYytsR7{;`D8brUrcrjrP+(t>$-H za8Than$#T8VK-gFDh?YjZ7gpZE^kFmMOT||=*=MPmL7(nfb~YfJ?Q8GF$QN}byXGg zn_bNLP_@X%y)UnDUhK~}Zq`hy@l3EkQ%)HR)XwdWboAu0`L%P^G&EAW=9>M4?0t1` zjtmazcRgomh?EaBet^O{astm40TEs@OLO;q<0He4Dy zRCrRNqrVW zUL}=Hk{_jO7qpf@tKU*;h+Vo18h8sd5$G6|aa=}{J6j)HV`~T4h}oHa*uRNQy393~ zPfTXzSlhTJtz#XHq*9X+k^VLy1m2 zul~h7%9#}2yg?-e#nAUfrzH}Y#6<^Hz#Y%bnVJy$XD`YrDbJS=FOr=|C8jo>r*NgE_X`S_zy5-&6t=5#aQHr>l{} z{oWGgEX-d`k5^xd-Uj8(Y9rjkWoJxO$;MoUHg9#c9pxXlLOQ+(r;LODIr=emc*6NH)H+XuC^I{MHS9YW z%{OC@l^XIWr19@uKmSCGn`m}*e0rEz?%S4^DBt+B`vpTw-C_Q%$0Es7cCk=1eMbgq zM4(bSDs`}u`s;LFxIlJqH*R-c4so{bz4}<0SYVT`ym!4^!27n{0NCbw?T>H&U?YJXRlv&2Z9`@DG#-kD9nfZ8ub^wnjbMU$N ziJzLp;rj$_dhW_^G-9u$uXQX5#rnbP(c1-DNjF`IkLEF|#u0?x?&Qdj25V6oy-x`#|E# zxR1Dl#tqeFC*<$+>~}_dtVEt7S?$^A8fq&!y?5oaSooYesb9vycaL$;vSndxq&%vv z!?Q=CXB`1MJig!h7AUV(Y3A91NCryu-oRr|IDS3VoojyGkF%0!2_I?0sYfO5pGuAAp(~*)*VZCKS?AloJuwfR*alqc;c>4&SV%{wRaNkAe%&vz z&BN0Hji}c8)IdrQSclBEGN7Qi!MRzGcxHjG)*_1^6$Z~*Ddat`Wr_B_+*@vj z!~=?ugct7K^zQQ=`#*DvFs^+&@;86S8-`fGoihAOs?7qps(L$=7+5JG)(VDmE~W3; z^Nz@8S)BTbF;uY@Zbf9U*hY>KZBH|%n&{}h4YN+_bswW?Kc*)Ny|Vbx`IiMZurzvt z|LfA@s4oAi{`a$oHyF5Fhm*V}?(QUI?%2$$Cu?XxgFGYz#2dxt%Mnz#UjkXBtfPuS zpG-{yc2mhLEemw@4o*&F@J}a{Ija8Zt`G5y0=Yy6{bW{I;OaSEaVA7Im(B6i0GA+k zGd|~KFYawLW47}gPhvmfaOj%M3W&*fmVe(@oc``(Qx^x36-&_ zAvwN4k6DW$QrynvnZ@Ay@|29M?OUs?wfsyDr<*Yo?a{JrAl*@NKSKhsA+gS4+?wh8 z{L0mOjT1bvImA=XRsWd}U|)i;v9W97gND;*&g<%z|0HSE#cYu&rJ@omXW{|vJr%$Z z_62I}%B>nL;M*`L_*gUf%3MeZjzLc$U~lSd6ARB?YF{@EE!wqlNp#*B^UGQ~rT18I zV+3-LEr*->OS}>Re%8nggHf)r5 z00T$-35Ver=C3w0uicLqMiD5_72^|j`WUTwKB0WLAzMf&aKB z09Du}bJDI((C2HG$Wc=$)q=74XD>Wv>cP8~igURv2m`Ro-!z|NIC(T;vr>bA+ z22fRitx~>3+;+NjJ@fc0%gWhwJtxHc8-1*0?Lrrev|`C9y;*9uL`N>ZM31tF$ApT0 zAN|(qHx$v!i^-Oob@qvx_MTyi)bva_8kGr5nvXCOlz+rbe2E9nOtsL?Q25;GA|3!9 zv;i9Zq0PT9hW~w9X3_gN@S#8ZfvkST?|C4?-`*;_6G)Z&(=)uUp%l9%q}RT=iTWJx z_2#%j)+ZAa%rcW+*U|I7&gd%N`|2-Vz7zCYN%{_3z+HZQ`_%GW+ljOnE|)`IOKHB}}ko|P>U+C_Z{1CN`*p`zeKW7HYm}JJsX({EtNL+TN?Dkr!a|@)AaLD^WrIb)o{n6w+N5vK}D4t!v9l$|35z*+0`yk zJdZPFx8%NU$X=8FKQH~?sm*2{jX_5=%6)3OzAByKjRv|>B8=g408U3elI6;qIgFAB z_tg%nVhxNsdzy7V&UA(yuwElzVae!y?e(LSrO&nBRm7vx1CnfSl{vh)7=(!-ll}>J zhyyK`7_kmTq-8%f8k^qpjB<CE^%6mr98okkzYztoMke7@{) zj6Ss}ue=3Of&zfOWb0Z)?!$l0&CVsm~hw%reUt8Y)0sYik_--fyjCr=HbW z-)J)Kmy_Uc-S+|79e1=XZ!mu0Iag~K^AGUX8`pdZESn|U6XP$PPt=$_y&QGv{8;Yy zrc}0f%)oogWJrsNVh@_0qbp`KZ_RGcu0UGH*1CFP&y6#9v*o8Mm{m1mmkROCP6&F$)fZkg4uf?J)a9~5 ziLMOTs2pJ2Wi0W|LAi#QEVa2&6`3&5bo+N{{esFFHaG5+vtPv{Wq$fkUj0_TKQ)wA zbgsRasx?F!CU#bOgc&o_$3_05PV}?#_f~WRlrNz@mjJecx@AO29B4dJ^;& z&P>WO5Y&LM#8WL!asH71&^4ib;OZL$Lg|vQ*#)BkIfAz%bIb&Tc@434I#Fl!DCH9}^P4j5Kv})p zF{-sTv-h5Yg=W7=D$y}M#cW-m3n?XB7k#+QM^FB#DC3F3Py;@B_dOLiou9GaRjXx~s5@8KC0@4Oh|)gPVjsdF7!JFs7P zb#d>5sLtLV%L!CbSF5_b&}uv_bF|zD!8Mc=V@w{Q9yxE3dOHIgv4(eA6 zzR4l6W|m?GoGVrt?!rKbI=m5{^_*t+I$7}Pfv0gjTv_8SN{--uX<2ESzG@u(X5%`r z6|g$(qaBuye~(e#ut#KcKVJfDD$Qf8wkZr4%v0BMLP6W*&9A9Jit}Y)JWA0&)uW=F zJnHuFBF60XwdbHU?CeKw(7Bkdw4rRG1XG*1TZRh&Gt)M> zcUw9(yD(`Y+>#+!`8SN)=Ff^lma3+eg=D|iHl3ot;^E;9lg z@Yy|^U8tH^al9si3iy=Ex(>=RvEB_VAMeisdcOoqp3rg^lcuGasKEkCM*RRmXR3i||@szU{r69r$cAlDSpQX_l?rrAZl)VkT#{ z7t}9fJ}Gvq6YpNa%G9$@O13n$WKtX~J>SKtmaH$LJ)#vlO&%;i(8ch;L}_#@U3`4K zN&H{?(f@mN|L@WrU~EMbKfG)EYVxkPq3Qp7?Z4gvWeQTgskB}3+twbA4Z)PiAmEoA z%t2$=9(eStd{)-dg_mDy;}FOeK4D_eflY$$-}sS$hJc(rEN@}owfE4Y(iQ%?puo~| zEqDnCyFvkaPGX?fnm=ToE>D-iI^S>LIPi&Gd3u!Cw1Qlb&Yd3MZ38}CUA^^*LH4aq zi7UDc?-5<5GDUM!uX-tB25M#3{%(Ll4S5teSn>APZtji^MtkkIiCJX;%sgda0za$& zniNfLDI2#XMnCjs!=Dhhy~EJwjP^l909cFUK?3kwRUMX2_SMQGhb8o_lYU$J$TthB z?tY}L=jys4G(?37f<8Qa_A{?zV%bB6+w!onP~&9Qd1slf1xKWql1iIh4??iO5;mcr z1a5PWVLwB|%qWv$GhNKBl;VUnE+hCzOcT1<7b+IBCNH^-2Le9>L#kXKxWVhB+XXd- zgvUg(1GKvE8s_*&a;uQ6I@0^EOWhUQY?YMiUwu=RTH^pQ*UBY+u^r=0~wtSqnn zU?ZKaXxpMB*N$}Z$7bahx#ULk%O30(-a|krA$Br}EMru4m%dsv4zj5|J4EiV6Pe7G zd`)2atnjrdnA4N^!A~`~wzvPz-k_1B?47>#pp3+=o7;PimEpFjHAFUx4xanzi{|nU zm8`jvT}6M%Uo}4$_H$|*F$rdUh%{5&q7#!1Ep&QmJgH>7$Dl?}3Y73%zc5@|)nbcnra9xtoG+10L^u zzHw<=dm@hcQ*5&uzW&JRgfLT;Y5x6qS%w<@B5;7lP01qbtG5^!(P$8n(&~ijRnnwt z-aa0$RPcL^Syt3IZt83oFXaPKFvnb8Dt;vLdks@k=(Bt@C6)pPM$eu0=U+E-LUj*V zWAiX)j6C@Msp3>d)p+>Cx{LHjH~&u7Rr#IEYY&&MS1P>T0wLD4aJ*2oRYzT>bqmj@ z>sx~x`AW#l$uP|B|8~`YS6%j#cW{y#&cazdANQC4EG~W)d1)3n;KJ`XKXg@Ce?FTV z&9h@Q1QPGl2eQH+xmQL3&bT)UDJ)(3nEtpG^Zgo-8+4FH*+ zaoPF+1(XNU%)!WUvfNyAzZUjS4|o9S$QVsf3@bZp%w-cRWfpvwF>CwVJ;?HYa&+Pt z7iinxqJe)29S6969ra!rE@5v?;RV~&q}4F$m8PZ17sTCzzQ(kAU&Vz7b$6pt%lu3= z791*1cCU0CMM`?v3|uRBeEYNRBmB!Q8|gPufcFO4xaWcz15X8C{QM%6dgZAAjHEo( zpc1QB(8cz{`W00uR56c!-vh`DnK{onetccUD#KzQ4@qm}?>8Lsik1FZWBJ)Kji)Ya zU_BNMh&%JcqZIs3Fn0JlXF;f|{kHQTQ@E68)Uxx=%{sxbKJ9XUW;`oJQc3XZDmAcH zm#6-y_i?kRH*5VLNx1UgZI=Bta(}x5z)L-z1)ODlNYyg&q_mYV2{DBC1Rk|8 zOQv*@$u%a(YY6#%PqP*OKu9#sgTg; zLowsYa9NB3hIzU5ya{<*XPdJ@rT?)9=yT>iqk*x3K2ZHn)qi4e1*U}i@yaMbIEbWP z3#~xXWmx@#PBHtegp*l5XA+$u;oe<8aJpEJzs8=}&pNkJGxXN&15&AOb=o0NZ%}zG zDnO`HGg1nw8~R$WeS-C2chu_kkSK+0pCn*M{~Z|KX(JvsAl=6Z#MAnpZ!*Bjdt7&~ z%6*9((XEaU1Q>_{^Zwj`A^1g@@(*7Me!EYd1(A!M_lEy2hoar7gQe<-h2ti`Hoq{^ zi7zpd>9IJ>C~?aye%JgI0bO*VD9rSGnVHWX5kbY?a^izH=kN<+;eZ9P>R6+OeSt~q z`&QEiMJ#fPyCtQplIqx@NZLIE=d`N@LN&imnwe=}UBuW;B~{emghQbM-WH&aqZhWn zX+P9<(=e^S59uLvNG@TgzKH0pc-$z8XGgI`4*!-e!SJz=l_KsMlhG=e(w^8E$6k$h z;|||I@O>LmSA!7N$$sbM=1k+^yB>|1QKiFII#x_?!d)Fyn>EZZ2OrHoef{B9+bNb- z+4!>4kL<(t%Vz<1 zM(fv&RZ7m)nx7kCl3bfA&Y&Qw*`|CAneLGmBXN?@!Xr#=fTMQNMVcVN~HSQR7nyl!4#+J zPgXP5L67*8n20@#TDfpcv}QqvL=K=nW=eA=cTYEo)vJ&HNCDmdTIcx?C=K4XP7Cn8 zpBdkEBsW|pEdXNJUfpU-Hh6|B9;x9MLU^VJd!!{w*`T-3uAS3kGpBkP&ACK{U zLGC+A7R1f8s^J+00tS4%ge}s0>yAaI!``X9h z`WJn<_S%lprL&ht${+SnD0rb2uO<30*76>oeQKk#sPj-CtpKp78AGwoc6+JUN8;U(!@<%TZ5 z<6IXo?@tE~_7D70`SQRFpZD#kP5lBO`}7sPS(RbR-??lC_LUTkyMS*C0D$Y(evYzi z9`3rJFR|1N0nfLpT+JJiqBUlTx1Phs2b&p`lOe$sHysfSGe zW-PQVUB}Ri3$V?{f*Y%X45>TpZNF*v!1rfLO_oC30E(owi)A6BHUAq5{&IM!z12VB z{MLi(sENzxiBf^GcR*Vw2JDD32ZBkBx-KqwrDfh~<=JrxadmEX;gsl$;L;N&1QAV{r4BBUNzeM!P_IcAO27|^ABlT-GZ_)m^? zACN>1iCcNfl-L42t+5;|K>SB0h_Je;L1VglL8xhmL8U8lTfPN_4E@zencZk=b1uRl zL_Y`~>URKb&B3`nvTD*+p3Ok7_|?-H>}gf~22eH^2<%LLR{)m0!Nvv?#FP&p!nc9NI zll6}w7>C90N;`$gAgH||w)&?qGCwrp-{zQmA-`=P+^^0qSrUkC;DUyLwevoAKs!L9 zH3yMPV@JWBIaWTloV)94Kml`jgTS;eofH~kvVW5knR`WLatruC>!NIV20$AFuhyEI zUiL&aY3DlE%|x~nCWV@vFGQKX*H8R`1~_e3CpaD(P=?T=_IiMy+5d+)m7w^&L03sylY&aH4` z*I?AE;H4jSq(5?*sxeBGd4xT~_Vq;cfyFR(IMqIIkD<;!y&nvKv2?+`vHhuV9b+Pw_IL0NnQS>orgVM?c))S9>`m(M4cW z3i_n%?vkm^Ibo@bBX}jwc_fBqt|hwe8ZUwWRNx5Dgj`NO1vE}o1DP4A-gdmhmIGO> z&%fTRDS(4NEdcmKJ`r5K_}M&s-K^Xyz+pp%7=$25#1W9EIMzu@Bf%kcpPNu1Q~rq& zP}e7f&}F`{w6Y}31A?EPnEt6E`sW+@@_x0?^Of8N8{g?JUu@6hevvOY>j(u1ZYr~o z)o0%B$N4bcPuE9cKy}YZu?g%)<{aoy^TN#Cr{2~%EDY=xW=mJo^xM(CtWU}_bdjd_ zU;l$Z`3VqLYBL|bugCYTSgCYPO+TlF^@FFO`lC&_`zdLk0dQh_mux!gempL>xoO-M zQ$E(CwVf%t)Vww4T-K@?d5pp+r;A6r#spU#3{w2ku?VRo54Elha&R=Hrgb1ve z$9+d0EII4L&psEbtVt7WsBi5KtBD}Zf_w|^#Aan@8_%)>igIApV+S;Jm%j}Fdq1bT zAunJIQv~2*l^(}NMzg2L0K7L7?$IJyj%pJ(;ZO(ItNK&H?5zi;?7#v)tt>$b8cndp zLz&Mftwf~Dup;zzhoISbv9qJy6WE8yz!jgHcU)Z17iM|AwaV~ih$qI)RcNS8HK!;4 z78ippIk>L-efp>28L54C1nR5oM@QA|r=ON~fR#$K@Sz5GT@$f@zENlV$eVRW{<2 zO~1=oiyWsgF+0u_e*+oKdxsA9Qj$n|i(>?x&l&)Zza3rb0M<91QC9V?)_&hq=7PvH zV=&}s`6lC4wTFkCuXL?WkFHzdkMFYZE4&;+q>||JWarK4kTuW;=OAbSMo@*4sr6W( z2ZlXuKdmNltPDg^aa2@{(b&|bW~KZ}RiekT5AIyh9#N>6M zMf1-sxLb1k6xO2W>_aVB9ie{~5t6l$6>Ut8(13`$oG8&6*Wc7S!1^uA&zNpeEU7uU z5=@%U3C5~P|3pgd5J@nPn$^4+-ce97+w3TSzxYJ$;d7~$wcM6jGj8tXMb7*NU6c`%Fx} zsW&-_KBS_0R;2C|_jJ1A7YI1d0b!5S@?)FhM)qTugqc@W*tAgKH`Bv;w~J(9Alnkb z4tpG5u`K56Uo5WmUkB`vfj&?8KA=e+;xA29HR$;+K?F7P_7i#SKeM@Zu6L|ZnvH%K zK2x&cjmy4|mgtpuShBLIX8?jAI3y795`E7lZm7NpD=4P10r<>J{lWN!`g39l1c&F% zTCXloeTaOV(=ri{go(R!i`xppemh8uL^!+ z-pDZO`T~IB;+OG(X~WI2tiMfQ(Exi4Y-V~eE%<<_kDI5QmvB>viPtk}{P< zjr3d)j&-2g$`x z?q2|yn|l5hvtI@U?nm~t(eBN1X?^SBpq~pA6*V>A6Tr?G zL&o8j=VatW8T4#$(j<}qnFrNMKT5kN`dR7-fZ?sJ=Bd$w3#|m!nK$g@#rtg1fo>H) zzWUF}2jBx$xc3+HnOs|YJ-u+vXcX+rvAWkYs5CPu^SDB0r zQjXr~#cv6f6fidIbl4ksFHL1sd5Z0C7o_Tob@r(4+oewi^iZrw+WwNuO8-R5lT>v~i_vwjQ-Ilu@E=a+2NY0_@S#a{GtM2lNuYBc zs{HJp#zrxHUL3)(*)#)7I=)@?I3I=VbsBii$uaDp+r;_K`jbh#W6b*!i~G_!QaV&u z>3G&&e|7oET0}rDbER%VXV*;Y=*hGkZEZ1oUP%E zc^G9*w&9%M-d*{mYYS^3M-ANrC7YZ5z8ccTl?;XS-07>`D#J#S`L(*QA)D1;7FO z3WCLMiHUtd4g6~udxx)*N&uvdS!E=)SPnOg__IX01!AJ|Cxj#`fr#S)Svb)M_hS?v|?q=+bvI7Xu35f2xuD0C6gWR?2 zk8_nkEM(E06gv5KI1bi+JWn49jJT_8F{L9z z*OD2A$>>oBz26IM4{y_OzLFW>>)Q^j!T|$1F~u}=3y>CUo#_~l)Y-$GfaJdzepO9$ zlWJig4eZD-fc6tr5biq@YOB4EuD=^8iWe!>^WT^=^Qx2Xr4%qOe0g;)3 z_s4D7%bL-x-q+R6=a%fSJuHSo20%_Smr6DkFzRzx{cybUfvw2U+P9REjdE(j#8R5J#cU{YZBU4^rk6GjCKJe1;J zQ_k51la<+Fv&%b5fF-g&aT_Xe>f!Uifrty6rpKN8HLl`$uD|@}at4;wUj%lsn2^9& ziyKLCH7s|zdqjHli5G?`7ofgt_cwycKxY_r$R7P>=t+>g4N~QHw_l4mZf|VAi&1RPjTRr_c$zWZ z;>kuJYw`mkLJcKnV8XB}0^5JIo3Dv&|Ky+W(@q*)WXqE6o{>W(4remkl=Bt9u@b6k zkS$!um3TD^$9Wb`uR8d}a{f)mm^A>E>DH`Qu6Guu&+~+t3223zj zV*WKZO^v?A|8OMw#IM7C3Th{L&-;ls{mX3o|D}Z)J~fZVk0Pz?_@bw%g$_cQsk_WX zyKizUq=_hgZzW=?1cfBI!T3J|5pr(~knw5kR#gZqtmm6OunYPS9j-aOb}9a7=ld|t zG-JIfrPu-nN-RLGYV-*n(L7h}jc>za;bj?8ra$@#82s~6;8w9de_<2%GM0YgQs3``%xlt_DU|SdG3GUV2@a=|T?As*hAn7noE;ZPYYx1YeEY(Jw=X zqI&VynSL2(h$R|#m(N>od@IdXX@uDu8n*9pN{v~}R#vP@^ccYyDVR2(DECliZYtEJ zXD`~hI+4P(mnnWw#Iv|JxE$iQgh;c`zJ4nzkChJVp^TuCL3|8(Ck|v106{jaP}e6V zH?Cj4)*o7j&i-C{mo^EG)Y0_j?tfgEzTL2uvQ}s?UWaB8tIr+_!lFt<{EAt=7#MHt z^$^#c@nvFwbb2`rwl`*G=D5^!cD^l^2sPIs8!2V~t_-|9hXneo@x zo!e5a%~{2N8}DL!qG|qa%@x~2WB~YWe7m5r*2XdUP%VPfg!tR34VRJp{ui7^x_5fc z`!N;u$7=_#ilI!{1HRswxNFZaH|2j;UQ3yohnyVYyRZqiR7fVxZ6ejFQIB;9&$1g4 z(>o3)GB6q0$kCdc6vuLrksA1W0qHLFlQ|2Ale)svaRsG@^;z!Cs`HA3((mI)U-5`4 zc(z~3t>cd#Z?WY{GDmX8UOuA-2c{OiEPMZJN%dW~?h&3D>Y73D0?W^dp*zE8nSR-~ z`Rt8Xb_BnyX)01#GP>t$Jo;&WHl$XmqA8he0JM3<1NUe4}Q2cu3{2A zD)F$9(R#=lKP$s*7WjFxK)oY84?Zrv)qggq_9}Cy?guIK8m?sHk=-FS(s4sC8qp`@^?xk z_ZVgZJL}8yyk~W_;OU&;Q+41p8|BGbX^dZa+<96bMO z)km!&0mwK@NgAi=Z36jt;#GL#!X14?XWH!ki-h-|htace4~#V}k9+nB5(w@x+J8<- z>4|iajx=D(HqSO>)<*V*+>f*J6)#c6vZ@G(L_eA6hX0?ppD|r>Wx#o}bgrB~4Fbrm6n|>0PalhZvUXJkA73!Vnfqz|q zplApvAU>ZKmH&F{=h;9tu%0-xOEDEf@|W<3O~OIt>i+p5{{8Rj&J~GRR=5I;brGZ> zSiUtMRn>VolZd;2#z#r9)^f9fagTegj-CTj9++4c87eVk9*m~R=pN6N5EhYcHED#x z9MtwVDcvkKe(ytGAO=36oiSpY_3m6c2VgGwayvQT-c?oB<^RypNtl}BlQzy@Cfqxp z3ULp*Q|m$f`uP6f$TOSSWl*#7&$VRT5WBO>1$#ET7>GsA6w|r$nPkE0$pf-y`5$FdYhKTu z4+1Rim;$2r(c>Bn28xpq`0cy^XxZy~=mb@xHu!9izbb?bLwA>Cm* zhA<=FRf5T$#qUVkO43;b{Gmr0BjTN4fcP&m822as$}AAQI+1x;hdjt-d0)M`^Oa&p z)iHvQ=m0UkdPUo(fS9X}W2pl$6-JG`sOG6IHEhlT)T-?g_m!aSViqVhSWCqC$d4*M zLvr5Y_mJ>FE%@Q*H>s?63ly(RaX>aK0K3H z<^+DjOKoq8>e0rjJo-ki!d07IN8>wv<@vLT^F~dEwa`@J`=O4J=sGfqx1$VpRWBpu z6~S37FJEqZ9yMk@j2u7UW#3-Fg&H7PK@5O>96-z^rmvji0jaYdu2-r0{fW{=LqA66 zGceOX%3$=_n__z7z#FBJ!eaW?b;DFA*6;+p_ngi*iR4x}JWaBSFihfHf2yt%+h^sy zus0<7aKJ-)a8Bs@un-?gu(NpgES{-rc9rP+%T{tKei{sSqajMH^gh|2t)4uEf4EH) za{5WW_C_;vZ?SWQO>XQ3L#RxY>|vGwh*lZhl)1%bR8?(yZJ(22t`gOjF>n5wv)tZ9 zIW}Qh^!{zc5?TQByI+Eh{`w_=x*-*;XS1hkWbvbjG4fxB*{9Ia@t?JiEUiMQx6Y~& zWg^M))y}W~=?&0lL8?ZTR!@F_yecKbnyv!IZI3pz{XGc8jsbnadyGGz8Kiu%+N#BQ z{HnzX(>@Sv=Sh~4qhXzZ`l;?8+%t=Ew!Z)Nyt>}Q5#g>KKNXYk<0 ze3Jx=9lG0@!sHDqw|OsS&kWTSPr1W;U8=SWnC0RHv?lxA^xDAQ7eMA33cdgOdlIx) zUOia3_$rzN2GfA}Ms-JNxcJ?U&#oPVBB@wR5~$XSm<|LMC5-l_fntcN*D>@q$(?m( zg(+$}%0zc%K|#i_xnjuEC8d}OkrgX|_-!j88j#C);ocyDMYmB}Y`YfyVErl%-%u#P z8AullEOP=eT0d#C3;CutajVzWNhELnalpsCaTk=IBh=L4AHdTV_!Pg}J5AvL0{ofmq=qMk%Zox2t!N zC5?}jAWT+y^4q>l4xt{YIPs@Ao!>tW)g?M(Z`lE7S9{>SP?g{)VyU^|yiUIn(B7HP zjF1AseM7?|EFV{1DPY->bj4^N>7zO7ZZ19N4DRiNCT4fr$cg(&%c0=)x*6QVp$ zCBu;muQ|3i(o)C|_v}Jw-bi9g0pTIn{N$|HM zqF`!)MzJ5QSDSkeMG>yw(bIi8n>y|~FKEmIwB?se@z3*r)`GE2Ro`x-(Wv~w_x|i$ z$gnlt6hnRZ@jx^w-W)!4NAAJiAr{TeW11A2Ub%N2a`l=tmE9o!KF-;~C_9*{pf%wt z^~JWR9%0SiVnfl@yHcrYmjPL*ngk;4vZyI1;4E(RC0w7yc!y7o8MRc6#D;ruYb0#sv8b^>BW-hJ(igN>HIOqZ-Cz~8AU$_(nl`$1*+XI zDZ`RaWIiFk`(JFGWl&pvwC>*u-WK;liWGO3BE_BJ?hXm=5=slj-Q6kf1b27WAjOIX z_aHa#IdkthXYTou*?UiB_J`!ZX34XDPek=SBQR)zr%6Bo%wbL$5TL#XCyrr*9!FYOr$AY|K=XzL2=VRuLH z9A0&5y{Dm@Kuy!7Xp8modn>t8Rr#*m7VH)%u8Xl5rWg=$w1RZ`mZYl;V;p^y?zL{x zU}W#X88#1F@lvC|Uni=9IAQvJ(Lkf!$Br?%9mc!&gV+K-c#MgcXM5eSD%W==dRhb@ z?D+jUhTYr)d4k-cs+nA+wNKR+wU!{224p7ie4EyfgZYd=(vxf^r2+@>s3Opk2ZB-Q zMm&-vJqxMaaDoeiMckaF&4RoA7MF}W&4|=&q^)&AifgJ@R**(23pQ|mFK$>xkZlv~ zVyf}9i73!(&>lfG$qGq3H(IU+<%CortUtuGx~jP~Vlb%vv^emf&0 z+&R8<&AV~&D2N8M!Y^dmdOV^@x?w$qN@6ooT0#&xM=f5QPSRVGasF{0-X^fB-U1b& zc$?Y%JxD3}iw6fd4=rGBf_H)S*|?&CrRKY=t2EopkXU zaum~{)uC){L5ILs^&FQx`)>Ts=CQQo;4oTpzp(b!+q##oSMKdsIP#fD3n1;uG;S9J zBF%WRV{J!gK*uU;7+=ev|8rGK3Sz62z0teH@n=j<;(_!hIY9*w`yLCLbh9>>*w7YV zR~BXgHsokz2;C-bmJXyknc`A|To^|CN=g3>WevnSs1~JELT@p}!LAWG5X%)I+c{sw zSbZqe+y8igaFPB!1LR(IJ|uu-xgpQa#&ga5y7uw zopBtMNdL;Hv1Im0aqJ!E&X7n}B4t+loo@r(#scJ5^R8ZuPJ}q31}e*75hp9-LFs5# zGhoxk>e^VsJ(JbhRqg@9LD6Y;9$$7di4R};D;{i{%8{p#w5?{d?b=L}!mX{ZxYEB9 z*AYUDAXsTgK2f)|*g>_j7Qqb74E>x|GaMMK##eQ5VK1AAt34#?>pXD1{2 zKYX1sS?_aDJpl_8jJLd&TY*mcDu?o@=~!acD*L!Shb8)UX)393Nm0gxA8i~6*=VhB z*iLAnk%9nn*fZXg3@M|+ok=;Ly;QLyIsQ$@H`K2lY{nh4pC>_7+uvNGi=TpyaP$Qb z+bgysi9)C7CMQe{3)b}CP;o%c6c^TKF2!!&c%%nakng|mrm37F8A_DRGZ{R;o^K2wKmXKCieHbw1ufJbQX<$4r(yNf;b$ZfKJ`kAepezaRQGh zC(vpfdSfK8K`F#p=uVbL!DF3R8`az-$f{ARXwA=G(Hc^JxnG zOBum?dEce7MgD-H0N*kQnJ4Zj;IlRS6%3a)TN#FY{$COs2lG|CK*P>Kab=O=(&cNQ zc4Lx+H7+~=Esh>MJl}4O%JvG|0_&G!=XYC1MM2!sKNkUiK2M(g+85e z1rs24SZV>k*2(XDq_5EjZm=P&0~YjSmC#$mp(cnpY5;_oEdvve<_vwrm}3(hxKcLvgmA>tzx6B+&C5{L%FGJa5$Zb!&L7W9x*ymT)N;k7}ovB5-aVUc@53B+P|i zu<$+R2KJ&K5vlnjnqKN?FjROsqabk;_|SKAF&n6qM3#RQxh1i*+2{fHtjQT|xGnh? zt`v3d-t^C!qXano{26t$=UD+Nz}PE%bmqhIvQRij#G)7a9Ow9vF}HHOn(R98*%j(0 z5dM0j#;_R5qkA}9dO#5*KVXO%_g+sAnx^^f+(M=x_85)lyTtx?NfApZ|EZb zK;%XezPom71M}sRAQylN(JA(L^7KBeoOE3D2UkOAHLo@ud>)?Izr9s%?X(=dot$dY z7d#cH?@F$qD!+wcJZ+r;ld>Xk=Wo;otVk_boVvdyuher4(-aR`pnn)=%}LBg?h|oI znaK?Vqvv)28+SKh$c2VQjU092&>XIoZd+bTTy zZ8tS@^)`xgu53a&W&pvbAeyi7atJd&UB&_e>d;T4F0~32g%Su{9(4|vTzUbPHaraO zP7f48&&4$>6DmOk*1lsk`B{6r9hy*J^J5{+H--X8nL-^)EgPm9rcWP;Whpp0H9~{% z(2CGpYRKmnOKWhziK5PF(DCn~_WDY{E$EZ+-6fvC#AeJ(ieOLY5@3wG@J*>Gm9DNJ zQD@fP0DmxXp842`D)7@H|H97!+K~!7PAi11IkoKmtq;Pr1#3WAm(k~x>6@;Ok!%9n zFiAb~0UmVMgeP+incmzfgD+b)Ij2t;1JTIE>Tg-l%@5!Eyn8QYrJCIV;gokBR z+2m^1N24CDdJ;C}goN|d1^(29dQ#?vaiv(Ax6cgpkJlXkiO&D;3B^F|ac_Q$RUrAi zbTFe?VClawebMu8omu%_G0(MMo+`bhojA^doonHGf9uKrmuWxmmv)5l9z>-7>WYM? z(n#6#O(@+DYz4ONGan4Xhd35CYsnkLi%rvQu;V?dpepG+0-Q)(Y_r1siObSBBA zZ)d_e?7WvT3K=@X;O5P+@>={+c*HniGnudV^Stl~8&Q=X->U%S>gP8xJk_!of+)I6 zM&BTvEFXFL_Gg#6a2iiTH3lGJ{)b!HsvS5k_*=h7889D@dBj=oOT*duUTJL>GrH_< zl4!`i>-^-P}hEJn!U1psDzUD@?A1obdY6@h2~ADZ@eE(47!P~<181HOOB)l zp57cCqr$F7mAE>{a)t7bQ3suw0tF8L4r3<)95#gWkNHUaGu|B@I|sUFFp=_wx(9X` zL`{vn^t%>>B{Er&G5kcdyd7W%Jlq7VHBMS6xkCurHZ+P(kderb5SuZ z_f8|g#{=yienuAlr27{$F<(J3(z9!U&F?Di>dzZ#--?l$fnqf(e%=;A0?JlPL9G&~ z&{pBF+OAh8X)SG#O4{RS%G{pnQ*@)bNW0Gw)xG$wcBIK?z1S-O9_^Yot*RNAFnjJ# z0%vZ<;hjcfU)P!*?~7G9+vND6k_szD=7&?(l%D8S=Elqlwi zBxFpfQKkURH@QDhhr1zVr1tj%C$P!r&%hsiLdhFZJh3U_cPU1PF%~@Ej8fpN6b0w$ zJROTXH9x!7_I}JXlXYAcr;|qVq$&^LV)2wEA*%)|j+K06jO(L*iXrMumB66M6;IkL zR7w}k|5ADUYs%dHQ8g_PhsLS^0;uB(R1_`&;$WJb?)g=ry;7A!7@az!gK#2ubnI~z znylW;zcE1L)U-(Cduie}1OAo~*cQNDP*9cygB8lWw3cmhP;;IhWxg#OlLRB(=f^vUb@`^@)~7lP zoX8YQOTZY(EXy$3I@)lg9{i{+%rPzOR6Ji?{`BLn!5-c-%X>x~JG$Q}oc5P(Bg=mx zrz^P4(md+ZozT4mk1BR(y0*uoUO1n;xN0ZV6jlF4@GCMo}U{NHg45BBu^|cMIq4g8+Y4?Xn7c!-~p-do}$cTWN_ z=0%8aXRe|%mewwcDjo%9VadwM=8wPiAckMPO`6}WT<&TI-UB6BjeQx*^ei0XV%awZ zd)^8!em@{^`{;^t2-CAeP$spcF5Au#4dOFnEK zP||6{|16#ynQJOt`~~mghH;ovU(aAA0ABjREwantLgU!DX`{#F*~rKo$vxuI%OseP zEz09w1#3wqW$V<(FKKbjVwo>PcyYY=h%Q~ETIPnJr7!i^XzzVuWKK+-prlbp1nbUy zzAaGOit#Db-OavLm5szfy8#bekKvx6PX-Qgt>g~gBUBVaCVU(HeygzvJ!2WcvTyQX z+8`?eS)2u7qT?fCz&|55di0GLMyU}WEZR>^8>1R{LTMG~No3-Y>(rRzBy!xmZt24U z$OJ7eNhG-?o6eUc(AK^VJkH?!)Tdg*kM1f5e8v(>z8%vggrW00#J)8|4wU^BD#{qI zO%eM;BJDYGL52d>o-Uh~DziyksUr8YJvw2A`pwsr9c&`p@D8k$KnizZ$6>V9dOO9e zboWp$8?6LImQR6XW$jgQJ^B_+?2N4lUH|c)#F@X~wFfcOS7IqUxGSs8wkC0QP25$$ zxDT_zHS%&cquetOy4y-Cmcj~3q@2bGyluK|KTXJ#E=AzgL~v2fa%0$Pvr;QqA?Y0j zwHUf{;gC!EKfM!)N7%Opbc!>CR?*)I{l_|MtJhMai+OF*V16+t>4L@%x0+aiLUJT`K>X+s}m(wRhg zoPeowy%F8iyKKQlymEHodYqMd6vrZ!tVgKvDZegOw?r^iyFy07zur zIK8TFyn0-Albz_c9`B*)+x6x|wvtH2i*4$N&=vdTh7xYXxKC~x$hFMHD~Ov==e9YT9DvWB6{1jzCTYA?=gi!iwuFz3hVAphdt}0)hDQ1dp z>W1IF`vhgN6`^qt5#Bi){wjQL8idB&KY~dv4$Q*q+YUSQNeV_X5lfSgbZQ@WzUekw zH!bziHRV1zr(MmU5`ThOLl~g1~=xMlvkS7t{SEZhD8o ze4Ik5sjEX-zjs|XCY(F`e#Pp0@KO8NWgTNeqi@7NJPsXPXWnf>n@)4GvV^Ue@*|F6 z_w1DL>6<;UdA8II8^}^H9u)CtU0-KcB!SjYE?nSZzSHzvUZFFXwX=6l0|R@?!PT3= zowt-wiE6MXb1r;5KPk!L?N)X>bigzly$Z6ST1M+G%w5}=2`DC#weeI6Qx-viGrC5? z2M3}{Ly=lvqeuNneme9W1p_q%tXUqbBXnW9j+5Y)f)GEpz+|#v7{&5p`NosehRc^r zNc?p}sf{4M&7x_gp!-KgyhUJE^7|+nAuY~tTy+oaitbD#CV<<{`JCuhW~-d!U(ELm zrU8Na>69&ZU$L9_SKjDyzi8D1+men0P;?2G&){VmVdaHG4B__S%p@wn?w%%*qXrGN z16ZD9+BcmrrbA;py<3$zNS`Tyx%M_sC4HYHP<>XfULL!>vjJ}Ep=jae^p0%udc9%? z^4hDaas6c_?_(Kx#!3_c6{C7mKS3jtD)ZWJxZMVbhfDFP1e{;~o>snjU+kl*xsK$B zZeg2xtOntZ_K|IiYt4t-DqTNwmGrWWsuoO3!`&~M5F(Taen|M1mUvC(-LA$MCJ@(xC~Fu=vErrSO8 z6&L*vySkDK*OG@VBdV*F>!aRiWNV+71jbeW`x{(SmM6^a@{zWW6PfLFT$xsdbp8RDKX2UkBtwSfX*b z(xDb6tlxiJO0LH%(MJ%eQ=zbU+J6=BK>`*MHQ_cdJf|7X?X_4js5HCTpq4J&Avay4 zz~pNy$WS8xTLQ>Dxpg8W`som7u&tjpj@w}Vs7JJz5mFJreSG6*MCT81?8f|$^IiMd zpiMdM-;?g#RX34+qoKY(2vbNJkC?gLse0YHF@}EG;bQzzBWttxneyity3w~NygPSa zVm?dt1T2n$&N|k+r>9p`{H&Oh9;Ti0D3p_fglB~t-@l>)%{S3L^aF^JjUDDI-?(@Y zJ37rd$%nmHEsG*z*4|Y8&$d-cQ~O3=r_pT3zbloWm(**xZer76oeF==PutLKUym*p z!_Taaqv5?)fo{1;=9N#b*H4vT+t~c5+XODoH6zI3ybuXLiFS6s9A`NNmg}dh1NNht ziGK`6H1OnaeK&3#--?TOG)WmXQrIuHI^*0}88g3XMCq1!bu9Ml0n}OoO%2(`gqffH zv2S$N`h$tf$=UelKHoDVZit+JF8}G>0M4b0H@cHFB-TO-&R=Dx_6fcj;o3sJDov~m z*gUv>*tA)W9-~vNJj-7_7%XNP(h;E^wiL|rF9S@BVWtx>)#74qfCB-}!GNY{fiM0A z9#T;+D$9R+V|TLpoLuXHl}?>jv)Zj!3ZwHE%=YlzkGJ9?jTR5?=k1^;XTj#ajsbUz z*~++qhzf?3tS6$v?Hx^&CrOdowWVx++j}z+Z&oR8l80BFLD@u#6gx zt5;8sQefjY0spU3K!2cHgwN`HzrPw6$DyYohjw=ry7NQsQ|%$%i)Ecb8m~VvKMa|Q zpv|rXUEyyPBzpYMP1pgG`K(eUyk23A(q zmZ!Lrc;}#Wf)`eey~0u5vNrV^t%m-O$Hfh@FD>8tB$IaInMNg9MrrS_Y+{v@|Gn22 z_DfRE79QPoMm(6jxSzGUzdDHbeYlck$!2lZA!ycTsbvcHWzapDMSM9)GRY!#)Oq?M z`wBR(i}S-#gGkyfIRNL~nPVMnkh@x%*Sk>ZF`-@ z+ihBsxgMsg=aV4U93m4-s7IZ<5{)8H?_3g|pleYg8OGZ6C!9P*{)pk?;=TEYk}`=Zhz6P9fB6fs8=DRd8;?-^&7d4 zp);(lO?2a2_#eFUAib@rf3jD%llHb_8mJl^OB2{ed-e$=PEOIc zEEs#=yxe%2D=dma0SGu~INC|Y|2K`mYdabHt)lFYr}J{$a=UJ~1eD&9kjxI%_?sj! z@7el;(`~gGA#D}p2#jI(+0cde2Hj35Zcku;RQ|6l1aTFkwK+OUc%S?Nf1&Jraf*Gp zd%1o|n3OEQOX2$TxufZn2BjCV0qmJ0+n|}5rGE7lRY}3w@4;6Bz?MX*Y7(cO{?{0j zUC@jH@K7iOJjWp`lnG76i_v@fssQdX!KIOq2z#F2!4a0ZJfLO}V%aW9n?>}~wV)lQ z0?Pw5k$w6&_-FJo&xX1BC6X^Q)m?$ns1Bhwl_svF@{5b}2zL#QF&mxKfZ_8orsQk$ zlr~&kGw;|5vRKG$qKm$#xyP3Hx6-F(TljH;XZRAB9mRJ7pul#hX*2y6K8FS-z09nF znBgw0M(pi9)tR??`A4$=2?Fg#s4^?NpUDl}+Dnv@#{c8_aWHKLefqHbM4-3oD}Kak$|;6X!Nv*0Pk6_*0We+#n2y^0a>Gp8y_+ zE~niSq!PJ#{F-LK9Q)K&TMWI_i`qNTP&*BlBZp6OSqWA;V9Ux!f3%x)TJCN4xQ_*x zUSHiN9qCmd)cfD0IONJ^hi>LD@%Fdow|9m7wo&$nIjo^7g5ZXX1k#@c6VVybJOY5) zoY*Il(EDpekEht62q0(Wynfe+Wov5EZ}d`r72O$4Y0Z82FYSlvNuxb!v#RVHzC=5o z-onV4Os(>u^-y&$9ZB%x0ihn=SG6Z_3F=tR#@*qd)@iD3P-cLC%f?2hbsQPgU4+Pw zGIX<8wX8jLllyV;Mn8!%n^60v5dPh#htx5%LNUHJz}`hoj{f4`f6&^ge_VD)xpU2k zW{E1$38Nx1k=*b)hOT`(CvHu&8_8`uYp>emqgSzvI$r-hy6LYaGc%rO|%yC)V}M z+X@%BQoi=b>IX$bF`m6!KZVs4nUpbfUL*-opk}}^C){7?(ks<#(sF8g0-BLo616?~Y%iY%@6l2$zEHXCd z<+@!|r##I20kX{fl{_oBLqL*9Bf^E6$z&81bo9%J-UF}?*WqorR-aJG4e-D3~ z$IZm=+pJ5=J=ZVU4>#-l?yQr;8jhLbQs@SJf}9%8pWZywl~5IdC)N%|F5F?&-{bm(6D2u^HJ-i?6I{|Z@21s3oyKA ziXrM6{rQ;n_lnDVKl9vX4c{M;N=zkrxZV=LxF1LK)v*A!6nj5~k~#xlj%b=T`R19va?e;B}Cc!rs0~u=1An(M{^Otm_Qc;Rlp%NW0z`h3SL+iJb;W zOnTo2_iG#X)*6ApS*Psr?6@PPT1iEgs$IEAuJZ^3Pp;g`1K#U+n`-j&F^nC@PEj0c z6a&Vk4+Fw!GZ%th)5WEp4s5HUKa0vhdSXh_W7T2QyNbp~!Jr4~PuFkYmOLaY6ytSi z87&pB=-Hdgb$DDdNpQ(Ns>C)YH{j3sByxAQ7O0)RGI<^nu z%Ki2|O!+``BGJP`&?1bhq|jj@t)zsJo?& z*9P&jqcceoX@G^_gME73m&!&2Z2Td>sf#P%isP*J{DMELf5JB3S?A?lf{V^vqfG4l zz;!CXR4x0c%N}|gCzO>oDobksEUnPBze$%C2F+D{;ri``h)e>WEr$Ij{QdHFZPE?j z&fbMy+peV1R4I=-oMx^2%pB&-LT{hW;-taGf$mQsE(OXG3j)^5?Cs+;!HZ=sB3uTu zD_P0&!>78ni7+R)nuuvRPVejOdb^|C~HJqTZqj`|_EAG(uI4rvOP z7WKtO6B&}XF-v0A&MT{`NBX4TQK6fx8dmO>*rKV!LVyyksN;&*Z{g>)13B2>6Leus z_uG}uOPf{rHA>z8I;@Gy5r-m2(`iq=`AH_R^WYjCnLyAu6|@^U{v*r2>RRNyg9Pkt z#Nm)jzHZbSra51tRmJdUL(hb{O<7KT8Q#_?TUMF`!~lDC+4;q?HjH3y__4m6HFm~Y zbo2dFVql1&FBKA_HHfMA;&9ozQ&DYIPVbFWT6O_^Pa~>g&woE~&8x zRlLLxrtd#)_?dW(&8bdB!jHj~==TCcAfKxq=TxRT+2An){?rUtCQkVDL2z=m%T2NA zAiR$jQDE&*O=XIoxA9SoX6Fj-eOOvj&dy&nBp=B@t^(-4S|2kNUf=(_nDx$aXQP@$ z2XHuUGn_S)qhuxfYVA%Eb@|UNTI%>F?*q$N-4__MXVO|@Iqv@mVHeCQuC;^V%3bsi zLhZsVb2fCNmN*$QI<7rGm2X1PxGdQ8azbRBKtE|iG=BHoNszo8t={W=ef+F(j>gXL zO~a2MYEri#`@=CVYagI~iN@O!(^#NkHz~L{svqsp(LSrxq_pa8BSY>?&Y zeP11UZ_;_$4Jnjkeln%A?eq}iy>9O#HTEmHq`G*V$LaPxwiY=l;Snb=Ahhu-a{Do4 zeV_z#CVhHF{&3&Pw3d24$&`d-EJzE3od(cI{bi#t7i}tH;aU+9Pa;hkN2B4YOTV3r z*_E>J1I!xOn=S5*8^}UJZHfURWVaNHBFQcn!ZW+e>_Ol=3MyHiQBRVG*yT$z3CQMy z!?~F{4g4n$R(*glqCx}ErTe)w18HXoidMFE>n5p0z6hOWQ!LKT>MP$+jW&<*kv9i& zD8a5}BU-b5EsD1P(yXi!8tA>nF8^%@+l6X;^v;9{?spFM+_HnmM`OwB^F7<0D+YJd zJ2^!%gmukaU)L$LOFeOh-CZk(pRZ#2O>)4zyUo~d-i#V|9Emqq$1+Um9iF!pH-aR{ z6pSY^J>EVQmjEFZmS=K(>wczONxVn~fyWQC@mmZ1m8Wv&!$*>ub%lc&omBh}LRq-i zwRo_>XJKUh)xxEMCwc5q(L&~I~%D^nL1=3A0 zbzvdXxo#h%pD=@qIrn2Ck=5(ZarmOFs=J^KJf*7^g2XO*}DNQqwbt9XeR){C!DPeRDXH!Wx6; zH*n)tez8pz|1R~29b(ebs6yZJNA5Q^+)Zz+5Pw1U=+-ICYP>?IIVH;DE#c#*ou8ZA zbB$e8!K2cLB-2X4Rik=K)PcU+U+n&PB^mx3Fz~&?;XiV4FUmZr_IAULF8fkM)o&e zG{QPoc~X6k-Cp#u*89}$!fUjzo59&6*h_B-&YOjo6^Aj|{V1{i+7&FU(1`2&T0kp8 z=LQH(EPqm`J5r^*7VC3>>e*`n{Kf!z=Ml#qQwoN&bC%ltZecH^)w^1B$vB3 zb-ZgTo81Q1E)k{Rc_w{pVCJpGdBW!KX;v>C?}Pqr9v`o%4pzdsazqh+g^rm5oVd;Z z`OaKvChSmC&1@ZZur}HnrytZ2h5~*!v}L6?@RX7?NgPTgXz(0W8H-8QnmQP9$QkyM z3usmnjJS#ziQ1XCbHeli?=*e9XPw-Vt zIR!?4=G0NXt$U&aYe2*=V*&gX(bA*WcE6I=;jz~{b`k5CbAn2@a~Xyd$U}7GagVA7 z7338Jk#Vjz9X>HnLr@(kYSnBMKvwbK@ocO@x+C-G&y{T>c&Dx5Zzy~pDT&A-+IMOJ zdK1~9nLlaCX^$ij3JF?aCuoB4_)J2DLL8*YkJYCv$aSJ@SwBJN=iF~jcqe9y?ruw- zGRQjwcRq2Na+f_Jn2#W#=&b+m2P{CCmaLo{-osy;L+krL0a7c!*!u8 zFl@d`+s8UcQZ5v(<9qrF4mQ@_h|OfDRA8#Wq_fGm<+&C9i5?E|1N?+3KAVF3Z-phz z4oZEo(`%|KGCAg-hFNPS7rb&~G7*+OZ(eY6Nui+D!hz2bozt*L{-3iZ>C zmXy#HHXmat4^T}a1Em|cUWau!^OY%?j{&z)Ia5o;eaZ}L{3h5_La21*G0F5vxglcv znE=uIys%w5KQile&!ONoF*5-4=6i~*MoVxu4_7k#GdHK3!xtUpQ#rrLpJFc|-#)~c zK@Zxr_?>r-2Rv6MKSb@^iVDS>iZ{F=)%l14 z1L>MaBJEeNIiK*#GPd^orT;#;LA>ysY1FjLb!YH1&-oOtQ-^3nFtPaKDA@OA-`{D0 z^B*6&9RET*fP}SoB4r`d6ZP+vu@D(JW8Jx9@7@=k!eds7bjNi1tx1dWh@xxUh^+=l zNu+U0axc-!vDo-*1iJqxE#JI!#gGz1Gqow;z69lL9&YGDX?%)pB0kNT^;b*RnqGG*{K+LN*MXyk`+-p8;InR6;szhWm4K3gX^?@DTd<*^+e{n5DM}$YJ}9 z+&B|KX7w+N{8!L~@ubak-JGQY&PZB?kwb-6|D-<$2-ld&<6zLSBDq`Mqy@WzvW*L9 z5w~(O;m7z4XkXf172DpqTtLg!oB!f@#el@EDjkVJi|7?+W>S030(~I&Z~p z2gQE!G35ZEUvU)KGa==p68Qyt3-yV3?DEXV+{YL(_gC2)^Dy6eb0TQ%Q@{uvhu3lB z!`kap0sJ&sBJtukk4xdf*-z3BP;RwRvSs&?fheQ%h#TEf=&e92L4@==qF|ym5QL44 z-oo`!w*P>+^k6L?Kn@j=e!VOCCrlN>_4M;Zn2m_^#O_#ncCFlMScUOcc<0NY+0PD3 zSW0&4e6LYfaBVLaR8(mBuX|@F<;BVXcbSo$UYa59t*#@cgH;$_iAGiHG-0F`Kr7Kf zy|p!EzHxDpGKhWD+$Rb^C@CSgs{c+jKV4!h19Td@tC#AVnZkUcE85UnFf{&Si5*wf zAeg4xw#_z?q>RQG^BZXW_KTYi5c|D+gy&NG;$dTP2az0Y@h#Y`0v2c3mJO9Lx&5cC zu*?hA-Z9h_mdn@@dFyM5?V;GoQcLkik3Kx1pP+}1p|K@m-j6<Yc7&O$mlG_zUPu4#@Q@D@(7^E8r-b%adytsj3~(U8I|u2%PC~bToMV ztdlO;p(e4QYQYSCCmW7BRIwG_boC&au5xH?K`%l;MMYWBa0z|M+arIfRKP@c$hY<8 zy7~E;BWxf?ca>SescoT@9r<+q{m&Jw3+k(s^ex(aGVHjs^FzZno0jB8Y46;a=)LsX z+((7W-=#nxg}-(#V6=F2`ch*Va_d-B^SBwJ|}W1G2*Q*TFS|eYv7k z;eQFY;Q4LzvYQ$f!>##tg21uW;<_uLTHv}!ul4uX%qwC`cr}TqN%R4t;W`w^unkWb z8bzY9@nGk?vd*&EP7{dOk+N|RJwaA>IV!ji$8O3}-f(g^7otlZwIHj)!MqUgeAA)w z(=tBu-p-d@QUhYf8?_f3ywT8g`_1Fc##hVCto6b|TX$$(1T79``v2(6VqK`qVe2G? z3;mu#d3R5o3Cw~nyOQ{Z{Mn6nT%gjNpf#`-^ZAq;FDHuN=zJapO{z=0$W=WT8jc&4 zDW+lB%sQ7k@Cr(nGR4gOlMU=qrE{QE5gFI?Tl<-#YP_`wDQ=z@Vs#GvSjFQsjQ-OX zJNpE-{Rl_4`OV8eIid`06=3!E&@ibli7p*(V8g%duG`HK`wS9tcgIS+CD+m9%X7C~kaL5(YsVDS)dPH$!MQqGz zznW{1j>?3``gJ{IUc7Pje&%ihbO>F)F+aVg8Wf`e-$CA)77ARod^&|AcI6-$$H7Sp z&cegGFgx#AVl5M%@iy4CRVesn2+)5tHxUH&%mFB(e_mrb$-EVJ`I2Nf!<_SRKwM3o z14;(-SDlTvwuRd*9)H7 z+6NT|_qi>zT;As(;h&_hn;)sC4fo~E1NQl(xI z7O-Azc1zB<3cv5c1}oFeLkgKq)%-SPS~08ArbehK$p}id7c~~<32^ocYNQDb+VT#2 zNLX3RhD@*PANEZFX;t=kdJ)|OE#Zy1JG+^MhZ^dirQDSXf|8qPdn z>J^?upDej!3JsUh;VRO7e_hjHbi_74f|zCy? z?*(+yba(}nt|LbK{NCQ1WD;Z$@y;Aj{$bCi6voTOASma<6@4az;y^If z273b0V7d;Y)K30=ujtQLX;XUWU=_&Oj2UUDV=uuHZ^T)eLWZWV;!Zq4Kwo`z2)B@zw5n>HIBbISom-N2+9r z;ZqUj^;pFFd6cOit(dy1kd%5IgW0p=6J7_b%zkQV!(I8CAK`yW4!1zv6@X`n0-V@6yq|l#teWfMj>Rx)i z#*R%{YrOHyVe^HL&XiGRp9?GVV?KPI#$=x=($;?%ZzOcm!5Wtp(MYeV^?n+wR05t0 zc%~)MpQzOcgez8GgbL2koLhU91vAP7%pF2x70$;-%FrhxOWRAN{or^$;hj^fc{Fk3 zJyD}`#k@Q7H!F8*r#GHOip8$_k&9F_aVKSLL7e^q>9}7`%Rin->&~NjkWcH%KeC$~ z;jbu5&{A-BrY$fKwF2LF$!*rjhVXn?Qa9``0|u<@su`x-E}=Ke~pxX7a?2E9d{ zNXVoCc*i}p&#dm{lZb#G?c)*~j=p7a)~uZOhNv8i{UJ@Kc7%x&=7L1 zde0Nol$(_1Z%?mhr^mAP+fpR$lz*O(#OZzUV3kxIfLZa=Ny^IJqIvUe-h4O6RyY6F zR9*I*k(h?lqYpIj5tx3K+O^KS*P&R=^OA+5P@kZfzr*Ebwel2_)344GoMNj&}8 z4T83JuCXS6ZYy_ps4yw3^#=AK<^X2sC%uKFqx}Tkt|Htv1{&d}P7EZt^Y7WCQdliV z>K(y>c{mAs)Y%{xk3z z9_u=eo+cX0GzZEVB^`yxZ!v|#Ls*gz34Ilfiu%<%s}DXi{bu@vKU4kLfT zDM3c9^yq^1^XsXX4}X3Dc34)rr*Iyrzm@H}p>*LJ-Hjk`@=gHOj+ z>_nQasQ;Ml(>aJ0ya!z@Q=-ANyYJ6k4~R1J;@rmi=z_c<7KNADrU zEaBF}v4$}WQ5QAGep&eI_x7?BIGOo+Zxq{LU11-6qS&*3T%3*Ep?l)GNXFkFv)@uu z`XIj^+t|KwOywCb{8FVE#{unyoaZ;GT6Wi_iLkS{Q3%V9g~QZ&){?$_cEt>R?%tn{ z_1&L|!KYJIG$%qd66;y-$GSkLZTBvH+%O)BvW>Dus$q9>3wHtGh$ddo{}Gi?n^P$t z6u!|;$SClkmMV31Rb6i1=i#5w2zC{GDtTCRvYVGxoX< zC@r^CqvgNjRLG>&*y`4ZwT%~7_nKu@4Oi;vkrcY(4`oTni8rtRB|tA_)By;m{?m)^ zBB93QtodT=51T(X)c|gV;~V+b1f!-ZU)mgCAKG)E{?oaAY3gMk?BFo_0CB60tcDWX zLsSBedXwL|S~`Q*JA;mUb!yjQS%njoXTx>aWwo*18X4%%)J*wa30L=X2YwdOUyW9L z(;(b3kA@L15oUWT)HUq=z)&c6K)^r`-5^+E&wkT*{aLSGnD_@Q*BJ~6z0NLzF%{4F zo>v@8rxWc}hQN`5K&3R(0jDo3;KT)|i=B=d!16Mfa5&cX+{R}-S}ICK&<-$k-a(n+s`oz`G?ze21EkE%QnpoSIP@ND zZ&tbYmz&E&pFqUsb`6coH*jy$71WCOjxc6{?;afa7gR<(Xc|Y`9#mBDX8k=8{m$@> z(j7Y&s8ciWjoB8SP52mp3&x^t%JgRt4*B;ZpZaw@t|FWz{!bu0yS`}bgfb1S*Jtkd z)7NN8l$3=dx@GIhV)=v`1b%cJW!JOX#W^DnTNvaiAbru98_CsR%0f*Y3Bq%2-}5ll zLYY{LY0_~wgZb#>`5hA>A-yJX4^5p#jnS218rG3N7{b=;l*tGUjYVuBQ!SpJtJ%48 zg>?{YzC(GxgBL3t!!@6QWD+sZIbyIg=!OjBF1eq3-u<9hKyD~)|AzU@3tTPH^~Zi$ z7jvm$u{eO5>2Ou8^bpEVH?>CiLr$f2y(_%QjE*q^a9Y&Wp@!{hUKO1kOz+=Vy19xW z8-lQj{6V{JP@IZ*&z6+;k<9~Zqa~oLVS-Hdbhr7Mx$BClNxSQQ)jvg^_$6h`wzY>I zLXyYYHCh#v7pjHjWd}3c$_v~hLH-)=@v%!-9E1}z3hp3)_%dd^-SCLM@mkhTGnD%v zRSEMF_feaU*fb!?4k4XMXrGhrI%oi*@qTpgf0e!qeY@AwcOZQ zh-y;cH0mAf90-qI$R55?;;=m}KNQOLxb^LQ_WdPf;LITa`{siF8Ar{TaUkHTG^Q?`tplOHwI6QBX+lT zh@9@fV%Uye;RwUap3#dPLYf2ZO!U9Vehl(`Il%GH=A*$0d9I%LKU}?KR8;*NF8nAW zC?$%dFw)Wuk|UA|NJ*D;Hw-ZhAqG7n4bmXpFf>SaH$y1hL(C8p@Xq=4p8xr_*V>=< zT6^F7cimTUPBy4GTz(B!e?L9(v{oFIpRP`sNxB#E-vUS6^=B3-=V4BgI40hGUZ$(= zZM&HV9&s85Da`2%;0BF|y^$tU0chy%YOu^*^>C}E-g0=Zo7E4EJ!8K1CX3&*Z?pDd zzM!5E4tQ1MbvOz~+gDU09Qj3jZ2zdbZ4T5^55yp)o3ZL29tQui+$wY5MI(bR=L3yo zn8tPc(0H4{A4M#^`}?00eLWOB2(zi3k_P+V3(fSXkAY=!af^Q~pU*&mA6?`uE_&AS zay=uL;Oo!)9gTX+SmF%s7fTD*FLi+rII``4>f^XUxu!vlV5FRX+=s{uY^MLw--g$3 z`En%2E*GIx6l!ETL6sNzu4+g50D`|On>Mmppnj;Vm$OZ6EK9nUwLQ-TY4mV2-aM~wSVBgHPCQt6VSNNT6HihOL=CyZnfSx zX;2gpX%o$-r_)x(M?ZyOhOG}+oe+J1$l2`>W!;lu(zDqdxO^`US#@&RN<30fgU^qT z#2v1QBy=Ie6WjjyE3XX+10F(E3Mi-&#?P#Q|@5~Y~Rb-Y}@_rIstpVnPS+~C7qEn zBMx_R6PhG^90aG)`vZ2S>{OYpw?g9viPy)}pIgLOM&54ftc6%ndE!n&CU+M~Ng^U{ z_Lw4WcytQ;yBaIppF2i}=dAkNFP*laa*z$QX#2&{7}(d|Rl2Tny}{{Q{a1zm(2EIk zO0pLe_f-O|B>1A-z?oC+qP*0r*|efVOOff=gi)luv!uh0Q))Go``-@=VU|7UBO{T0 zH@u*^RARMh>&$QH>D7Dls;rd`%bqnPD`c0TmRV}DLG22c+}~1`J<`m7E%$I+w5&0s zoA!7f+h+|w_p%iq2+{5tv& z@q>ZRcdYJA4pp%-4zV>Ylj2x3Yw7-asy-2u3-0NK0IO_us~9A~AwdH6%V#F7nXk@3 z{BkOaCgem2|8K)_#h*p`00S-87gAMC^zy2oNeZr4M&)}iLWE@m6PqE7j}ur1~qE&V%S^&gy4&v0gc|;w^N)5uO%bBvL~)sBnLWM3V+tv4hX0UPjwntSv+9@hv3wVW2KMo7ERko}~*`M8;lwXh}a~Fez&F zF+WVGCZjcOGuZTSLS63Y#kEj3?hj5@xurJK$=&s*Gi<|gTwKQ<_hxL2A~tb%U-9n| z`_BuXkgcA1eK_J`gL_#=%+=)S(mX)zr9E~Mcc$kJjFffu6xUtl(`#{Fb(K`A`eu_} zm7L)UH9*7`oy-iBq+F&psSChG&P7MaM=+*fI4IYO5WQa5z&I;bi!)!Gy}I`aB4#r` z{~AEOg}oT0NxIm!;$Q&mTsjj5I*LZeMNmw0w+13cY4{ zUg9gZ>iUmDd+c2$->4m0GL}dahmfi%AqeHT?*Sh{erq zI68Lhsrnz22r6<_ku3Ikt74gEE{-Y}xV6g~{9d@j4I>0D|EuBQSjTpYyPWkvj#wp= zDG~aa&FXnRBtD_fSk>=Tc?CWR5gbloU}kN~c}#lxCNGq)JkQd1B1)H}ij;U=&2n+8 z2o{zG)P-V~r~cbqHx=uEp!&CyRK}bFD|C&T24R>*yGl6Ba{=eX9|l3{ieBda9x1D> zg#A^iIM*?_8LJ9rzw2@jVQ;Xwshdf`{Biz62<%|a%RO`Gj_C@Rmpo!GdCBx~RbGk} zKm+Y&ymu$H{!8P&;5lCrS(5o9bYNBG)m!ry+q`vg{$$PBVEUgI1Me7%4t}EHe52|) z9V=#THDYzF!UjRnnUv4)aBim2WWagwo{9|4c$2@g2*VpL6jbU)UCvnf1Y+=s)XsM? zA+294PS}F(NNt_o|L6_D4y^6l)IW7%Wx7lv zp*o~`jg_&{qrWm*`rC^ajH2X2WF#90dZ}9a}pO8?zQf68C+8vt!IbEIR?>pdU&FJ*q?GR~X6q;pk?$4g|F(*}Le;(tgQkHQX!u z&ru@KsA7{ z6hgRwsi84bYwLoVaY#u6Yt`2}zZosH`-FXp!~Q{b+-uzWbCSfcKX$3*#)h!5;02a> zMJ?KrEu&&YOqqcf@*Dx-0WIHSkp5D_KjYs8kWO%c9&g!@t{0cM|D&`;ObKno$R)}H z*`_ldxS@n`$-_w?l&nLB{Pds7#WYgyO!2%jnJj0(z$-a<`$?zSM{fdM+?)H>%lB0W zc*P}U4>)^E%y+dNL0GeWG00|47-K$O7za8(hcUs@!a+;Ma~O^$N&f z-x@-pRh@XBkVgsVI`eJ(W`Xf+A@W)`&`8P5^Z_5|OU1a8en z+2nC9>Z=@MHNr}Z!%0M9>ieq^rF?6}z}e?b+#k-I<_>8hYbpkv0UjSh(U`XqhF5v= zp8r$_#_1vU9x6%Dq~s#BXtI{yWLaxF5Kb%K&KozS>nlM$J}38;S=(ePOR1nzZ`cYl z4+mT8UClQ{&Fam!46E^-Uj^gZv6v8qfl*V{jl4m?!;VSbo4>Pri5CVgTjq8HMsmdM zRdM~Tbisq@OIXi(D9>1MHZ%8>xk2lfF4{s@l`wcfL8VEv*u2W9&(3A$(7TgVqMG!5 zd9aFO+o<5;wM?|*Vvm5mY$ThM+$^5Ao#1%vQ5>CRzZzqPcjoH8{7rk)= zt84F>ay#n1#y0c~KDerQImN|QWKlN%9;>p;HR^h2qMC7@LN+0Dgc5JfO2!grPM*A( z->Kid%U_{{gU%qC5le^rI4uM#^^c`*urxsP!zBt0c)xXd%}g?GuuEFLb8C7Ls^E5+ zzm(O_T4>M0RPqNE{81VWa}}GOX}GroIA(<(gaT^7aW0(hnBWg7j0{=kKS>W#lYCb$ zc_02@`kqthy8Hw;==(5U4F>FK_c?5?89i4upPOV4WO!RoRSv?Hpa%~x+# zL6B}aM+wA$E6&mjGSiD((CpN7C^a!VU0WSaWGTEh!*3@a$>QEJ@4317c~T%?LS^&K zQheUYN{}7|gRTJt*ru}n^}AW1^ztN@Iz1Qj@8h_G4=Beo$0<1naM0ONo@Twy zh7NRk@4`BV)N>xVHYdik!@qP(&BOf+J6@`WiI6Q)hxM7|#Mj?d+4W4935mM5|t-K#^{$W^^Bq1N&`mywZ?|s3n?fJ-~f!>|d_gs(2N48_*C%?qE zvOd(?yOeMhw46lkN z0{_<{0*^Z?w=C{jJCj3h1#XkD_IF!VTMO$UoVI3`mGVF%wk(?G89zQfgG7x)?iCPS zS9W&WB-ts+Gg4#XllN8gRNHZ`0m3wURLsj? zILYyFdzUU^1oP#mdd&hii*pIAIAR<|7f^U>yu_lzgPuEu@V5Uc7?_N=5fn%$OS^)4 zteRWUC62jj9apFdlg1fDD;ZzC;g*AH_>TE{ME!9Wi8bwSY^{amyWWQ<%htt0G;Prl z4u|OEqSf&>7lg{VqoXxYkh;0e2gR^^WkYfTza*w-G=S`TQzzA|-rWAGC_sD0O2n4) zAy^%9QJHY;ASeh}6f4?*EGJA$TH|yc#aLe!R9+ESGaK~vT-m&o{i!C6%xytTf zK#~G2h;Ne`IQ~U_h5tIf8RiI3iW@Mwen|jiJKnATwYvb#;*dU;g1dwL$?h$n!fWlP z>oR%6sjk33_=P*ZJ*S*%UTe5x{8S5kFMYo6(m`rdx@}LFXj0%ue9?xjeyTi3%O8bu zzHu$>a961dJU{*RGo9j6_9qho6nHH)@#H7ppkx_ypc zNRIsFXn4Q6_CmhAKH>u!fewjz=68VgO&rv_nkn^RavUfn9Beg=_B7$D<~sk`f@?MTXRumzdnx8{zk+Yt2(QTDTrB@JIrKvJwT@$wfzIzN$pk zBNo`E74c^iZk7;q#yY;2d(5wPJ|fYX)NJjj>Jbgr|LJm=32>Ew;(SICp|P*BVti5& zNpMSmzSX89Rn3@mf69@XSFYKw@Xz30mQ4rYIOuDf5%Y_pai$B}qj+o%kX74en)zxt z*hcVUzLeX>`SOc;2A$1g@`sn?sNZLJ4jUn6n9{&Nk8yoZF_ z2OXKZ3**0w(r~8Z^&VE=_^RyJ^Q{C&FY*y%o8W3U!Tp)X!}2X7n8Q}f97 zHVJ1p9R=C5dAREM%q96&Uaw{~kD>`FAOfa~B=WhH_HHP2k@XK!2 zb(Xh947Q{{5(|B1HK`OPWn*M&sK6O%n0{F5D*q$ZMmiPw$Vg+24c$kgbE@NXWEgK% zH5DW@ahSiDa5%X5E1q-(-Sss~L&CNuK(O z(LH7AqUndm1c^$E2RMhDgQl|f`73*Db*la=CNruBc*szhxnA(Poh*CBw;w zYVvE0mBfAA>z_$sjP^S!{jN66BDNx|H+8`=sW-nzS!cIQW-n~!ofofIXR!1`*(hrp z@5K4n&!FELqt(yZ9i4H6c{fl>7opUye4fRb z5VYhiDip5(JohylD8RD5)*WN*Zs$Zdce#*hShb>ka|dY7+ibBg**~Seuz^S$UqN zrH`YUk5oIuJ2opa|1?y;Fjc#5xAe=7uiPcX(7wLk_`OA-qFro++BgQR5MM}jvyUGc z8S8i29oX7oFQbCtXw~N>w()As5mfEcGla}OU9rXnMg^+zECPC*+n5NGo`CkE@|}S~ z>Hs4PbbNqO0l#tc29I=9@5Y0M`pt*dfM{+*n>o7{^ZNT}OYtb9Muu@?*Z8nXSy8J( zUf5#9YQjRPeTou|mm#&;!88pUmtM5~6hpC9O~iEy3tm!dQJ3l``z@MRN2vgP&z{Jn zHxIK~!MFF6c`~5eR!WsDm8jZSdR-wRN=43Qd3K?oYGo0o2g~a2R zp@qEXMV+_uw>aRyuZ4to5{A$d$zTfP zz#xpjaU+l^_mJl|Adi84?ZaP!%{S`{D-W70*QxUR$1!vWQp3yQm`&U9VNP+#sj@8K zXMPL56jDgIjZ9y((lMj_a2LSV#RKaF__c-Cu{JQ~w5! z21V9txhd}r(@C4MVjBK=euXZ?4ivLOw*Bw=Hbegh|1eiYe)wf*b)Qh(@z3r-=-tDd z2xJ1^o9gTs?ZR1ZTfHI)Bd=e9nA?@k~^ zMb5O;5WQXFy*kmclO=VmL()9O1QEC}BC*u>kNwM2uVwLNA%fM!r>nzqEw|#kzau`- zz=t0@C-;#&HO5*u`J?14+gMHIVp)|X!3JF^AY7juAv`DN?W00Bf+Y0w?A7+A02JRr2yG|mcC z7Os4_64_FO$fA8G6AzE-hG zkepE91|ggleoG+gXF~T{IWC0_i#A#vf7ZDjp23XmBhJbD?Y%0TjnMajkSU28AG5Xp zuqbu7pGtmbm{7ZW*ZbzHOmJ(?Q8D?+H}?q}A&QweSYef&y?X-rLam`dO4s2d0Unms zfU)g1SF?E_4W*Het*JrBH+`YGqvOBgy$G`?22*_hA>Qc6R|Z=>VE<^+prkQx(}vI2 zRTv%6QA*ZB35-m?;Dz~z4#o68G%7PK7}Pd=VCbwvyw8eNr}ZEML&{kAl93g@3zbfcAl8&MFs+ zOk4~a&Bng*pXPA;=2A%*B(p@LYBpe{$pU4;yHA%TJZp&c&Db~&T8-g`?fldkpK)4I z{J+8s*Jlv!rrArT~-g75xEF@kZDd&PSs54d(q{3o~YXb-zzzDyy2UV zHV;+mdY1kMHw9`?3c_BOSKxewEL>V=<1%my`Lk0J!CM-UXBTXspkonT|Bom7*#E!} z{&q38qbYAo4#3&R=R#l`^Z0H z(KD2a2U9tdY3G30cJ#xmUL567JtHXLyZI1X2F2X*_1TY^hc;77%wKZU<&Zzx6(oah)y(%QRAV#yW1$1E=_d5;X)65k}#G6M7K>sGvZSyyXXMLPan z3t4?UQpdH_p!7dsk=!n`cu~QFMY)a1ud-o0M^DcAE{YHTVKZSz`)jQfp~9@0?tS(A z7LO>MB5s`LBs+Q~;1jhb8?JA#FOe@)Aa(sF0wi;6|3mu>O8=`0xk7AZ<23K0u?ZpA z?7=Fzkok8dQkp%JL-*%6$s>9#x+-9=Rn+;bIqw}8VYqjj!?+zW={eb#yc%~>{5$qX z0)Nv(a5Lnq5)zwrb=Fe7rc01p%MPa(ftF=8j;q{DGsjFvy+vS3tgbng>r$uTDG(z8ppeI7T^M_!jk!V)gEUC$2) z*WnYukoMQQAz3k5wz7OFV>g4UApFT{XY^>Rw)q$7`Q>FD;zKg3-e~D);FbFX#ma!F zJqN}GC}{R!P-@~-fg?cj;b24X=(*bTHvBfFp)Qm3V7X3YS)~?`%FpG_5q()>`T>xX z6v>B_+O; z?05%tu*R8occ9cu+sBr-ErUN&a)I=WU0E*PJr><8#!DGu43T7+-<+`=Db1qk6I_)j7xJIh@hDsK}+ft^?a_E)8hsZ`nJmKPdFVsqT#eK}& zSNo}nx?K%J>8b7PL(lHLr~d{W2RaUf$f!;E$fJK#B?0D~BlaU#v5dWn24*& z;y6`>U9+Mp*{M-cx~V=1r#W1d)I(%Vm#aw(v);?)ygKJ>0uiG%>*MwKa_4Nsr)FYL zRPcg5RWx{3>?Xrkx{%7q;Lg10(KbR@hP?w`{jmWqzCnxBnJhv^IUTA-6XxXZPa*<> z1`f$^Afsg%wN{N%MPQJryZF-NwIi<>yE;w0ljlIoJ8v!)n#~w7T@u}-mX5)e%G!DE zkUP8$8Hhnu*`PK#Lfci$vdzNQzyI*-ZOHs1eaycmeR0UEf~G_aE+o=v|8=M{Knd)P zUn90vFt-896ag>7{V@UMPZ3#sCyjEw!bO(c;$XWLiu7wZpadBK908b1g6?7Ag>47A%P!0|3__ZzYNdaP^> z*mHHMVk-K_)gWut_bMI21w*>d%IuJT81XiVkYCRIvy|F$T*JqkOP&JXuRg&yis)7c zWclX7fkeK;F$b~))=4w}V}yKi-VyPL;g;qdVV3<(rREzCIxz9yXCF`L-t1LJ5}gSu zKmX(XJhMD3PlLSVeFzBV%HlC_1`&PJb?*J3NrY-LFX3o|MyUCe6hb1U! z^&VDgp9kjn%pg4f98Cph+Y8~9y`X3Y=fb?;{hI=Ir8N%5pBKSuqZD{|v@j4JF;XI2`AYA($9RnV!!v`7x!9#^H!o-SQ1l3wEP38Al8w?0k~be*9JyPp z@lP2PhQ)tG33KcQKCu3>pGAg#8}c){HsP3DfJD5{ruNlS^c()e@cG^VsHPh%VE)C-~yN^sDd~pUqod05IOtNNuqIoEt7G#F!tHcmd;TKKlE0 zJN^LnQY57dqB#Oz)YJzD1kVehtbcOi(%Z_l9wvJuw@XPi z=VE6p)BUyoq{2~^L8mUdUgXp5DUiQ3AWzrDpG3I zB8>SDcOPm(C$PhEq;jl42102g4p`W@@_dpX5vVO_H~P5Mp$3`TNq(Rq{v!&eeB`sN zlOdo2y6g(0U%H z$m$b#L}+E3MyqyrG>lgv#TV*xHLOa`8lwzP4UNNC#P{WHqT~c@;|USruJK=6@OKxd z2`Vm6!a0>7GF51nWKf8!Ktcq@Qd>8Z2~u(Sl+q-k2bH@{NWErA9sT97Qcu5i0Yns? zq&$bYaVQT_3lEMX0y=UG2nALYOhz0DxhNR zM6(Rgt0yA*ZHF`QTl+0h;~Ygr^|3HoyKr^1mH6_i(tIuoUPI}5*5~gO3y!@arompn z-;AE%C7PY_M!6ThB+_6FjTyZ->>`Av3wf=PW>1%%*NclgTsjWjB zE+unwb2O2`t;fsIDE@f9nPTc! zge%+~UBOp2@S?)c90X_i6r!^}s@i|Zvs&K)162KpKDwN0UD>5rrii2muQ*>QU?}TH zRB5F4-@OXIp*4@lM6?2oRKzT50k#t$7{OT`KfMq43dMw4un(lD{!xCq;EKyuF!2yP ztH^(O6#7c!%=*C>oAj)UppYG+Vbkc83))YCM+!&7aR7VBtF!q_@0;98D!)We;5Qpf z)p3lG=*VJ;>pCOq8`VygV4jOCXg3UrpHTB?b zF}v^5Tl*Yk0&Oof1g5-S@$WWv`Cd=iZp$#0W&8>3YIvXM3Em^`o$=jS%;(2VPFK>5 zd~%7>RPJ|{Kn{^CKX8q4j0ZvDaXmqfa|hFtoVZy(R5RUqwGECEun4MFe<#ekl#dss zSY~138*K+T?}aFTl2$ejY`&aBFGpWNSzuVg>!a;*kIL|q(RLL0;~cM<2K@6Q*fCRj zJjgFJn!3JDv&QH&eHW(Aztj>y&r2B17f!(on6r5{DK zoZIB1({8JaAmWN{>3S!3FhkPjT#kPLTR_uF!!& zhA4c@p7e?E0 zX_!Sxdzt7UCVI-MFtr?H?S3hTleZ@bn+ac2`i8sGT()H1v-ae>O8kG!QjH2+EQe?%PTDPX z@SlHB2JDR~HFDJ{M8hW|g}UTFLMb{fSuLUX)Oz{}qo~BfV)krgJTC~o8vZn)V`J%E zS;}TYgO`~{Am6l(^3<3MTWv|QOKr0d%Q7SF64iDN+GK8sW<-^E5uNn3HWzuM`A7Mk z*qJ8c=~5!_yF#rxM~lHF&vA<;7%e6CR}Gk3sd32@J?^kSy78eVm0~0PP?7~8)pz#` zTkv$PBi~w{lW-p-N!Gkq`u6V!?;5qAvy$prICP?Z}T&NpS-RfnczLn*_hVABT06(dK(X5 zIi{uE1{+sc3z&v*4BG-Zc17<2fA`8@Ihtw`cE$heC=SO6m7kL5Hb!V5SCtE*zwaBA zB*F{^yJ&Q^Bh&5&!B-ak=P#b==__aW~kf4}*K*uKa8dBYw05gpa`8!lo}hXm7^dAYdAcN4kwLnq`X#;P#T36{cjL%(nPi9%JmX#!8zUNJ}t zHYF$xHY)w=TcXTI5Mx`@7Uo(!sO-B5CnI?=4*a!|bVWq|gn;ya5J*cfOC{wNJAJ zU;#UR_;yhYcY8iQJ?B}kYe1_DR#5O^E1Pwu407N#^;5%zw27Z6DXk`N>sKyE+w97D zsp4?*Aoc&+fUzVlGgnrd0oO}qZiO2H9VWNGA$7vm^TBdcof(|A;$8h0zcdyrz9k7F2CFsqXFBWNzHW0?Y8Kn-X4VzJD_|& zw+I|iGIw3jx?Nvu6-rmOmCruj^@6^cF=;%6<_yOjf0mD}Cd!t~0yiC*r^TYSZ2aI7 z#LxQatD0H(239WX#vkuXQZz;wIOEkLD*YU`=Q{PmP&6wCf!<$P}) zq8*w+M>Ji10$w9rOmo4X_EV0c7QYUv4sa|vM2cY>!$mj#2^-zx%?=~KnR+3A_Obm+ zqpOCr!KhCf+NY*SV>*<3=BlMfZ8*u=p*twYd@pGI_{9?e4(XA|*5N~2Q z_`u|O4Z;dZUvcHL*?2SG_hLH#O_U|q)L$Hp?v9CRJD$Jh4GiM%$f@9?N;s&kY@p+% z9^%%C4o=Y@ei~d+X2cD#h@XD=RJLe|c&po779o+~-ys&BB|j+SnNvjIr~FkoILF_3 zkA86b_`|?UGT(TD5A|?LsXwrZCQOpeMT4@B2|1r|GsVY-t5w0wuOiw zPtcI((E|<}BQ+9$&b-3V?e7IySU&GOLcYZ!L;IO*lnixVCcg`9$u`I%|L<1|C2A)kqR>i+W` zEZn+nB7sj&HZL=2{x)X=+W&8-5Pk}cSM$=uk0Dav1Vq^}Lh1jB1+m?$3s}zoDbvbR zheP>fJS}sSD$17?Jm4tl{f&Pb&}Ut>;%OwR6h`6KUn#LZ`ZDpqkSTY+s;Kh6FPsh% z2Nz$>C-wF}P`UP538Tkha*k**KNjhlB&M!5S~8#Gu| z5>5L~?py2)9Q6GWA6713fr)ln*F0WG@v#i9PgwfX7KLN55fop`{@!A?wpKdO

u9xg$5@ZubaeHtOW19eQo?gEqd;J}8onh8H!Q4Q~aR|0|27hP} zFHe?B*N^>9`tvF?Ig9<%Td%yUeDYztPIRA|O~N{cQdp^dkh+?;-}+E#-9Q^3f0sfg z;B?UglBm^Ck={KFes&V)y-2$6rr?J~_Y7clqEKlS6fEh6W5wu?-O>xjrK;~ps!<)E zeA<~)`1B#VW(?_(#`G9=Y_f6W!L}}owk-^2^9gz}ei;Iz}Q0pnMHjkLG zX%~&_6Ur%es$rOpc4eo8#qpLwS+A_^HK|maYa6$o5AO3kNL;^MkA^0+zxUGh*hP-| zf^Xfu2lO~whtI8ysmLGrYs5+KDD@o=!R+It3(@_PGt5xJC+Ii#n=u&!cN*4Uo?T_)ej;#3Z>KgF1$Z*i5Y zH#_aCf}x7r&?q+SX{l)Nt-q8s-r``?q^vwO!K4*9m65VVydepYVW?c_oY_CeuDtRH zT3BH!1s^^-O3G8Cvfa&zJ8p9M&@_(kEI_m97)akank;{f<)5rw++fwW>v_2^MqAIz zyxZKczFgx;li`UEpi_fOY;GR4hxzdm<8oHAS11AHnnD*ssEoA5_7?}M8Ep6EcFHpr zADPxz@3#vcSVVS;!FLDxLv0@YiO5(98`CRP^%Aw*h2b^=nd$JG~0i{^?_Ygb+v?b|vH3}H*z_nBB60c*;zEcWjN2IVkxc0v&q%vxTR|REJ(Qo^-gbEdsEn@d~^K^c{UAjWd(pOl^|orRZMboQ(`D zbL}me9A@?vWm@`T&uQ}zG6d=I{;#R@*an_|Hi06Crp?BjNP6UoH1XDb?e{RMhh%!+pW znN%Q9H=7JK8`MUp>W>h{sAMnvcXB^$FvOw{fSIg);ZeMqx?OC!Ln~rlGx0NJj^hc z;u@6Da9JO;-oN~p6TR!7ewZoLLf&1g;=d{`h4mky6PD|w=*_caS?@pl(Qr|{OOx^6 z$!^rrnP6$1s5eUq4g*tYJ_}}3rn?|#OtIQbi7UM|F9Q^sP@Ff5Qd>uWi+8^A_f9R; zmZ^L-?r(SMd}&uiK)vG;4~l&N{ETpm)A@Lc9^>9*(ifx5{(NkI>l+QC+Sj+es6B~N zH9sr8dAd|Q$%oud}+^mql?LUD;6*HEWSK$ly zxO3L6{VgRD4Bo__lz(h_V{D;iJFohgyy06JdR437@Y~JQic|C`Rs2{$Hsw1DAraGyAg^>NB_KXxQ#S1WZ=tYI#y)Sw$i^$8tcX_8rZ_N_*~;a8aVx5= zHq8!WrX>o%*Y#h6+6KQ?LW5tIiuZc7HPmY-9~E>yoZAG_EA%dN7SYuq>7bSNVI*NH zd%<7G-wrNJI2?**0`%~|WM-^tX`}DLo=&sHa9Gtpj{bOO;UG;SDuXc5&t5>s1rFI{P z83xAKAN;Sqk+_*M(^Sjl^P6#$y(ErGJLGomxBFfZFlEYKazW-r7?J$kt#Iwlj(A|^ zl6GeA(;Kw}C18|;tS=aI{hMl}YK}F$IXw&Tu{qBz?;F3M&P&a5@{SyZN;Rc`@->^! z&N*X66Yv~|s{8nqtT{5QFvT*doP=S$Y+FIJBCtzRft#Kr^`qAArx5wO>fk;0hgBS1 zrUonh6K#Cc3nmsr1Q`W{~qVv;;!E z@{v=)^K=-qb*D6=TY9`xwrVC=HTs5@uEKfpqckm zeSs?jFnB!bWv+8I;_Qvg-Liko(Mw6Z%GFp#_@)V*3>fF7zrXlqY>(_DiuN#wQSa}13Bj0UtgxP=x_L-`0 z+t;0%4)+FPZe^B(XfdD378W2|+7~^Ajr87+PcWb=mFcHso3E^+k`Z`&k_O#BDIXKr zDOu>(!~P1Ub_ZV1%+JEUGfc8>3ZN}xi+#tnEz1T+dZmX0E2a{f>uxB9Cis@toBWb; za}|?fO~tCZRie8EekW~;EkE)cmze@C^b$G^fx&%Q?j95$gD}dJkdBWv0iD__PMDyS z{f`H@iVWMLd=7;b$NDaaI?H^TnTtQE@K4v7^K|;HZhUI+kZyibGAGi0R}gp;Z|pqx zmDk#$p!a@sG?Rg6)%R$!zmcXiL?zQFkIL3ZHXwE=ux10pRf$LNB_VU3d2qR&iQ=TI z&pADnz#-XwV370)jeT@vlX;baW8JlEGvAvh%7uw6YDVcFc#3>q=|l+xTY6TAu{8fq zb@aTL!$ujt9zzv3t|O9k6!|G%_?PhZH&99E=_b`1)tlw%n;* zu)d=vRkm@xZ)9VQ-Iba$40P7=MZny55>9inq6_c=ZrnQ~Ylr<%rL54cseR%ZtJ|9k zd9Te3j5BWmxkQIFXVn^2_u&2@l18&9b6fCzEJpRc;QU!}sVC=D8!zAQBO>YDrTq!x zw$^yWFNc=UawHxsnFinX{tNB^-1ttl`>?W_66GA!$;o~mQ3Dj7;V*X zV3uPAUXQ*(i_J+N5Eb1E!GoP&tYrIsLM`HSg{$|oc+Lafor(%eWfxrd4vaT%YIjUD zsoWt~0=6andqwb0Mh@9}uCq&8Y`RDB)5-vV?=gG{9NIy4^&)ZbujSI3VEq8!c9a2O z2Tf|<-K*^XRSJH21-wNjV0Z73ok^YOvd%;xZf1QLAEI}gq7|)LBE_ui_y4i?m0@jd zTf1#3(3S$FxCUvV6f5qb#i4j{EgIY%f)@_Hmz;L4Om&h>9jGd!yGG|Q5{nS3&%F~G_k)OH_{iF?&-D$G&K)HVF zqy=QkE3~wcub&*)LWsDX4Ab$5!Dr6E=PbETt1rT<>YIuum?o?wVgzTLz^Gz6H+UX? zC^Im@e220G?$xTr7HkIol>XPar()A08#1jSRwLDkxmD1GA8oOz8uhqdPapPX_c3{O zec>am05}X)e@*FzM0Ia-qsE!~g>&*wi*t#|w6uA4U<-gRZ1bnU;Xz(c4Z_d9W7iD- zpcdM#qi3JFUb<9>ex%L^bO67xWB5rYU0FPXZ$b%z`<7V707!5pW!x3jObRSo($f`N z0`J$R6*$gGTNv1mE>W?=jX)z*fW*) zPKA;~E%Z(dpGnc32Nsi|^$JR8*28%;h2WRZ4^R^25O`0qOr0>~rB1F7}ARmRcuEJ+fc_FdZHNzS+L*dCXVW!Ts z&sCVOltv+@FwwLW2o+9&2=n)>ay)*opVi=uF~{!)M4acG=Ta-lh*$2ys^lhvB42`X zb>Xha6EN<^&|=TqTM>jQILmd8|E@f#Ph!jh(LT6A)IfsqsfgN%6CDv*Oo3hS6#t_zRH3KiUkp4zdY6nO#zx$EmBR*(_@nH@Qt~cl`3+Wy|9Q zHrYj{^c?Ct?4ICR8}G3iaCpYnY3zugj2sQOBJzmPhfumM3D#}3$%#-Wo31I}KO2MHCG9ztPmxf{-&dxq6&nAJy{UyiQ z$Y`y59O5wLJ1YT#dwTA;xjK;B{@{;1OwqnuZi`go6j&!dcO>TrzbpX*OdF;JEx;ye zy1pQ?hJOT3t93Ug$Ad>1ccXWzw>K=e+P6(Y*B>;tU-ypC(lT)^l}QhWcW$te##bbSPJD`{lpI?VKl|4BQ{fvSqfzTB$Iu#nxbd)6?S`MmNQ zx^9pZRI)%0N*@)tD8Q6wpiU`UFU9Z*`~a!SZyBHfx2P&qi?!?Y<@t!I_=*#w&HTo* zZ_r2mxesMRx6>6>aeTXT>n930hM`h53L2WD8?j%V_M_qo-tgAFBxcgxe!#r>HF-{< z+$gn?ufy@F7yQ|&DVC35ctE@*?oDzd!(*MOxNmRj%HP+x-1TmzoJfYWgkwfb_i>j+ z`m0NppzJTY20&eIo=tVnI9RLB&U|V40Y?$?OhwivCWm~H1fYkaRS(3_I z%(@}$Zs##OcAswBuj$h)LgBqHgseJCa#VOs z_^UP0lZjI`)%daM+figBin($b`MDyyoX8gQ*1zWKO(ckUdAUU+ks%;Q$Ac^tUDPTC zjK<~HYD|0MWlGe`80eCWmczN*9i7+cR_C4l@+uZjRGt`_T&w3PyZNhp9_wuvg&$+H_-zk2UpXkyc-0t3+KVr&9QN^J*^TmQYykxpnoDJ+g<1{UA z`)rz$1K!ATZz_q0l-C^L3zp8*BZ0X2Jew3~trP>{>8F?cna3L7!nsoS)0(q> z8&j8uGg)}rWiPz-etKGk@NpHXb}}Ee@6;u03~Ct{Gx;IUXl&iA2LVFwt5I|bS7k$BKJFDC#qzD&$fc@c`<9wOejI4fDjp1PvNzty@z)a%R~J5UXP>< z0pU%{W7aowKk!zL3wDnvIPY$G$1VH5Q&*Biu4F~oQqxGq7gE&;tbtO-`CKT^Twk|p&96z z6CNA(3?WqKe7B8`JcN;4Sj{IRfX_2!n%&|IUo{i9`BtTi+xAz0*jZ!N%HXw`;Y7a>1*VI@|aEfb2tU!)NA$mp{(_s7N zNgv7b?rZ4=y|i%&T#jly9m#A=fhNbwwQF<2 zOww0DhqiUp?kzu)VQ-&BKj3aA^;m2OKVo8FVcD=BH!yzB2<;K3%z7~k-==;>(QM^m zDQD`By04jkT~Sib^htj_xSjDjB&Dvny~ka8gPb|o4Bj6}9`Xz&LjG9WY3V!Jm*TLX z9B~ajq7H(agSP~SIYte)W-pUh+7~SCu+6}Bl?s8X)JL<{wA=c7^wjk&fhuj+IcI96 zb!(Rf;gJ(r(ifB5%~-ECYd&>YE!YZ=2@gl=oDjos3sp`sChCxw52DORbV4_jck>yZ z6PnmJ3U>=wzp9pD0S}%Mlh^T;1YcY_zHsoeEj*ewZ9pvouByAk8vv8z8uO9I} z4B)MCa3ufi_Ia+Ymw-p;|F(qxynC;O^K=e;mH>{+LHaFfAfC!oQSCSK_OX!~E$=X8bii4r@L$fr% zH-p+R+@lJBWQm$wa{?KE>3PTE{d^G19wW{j`o$r^5Vr6DJBb{iRR;cwJSdqF65iu} z^$N4j*|bUZcFXl8=p9c8WM|H)R}RJThz=#DUA!c+AbN&%2j|f{EU|d<95*BmN?lxZ zzoMqkaf8Er)5oaD5|>#>tCMc|jbzvET6cE2JuHtd>FXfqWYtk##Mm|>WGc<{wkfms zBe6q8vgZ$Myzyy*x3G$ty98@0O7?CKPV@RKh8{ThJ~+oej=+# z4L0Xb!t7Vf;DCRtuq$OEUgWrp&!QK>#)Kr!m&wA5ANm*8rX@N<09zDq@Z*$1Jv9n% z_OXR}AVOed1=47x>F@VmP0%jVkv`b)eH3Z+F>5_#Hs(oSTRi}SBv`$ZeQI-66<%SA z$9F2lrERm9G}RyG9?VoS+a&C(pC)3$$)~(HvI-hGE1@U1C#EJ@ zyt)m>Ca{mq3Gcj*5RO37iV*+D5|<%1c|-z?+hY-qkS8w$gZKvC9PAO8Sk-hE>3~+x z1f`pUEVdo21ozj%Z9rg>ZIaLAFMg$8>Y>WlMY{UQwH|Y6=fTjf+Q)aMaJT$}56N^J zc5Tm+HVqS*|8(BS>=Fw?9qsf| zmzBjDvDk;BS@}O<-@U zf&X0Q)95*QU6x$-r+Bi17n!&Z9A+C!>wxFPoxp^!6G!i7u(tsz@~@(xfZ#%_iI8Hh zV&>$)iDt|Ie8U){*RQhwj;O$wc6qI~l7B9@kxco`T>1B?)1}+abxKvTr zD}To2)bGJy4*Tf7@#w`RHR>~N?cKLkvhE-Uow4{UV+>cki5)K=ONJNEuP_;ACc2Kx z4n9RmvEC;g#{FJOkR=P)@7ie92KrWz1V^0)F#Na<`&L%=Zs}~w=*^>k7tzy?h^Bhj zCfWtgl_sL854b&=3vM8)ms#a{*9k7KpdiE+2}`DRy{=YLAlf{;ajm#;XZ#U)3M;9{ z?X0GYGY`EXB~!~r2qR8!XF4*uZZ)(THdI@c2(*T>95Qn_ajC^1<4U1pPH}_CYRl-} zXIhucFlBS9cjpUFe%V3()q{M`mPP#)tt=h7DWBvc%O7zEm;=p6INi!^u zH9gp8v3KQbY-I%;bke1-unc~1-a4M9o-|9ee@0HjOI02RFQ;XJ20Ekg68Wnc!>$x^cgrNEioX(#^SuW$H)1WzmmjiDrgO!l}4Sm_9Uas>Y zJH)g}Mvip9#b&2s;K^W8Qz&YIo)s*<@(Wg>$A-l4C8c^oqJoLs$5$~aKI>lq zM5T=UV%ji-lODsysf9VoH{gC{aFvv#B8+|xT7-5FkNHYJazh2tIr@ z<5~--AcdG|%U_gh&2Ji)9JlQi04RFru@``q?A?ToOvLnN0_v>JgGc4! zt9M91xpX%zqkfNF@~V;^uxhcL(O@1n0ni_c*6Qkz9$&b#Ui4# zu|H;IL3gBx*GL!FMcy^h%+WMtacsOQ4Q}dxz!7tJi;8#@<}p*>Uz;ww=V#m`RQQNP z*bMi;&@MC-c}nBK-1y0Ni9-JbWGV}6|I@n{JMSG?eXQ<#B;s(*J?7a9D2X0X)a)s# zH012exuA%*#wzP_LhAlG(_ux9U^&Z|m~(#LroL9-t+v20V3nVqoq=}xvU^3_!Y8sQjKA7oGAutCKuzCu`;%Gi|Y;DP?rt0;Ru zAy$HP_!dm>Nr{ZU*Q5zNV`E0^sNBr)juD@PYT7`hyJVcwghZq$a^Dfrd6Q3F!H7I| zoKvEjfy^VgrY&6cnt1JhXuX%!IcdHkS{Rs6E?=oD2Dw%e{pl39;CahzmL&6s#)y)S^4_!!E}~~}nefs>iAGqgE9g3f%R#17u@N8!y?a87 zJVh2YYFYADI381^w>q3`V%(4|bjj`-P)Xf#^ z6XerPxwXf`aNK-LVMQcP(ns%CO`F+~4`O*2746I3Uah-*HpXN3JN7>qw#82|M88bj zV0NoB;Nx#r&^HV7C`v>f?0>SV6;C)f39q55nO?>do5tI-6_2QOJRYZw|JvH0ZJd@m zl1{Z^R3vF%{TSo{E zK`adGIwdDw_4As47;HO9jqhFalo>ROyc({dk8yIglS>jwlF^*hS8J|RyFaDK_5_cF zX!8V>Oqh{B`~D1FuaS`b<*EdJ9DQO!@9bNwUdH}+qpyONL`}Ac$Bj46Wb3zl9AJ9y znM4NXOnONJyhJx7s=~-056SCf=p8d{HNq_slj0LQelI%@hfE1FvPrAhwZnqaQ>uPI zJ30^V$&Y5*&K$!uY*4ioIKtiMVtcE1c$hxelKG%6es?TXs01Y`K4m~-E~bsL*6+ja zMTwhoo_7(@DMf`A2V_)~=V?vSRS4~kW;4C5bxq7BvLZ(0OzlLeAF}KdGCq5r8#__l+VDTyJXbC|O-NeRY_Pr!%QUNTRS1 zM^Gm#v;A60S}S;HTd#d)l4iT9u&MOrr_2Q|-W(O|H9SGxm*OSnF5=8OyPO3Q9bl_4 zieSceJ|x!r4RaYJXk86QLplPM&(W|ym`=CuCwVdsjapTmC;X;9L;aM(HEI}Vs(MN= zkA4(VhUbxwb;xIFuEbdLvzA|MOM9n@DEKlHIOE6m-djH~dCqG?jZt_BUnN68u6^FI zHN1k{NZH*`V$g+Itrb`6BW(|-P-ao^SVdL(y|DE!`(DGCdGajA!-EG(t*{+K{qbdU zv9vc4XXHK&E5j(2G*>$>TB>-W*Fv zx-dkzwS3F;BPew@5M*>lRL`xrEmcQP zw|qZv{@l=G(`R@;&r{7v$po*NMi_H`m14~JM^^@p2k@$VcSiTzf{5I31x@wrCMkNx z;72~#F4g|bQ2^xxQ4Id&z(kc^HgeQE2YVzs?!_3FpqAzwISr)47(D{bZM<~s!XiO$ z3O72M_x*~mpV?i$b6>?_KpOdZm z^1rM8BtT`E#c*St><%VjC~_ghh#Kd>|1Kq-zF_)N!i%qN*K(otB$2~N*vvX3_Yy)y zK6_#xmA==p`pwrcc^0%f$uWezaQ0Y&wD9b41Mf4BEf33{%>hrTz!3TKibF#>!63{U z*8b77XlD6@w2COb?9;-peNQh0B{n+qXElTb?vU7?%S+*&Ehm-65=LN;dZXpuK8T`# z09uwK-F50IpGIEnn#5UPp!@}EMeLf7p96m6TSQ$3HKm%R_bc>8qfyDqL9&ua$D#mv ze=ATtbY=dt+(faowE=0G8YjRKLFAxnEwe?t-K$bfeu^?@L!#)tz;dNL;q=~0+)HwV zwP3hQd_&@vJd53qZQ>o2`ZdaguAQaHJDPQk)tj^@0RWUa*M4mY2PGv+2Qc*Up#GwJ z0&{mo&={g)rwXR@^iXR+o4+t<;gg=~jK2d7_K<3TVs z`k^vfN&JO(@$OY zMwlJHcEL@$DPF68Vr-~6sJJlT-c#SAOC3Akz(Q}!=?pQ={$wwq z^(L>{@a*^@;}4!xPtGL-HTc?xcU8Xlb7XL~?`pJ0P0u2e)^n}RFxJmlS11}x^@@sL zpTHbXQgq-D@Q>tDuwnwz;}I_p5OCDWQ9B_f7>a`4v_FI6YI^3j8Q=JgEzgYOJBrpp zeWW(aICeR6e1e`W81!VxDyW1>D~QVHs(7{%y?^g?%&ei$e}v$Nstbs5T9h#TK$aMX z`NbtL=346P%_)C@Y!|wA%_k)91(lybOq=iZhsInb7NU2aereyg2jbB z@e2_la>czRqO*nOz>8!1d)m&c#cSMV$kn<6%L6$h!L~%K)ks@GF|5=kza|*x&T$GG zEjLbca>OmUUb@tTHFn8LwWuU5I2`FixG^0$^=qYO>7@);hh*0e8kMxN(3R$>w>|+n zO`Owx9@u8HSfEK$Pk3(AKPYHjUDqi?_m5DAY86pgQg{QnTQ4=%0e0JX9W$i7D(^w2 z!>>^z5e+;ah`e!cd4$bO(@x8ndLgUofmJ{5@DwN}NWFtTC>$Y=HD#F6pl43%yBjh} zyWCoZpCPooW|=3u+#T)WzDKlDEFpacD)dg#jfGh`N_cT(%88wGG$*`%^S(Nz)=*24 zmO)6Wq^)W>-ibs1oNP_KRb*Gd2e$aj)=^v)T?cwgT>4$jE@L z>{EF~tk>lUbWI{|IGK1 zZ@CVbG?o4}ZtmXPbvDb`7YqecuWPVV^B1uOGT*LDvx)Q(5_-u^^Y2a)O{~}i!e(K@ zFNpES(i+RKVm3kpUE*u$x8$_uVyzid42v4}YkIyx6PlAY+3 zFH!zQG8meb*Ymo4_cKy4r~th+SK)|l^vk7D(52Ca@M)8czs2@3W9=e372p%ky9HkR z#rw^91y@=WanY$88_I(qBRU6zKRR z&^^3(COH?FwtArxXWX5eGTNYzq=M#*F=<}ac^>NPzMZ#{cj-cd)E%|l+d@ba+2ygG zzLRW&-`GLFHFC4P)9Cs2GG2yHq&;AJ+`=I#YWydkAFME zbk_@QZfxw5Z}yDV`&r=K>Oz0yRwqdx#(aS@sDSutVC7vPkj}oW$6*!g&xI>sx$HMq z;2l;q%5a$AbXdBF1z2((RGJadPhHFzWD}HkWRntD+y!)~n#Hm?k_5=7_--`;%|r|c zbm8uCCmUbqJj$nn2)ONd&)e7RW%c<{Tjmr_O+UP?&2eehUkZ;Lz+@@h8|TQ}C*Y6U zJ>&@lVo-^Tp;AG`re$P5SM(d$wIw@^W;0T3V_XFhjH4tF%Pzep$Q8&cv*Ehi`3_Cl z;S8672IN3VNNC8B2MMDYGtO4ftE432IF6lpED91_Dj3G+pP2Z;1{!TvSK3cqlXDD7 z*q%t0eAq~^1O=lZ_qTkH4zN8_@;7(Pj6H>R_D|GX<(!q@P2EPJ6wK!IpADZ|3OgIU z9LK}}c?=qSyxQv9=6Ww7&Nh+F%L^w_a3QYRA{Gv^3co_Xx**tl!S5{5)FhY zzE3=NDtc^;H+`LGX1Vp!`A`$vcwME(^1b=?u5{bWQ}9CQx_fp9M;hX1{^z_Uqit%Q zt!%gYQYTD__ipS3R90+(+%nz?I6)h71dIla~J!)VpH zZSl|(3}NNywTiC6<{RqfyEedDFAGZrqqDq41@&Hf9{zivkMLe6cvd-ycSzLAWgg0t z{8}r?ggvFdf{C_%=BQ211LF{u+pn44dm?dm>0#W13K8uF6?Nx|00fVM8plBVa%gyb zfqS*W3=%VYw}EP?oS5ja;UP}QF_)LkqGl(M!_qfJl0s)bmhyG-7?|D&AD#zwxn#-ORiP8x3Qowegz`D0CADI-?bo-MNF&T(9T8i(5$(sW9N` z&%Gk8{08b^xA*wEZ?;4pqYs%9>SUUjsZAq`#kU@FL0P2_0gas~ z9U;*rjo_{>WYu4R5@P{)0WhPZ<}-fhN4bPlbceDmaI{X^CXH7q}_=Mh(s1_6kW_*zGKHDhk0imKho%4kT7hM`Xs@S|uuT#`ja|%a) zp?^1GycoIV7@j(1h==i>C4UB@AJ$)_uGif``7PT2;TBHh=k(FsTNz7q{UThn~YrqVht?dlN^ifa_8zv(c(7it2IMZ1w&VX-w)Lp^{wp%~yv;;to0Q`QY<)hBnP3;Hf^ z!JysQX1MK9T`0fD<>zq4(JGaB_}20rs`>${p)pt{*8RS6rL1WMiHBO~%b3=IJm;v7D)pW? zTFM-kyH?x8QIPsjx+;T3FI5uaG)iWgp;-$j%ib``^@gT~zXVcVNaP!#8*9MSixw9@Kidu^rgXqU5N3|*VU>T@zjOhohxfY$ow8DEBaWiV(!H^-m39iijiFr?T`n0yz2_M$N0;`|03bMKFoPhhNF(G) z_7IE}nWXm2o`h^g?8>3dgJcqk6L(n2r_Hi;OM^Ay+$8#290}xu)IxWfb!PT)|7kqC z&}r_fVAJp;X0cUc9b>S@+WX>)pDM@+8+NmV{ae^Ur_o%b#7ub2(2*lM;sb!=4~L+; zsfNqX#uR+8j8`(SSC)}@1*8`>7OV-Ca~&eaO0G||l<_JQU0c~^MzfNFd|R(n~o=b6tz-6 zw*o2dm9(OF*yIaXewNC|abgxAPVTbaF8&8~0p|iOQKN|F9y^h%zoj=d6z2}ID9rk*M6eIU9~l~v`H(0zx80>eCz|Q2odIZL z<~*e&5<6n-hm_NkgBGy`Bsxr160_Uhn~ZD4sg0E-kAk{SJI)-3hL=ev-kjw{sAbMH>buv7C!6ZQ{tiS7ys1tDu+|HmzWRlh%fT|RFhJNk|k1tsIyVXJg{jh zF=wTaH+zKHEOBjLyWIbqh@Qt#WP08e&*@8L2zv1#rVv_(0q#**eB#^$*^9HtkO7=n z6fJiWj=gr2Oa|>wf?Ddb@@hodkDRmn-;j=%fI?4johDXOtR|+npRI-Sg|@?Rql!s& zUlwQS&^#qUHT;^vjN(R=o}blA%wKPTLtp#dXK6x!D#>!w&TwtyKD<-;A|A2Tvhx5Q zyeU6iSS*KL1^sIltZKAe% zVMSd6PC2wpwrPHsC4AbBOLx4O@wKkr?vtJlV7?y|wEi-x2 zA0hGvkJgZjGeH1vJbE#p_w9={d$aRo=etT|qU3z%{ldrzT#3^B+(|G5eFAKMM;WL| z{%Vz@`s@3gJCLA` zF-*G*SJ+sB%ERJU=&<_QSt7i<&iC1odtc=66lM!C7oS_vZ@S0R@__h9F`@IJ&&OWD ziS%DS#NWJ!qxch{;t4?S_&A}>Jzkv4%Y=-zJb-r$!23o@R~M-|F=Tv>kpT0ypY8~- zKVOhNNnN1qPnUBnlVVo?K^ypEl`*A{z@R;W{Xps|^j?5*b5Z)jUEDUc*w5EiU!Td> zAU9+Q(hoNJS?zvg;7&Zp1zv4*LqWOAEIrGw36k&g^JvK4c@@bSgqR6wo@X8#RxxiE zE(((}3}`wEad@@g-W;2IUHtf*sBZeQ5nQ00mcMf7Bk;lOa#(>i36oIT&Pw&U0Y+?m zy+X?iBK4?ty3_oO`8UNMqc8mHiqldwT23xA*`^>RB{<=m3DeZFjk&==p$GkfKL?ln z(oxwIndGb8_?Sx;b=Ar#Z%9CJf2aO6Zdji!wx!J%be)AyC@m&L25xCsI~g=!a%RR6 zY#FA}mdDQN_Wbh+>|WYm8BogUpB*yW&OPLiukN-`Bj))?@_npD-`;~rD1xZL9<6>u zr*+k{FT#BFD#Yi+^*newB32q_YrsF2Sd9F-wu?4Z@n>mzxIk)(H+2PZU&EUz@mR@$ zc225w@^Qxz?k~W!xZUs-r%g*6{Cqj?#FBp2{#9y@6g!#YX?I%ZoH)x6*Jl61o7a`C zQwL(J${p8M));eWHag(VKto*raO*41a*G8=fu>w0R0GR%S)kd>cbv^to0OBiOX`Xr z!Xd9=n(55T8_db!Ih+!hgL2&!PFZ0g6TIh~jld4|1S<8VONDDj@Hvr(rJPK?H_XP zCVHXMr>NAVmoR9x1ev1loH=V7DzGuirh}SNDhWfST#VwY!ab+7k)xTW=h+@ywM1Za zl{}B|&!;cY2KJVK1}>!dX#tGA>;A7y_re>9<(W~UzpZOT$q$_eMvKWhkiu-E&xZ}% z>SxemUTflECDlp{H>!>zSI$OY48(3!)K-1@Wr7%WAe-gAPS2TfJD8dhvdY5=Nqgy< zfi_`u0gb=c-6EQmCx*WY;rfT1*M;*t!a00U^?O#IYA304Gl1au!3@H?*Dp>uH=IDq zi1T~MjlWOY?fb#LDBM)5vWetbZ5ZXT;g0iJ$dpv%RBmLwo%^y#sIC?RQxJD8mi+td zMg|P|;RH960}qFZi3UA6LJ5KfP3+io_voZUCJhLDjlXDnx-tc-`e~jPC$OdI@_h@w zn0$!o9j^_3fGpAhhb-wk#7#3jdOi$2+myjPsWP#M#murg{OT;@ZnktB;>fCD&BF2J ziCMQ*IWq8B-^1LF3o)7tp0h&Xx})mt#62>_R7Ms zX``p+UMcFlyfTi?$BzBhoB4umO!e#VtE~sYg3z}Z^Y46diq>;C#Z7E$R=D5E&5~L_ z;cl&s7?;sY{EAy>HB8Y=I4&@Xb0kLSu{ko-!IaGx`U$SFA*uA1dBbJx-K+13n4$<$ zsu<%+);!Hw#z+|H6Grlh$ImOZj2i+IXrZ}7sJdvk+O4MaqVk6?Eq+|pUmR|owMiwY z3Fp#RJiQJlN6b^t4mvb^)vYHQ`RLRXJ|lKrF<#v1c&w9>Ssj2uSc<*4;v1>PWxZx2 z;h7hVH;gLK7u*f-U-3H+nGD)HfB2jDFe4k>?zxrvlT$4`&tmt0@$mIZCd_{QU4ous ziwW*nrMQ2`FGYg{T)a zAP>w>?(7G_p*mxFI+u!rK~ro^ATqBT**`t{EcP2tLfWjO0Z#XSj@y43sVKpAV) z`#M*{vq=j>#`qs1Q7b>m1}VILL3ZWz%Jyl2j}-o#S1z=<$0NCjKMy4CMWq4B>)+Mx z?aCDx=y>%btIFf8nuL*uoA(cL71~cx*n^f&XGyt@^Jc>fnNiVJ9gwhKSyl@P{FVbm zQD`l(mW138`A%yxWPFvbzWri+rO9QV!P{9IvHm!v#2&_%QmR<=Ws5ke$8zS3 zjP!DZ0DWpQ0#yjj?I#74YRy!*z*s)#%BL#(KGCwdjl}u_2{L^M$(1Ob8*GBcV+)dh z816s5u3Dc=oa*h!?*b0qzg3O~L1fzEQ5PO_>Cr;r`l{#XQ$zu-pPjKcw>|X7=FVIp zPL!Xb1a1HkA2hr=WCo{>2GS`60{T~1(NfsOH+VDc^aYTTL8)|j+{tqkopic`DM5GQ zNL7V1$C%8%a;TsH ztXqwSTBiMZOQW92g6PsY-<+CU%2OkF%2&qJW4abu3XMS-Q`ZJmFfclLSa9FLH`2UJ-(vwed{<19$kd1y!P#MF53zy# zG?nY%*-08wnz>ipJqaNtTCFf=x=LpL4;gEzjLjR%y6M@p0~Ii#;}u4aGf3^k8BUfv z4FoE*gR&ry<Jx%=R%1|kVbrW;eb`v4hzXYBeb?>73c_aQ)jkWj^KD#S=*tCSMi@Srv)#93c;3^<(MFZxU)AxPtE5Ka-x(0rTit!#{cdS`}2ga~9r1o*SqDR6iD#(X>HKHH) zNS2jvwX_LYIuq%}a9BnzNB5>u?SSROw-Fq={X-VVo1y*gs?gXqdzga_12_N6l$*t0 zTf_g0a8`X*^yUFi1fobyxWYplLwmE#Bu_tPqWA2v7JPP4{y8;jhXLB7rU*MFOlbG=D~7k{twUFZ=y z$g*s@+WZ&kp6Um$*DbW-BK{nkf4%Cu&P15(?G_~n9=*UyRdo1~zDI7-K9DHTZV4T1 zd-}8s$_BCoY}LlIbDh_AX3TOsq|9#52m+(&d5dbeu&LzfATMit_)4~RAysY=X5lW` zaOU^o0*eO%h13wV&7T_NNSq;Tk2b0!62lQ51)Wh!yy;FwvPY`{DXq@atje!|`n zz{Y~vy^%GBCZamR=9phwa(|`yPl4!SUhhp`0#-J@1z<0~U3=#& z5m9sAH*AC>tQ%s{Kwf=p>7eWT| zot0C^hfE0SjYQ{Zbl*sp6RHd!Ic}`@Z0Ro7-Bg-BGs^u=Fkq zgfHU&2PL=N-Ve%)Hdj)6fDBt@ofNg1i2}iaR39(k6yC>}{6Z)^x=VdUNGz$WyPo(Io1#;^)TBR&4X${A_|xsQ>lX#zs|r24deE#` zd!`wntb#*z_-wS$^UZDkf|+oRZ+0ETfGAn5Yy?^5f%iw#s1p?*rv(lTIkG52k1ma+ zq-6~W-h*RBOM|L5;skNNfzLF*1adjO_#Y+nn~b`$T#qsVrR9qfGLA0+7%3buZVBFG zWc_51Jz>D7DDGBl!~{?mtUXPdG4EFsiSBkMP*F?)-WF`@JFkTG_52p-MRm6Rt{{)r z8^;NA{=-P<`rxCtwen)a!z}`dn+yhjYFkyQgL==74Vbja>K`)n|9aK}*=1GO#z5uq z>w%u%fOw-I_kY*)U2_+0T^5PpZpSd@|1jZKbv|t13OHPaTM#<95>zhSb>}mud@A+P zKGc@zV&UcQ?NOaST=<~6@Xog?L#IAqK+a^D=1-MZhy5?Jw_hhOP}YsCil_GUvh{OZ zf4lJ)YN147@wI>RlYZ}NRB7~Z=@r-)GAw^pLRE@?C{u6#bo=Dla%Uv}Y5*%m`{H>t zXojvvWZqjo{QDUN;?L3xm;X`%tE7vYUlk&1NW0}T$U;WX=zZh6tp**rhSKBsthd${n5N$rdR5K~f={O7cc($cVhfVAr8 zt%8I2k1k*Bo*frlHn6$GoDM=ArlZOJ@n9uFr)-NaE~C;u_AyywOdb}tWi!k z5a@m$tP6DKJ^kEwvtS$niuwz{$^&n^IU1fOu zO3R*We^rG;+jY=+`N=Rn>7C4$40pY2&abnuFvX*9e=kz{`x{r28pmz$%^L+nZW`Jq z44!vMvHcGzkErtgrOh6nF+VZE&b3csOgMhYlo(A6gro?7`=HiT*9VW%{?jP8IR4oj z)O#jo5~5~rCAQs)jbCcqc`NsG?jz@4`ZR&8{r1a$=|XGdsXf;p-V{d3$m&0FS);}9 z>f@oOJzA{)x6RMrZ@=WKI|5l_8=vqCvLcmrsU^T_+?D@h)!R-%IZz5|o}B%neFJ$$55xOvG3{qUy zxFl(TC$p}Zmckh@S8UK+M(sAjBP>YmTFAxzd|MYc5_9~wo{iS7QTt;z{MqThT}3&J z;bOQ+URmkJ_cqV8Ik6~s)9&!TAe0ORIh%yv^wF|;*wqGDfd7Kt^6+1BabrJfa|{%Bek_>%6|_3BRMzQ7QP)xWLU|Is$}YxaZ%dqsCU@Q+`R#7TS| z)0A-V`NjSt%qW%z7qN)#m zVbeqP2o61wNBz0kZ@IFhqp8QO%|jax)wRS5l<9LMi>cc^r>)&6`=PQ=6* zb{X6o_0$~W43E@1n|u>#HR8&fyc8WDu2y6GRc-#Y<6TUR`+k5+352%tVqqR!C#z(g zyoFXwQa{7hu(5ynnXyMBi+E6U8Fl<=@z_Ty{bN=ihPHRExD~?5UgvM zaCVE+cHqr&e%k62PnPHB`t2_~TZ6cdQW{xZnNF&;)$-b^8)mOtPD#PVnipbEs8$&a z-;Bv#Zm#hCN75{gZ%~D74IZc$a771rHX)(t%_9I>yVy49eO0Z^e6sV{Ghe4cUUqE5 zvdTQzU?$wn`KX_QT5ot;{i9HJZI|2M)Yfy?jKU!hDi35hx&vYTBtxqxWb3m%8MY0r*M%gN6@Q;#_smX{8Y z051O!;lIAxCvUJ^M0-8jj@8~SjwP73k?7_Jm0Gmxsh3#x)^yC!(`J^*&cAdOxcpH= z&F7|oo%b%Q$zIDVvD?+H9NTS<2W(2IyEhx@>&Wp1N3|nC<{)IKz72*P;H!LR`@E=d z{smlEnZJ(krJKTz()?ZZiNz77P9gks4N_|=S~$?C%Rawm*U)A?11_t7CM;>f{=Ges z`&MZWCB5Q5(JVZlnujEs5Ol|@x)@P{2#`? zGAOR7X*0OH!{APENN{I@J0!tfCb&azhr!()1_`bS?h=B#ySqE=y!&TsYrm>@`{$ji zTX)XAr~7n2Pd`0auHGP{MRw1yz4U7XueLC^mBS~u(+Ae_7tfqY5Izfk}*0BX@ghL zpx6JWg&1o7cTMCv&ithy_BO+LjTwJH#L<=d!A+8=ZVhz5+$Ho=za7#B)ZQL z&y0@&9fj*xij}9f9K1PjvqojrQCD zV{*-~&7sHr&9EI-nZtFqAvHDiq8dNGn058jv6qFrM^t}3)!R=&K;FK*NC_rF$Iqq4 zu=T>-36P-v&Kw2S$cb z(95gkllxf@gG=i0|FEV8Ei&vhhJ#p+No@_x32?F}T9dpOF0C?~uYQF)sQ0sN1b0LK z<-C@`oE8{gn>|wR><6P078f0nKG)&M6HP8V5%YhDu)dGbKCiQDMrPpP*Vp)0S6kOp zhr`6#)?r=q@uTH;mgasnM$L{2!=2p`7APo|FtTg1IV;$HA7N%ce1c2OvE_RcH4HSFaD|&xqH<94d(Y0FG zlYK5`4xWSKmp7Ctm*Nz^t8S+4J=OSqxtd1ndB3IV3VOSwx}klQ+@FoXD-vSH9YfG3 z=WtC<<@m*#3ha1x;gUElyzP@rW1%(d_t>7N@Wh!g^nCcti3tBqMzI~ zwjZZ;CULh@7=F|9KKO0Bo}flAIl&?kL2TB_pEkRWL{GXb21K(i(zKZ#cb8cb8tis29dTK8^xMk5BY_H&GF^c8z zZu9C?M5aE^{juJrK%lLV3}sL28177)L>|o*tlx6{94I##_vU}Vk+k~|7W>;}XMX5^ z^pA1&;e*g=^m`^1$1LXBEtKZ%P=;^u%lb*Xy9Z$2v)Ly%eK7`skQ^T6Zp{k^C|}TG zHk`mZQb(`LUQ0eWoVufQCHU&P#b3M4uIm&}zkJj_a?~DYat`k$b>4NC?bIP=VNv@5 z=CfLz*|?8B+R4~hmcXvSxB!n=&N@?*a!@_;n>0G638~ZRK^)n;IC^qwe$y)sO}3bw zvo`L^Zvwst8JcIHp>nY@AOIW+`O3RlSXU0nwZBlNU<~@WK~-EYt845Z&>~4iLCM<0 zbB2}ZteeMCGQF}ebTDa(Tz2=BS-(3|18d_SQdujy>p|WJpjS!YCe6AJ62%E(S9>fS*es+?#amue}9Ok7^*L)chZ^(gO&ORha4B{ey-vlNT2ZD;_nx zyy(JXP+?aF((hKuC!b{_oVv~0qEFJED{q|Aofi*X4nAoj?5LKaF06NHALFJ7>&c?} z2>CR_9>#jNH68X3Qp^Ku`f-t3(~A&9VSG0|utCckm%-FFxz92i_C==}YVfGAtDGP^ z5H&ughW1y~7}e5`QTuB$4##^Qt~b7%4__lcK2ZDHjG3*!y`C)mA=%-NbC`=cCoOHsLphAH5lk3U82Vmp8{mb{-WU>Obhdz z0XR8Mj_vZ6FcBha)@QC+_ckQH00zKh`HTIw%1a!7Y3m+tGMAM3#y43&(_`HEnyrD< zbQR|OLdktj0kx6{)(iL0dL@Jef6P8qv)|WeFLbXhVPRoNL6FeL$JxAN*zsbI|86g3 zdA`?~>o0p7(It@%!LUV1C+nTLLHa5>qP0c7wP%@|kYNS48{oqf|!vJaTI0?4ipX|>WuJ(ScwiQ>CoQbLEJHHP6 zsDfoI2KwYFOE|R24lw{Pi_PWpK!5JQVBgQzd_hu#;OJbvzgE}DQM!UKYPA_ zHkN?)!o$Dp?ajWus?o$VOLBlplkNdNc$aSnh6yZe!}U;97nwI}Sy~e5HlOcI#9KT)O<8qtigtGKLWfGj!+=$> zB_~!^{;v5Th2PU(h6O(OWU!HLHI@x}4G_YJBNzEA3iih6-&U;FMZdD0o|KA-Z|5Wa zHR%tQl31SSM~!@~Z#La`tg;n6yQMw!J^6t%_VVrGAJ6#Z^|J41)2YzmnL^$%B0YWo zgO8}BED2OTkW2*h5H5q34Vt z`kFe(z=`SUk#j?j=uhW%^tdbq6?J`tBWw*pSk!RUJZMgb!~y06dewVM`FXI)1>Z}Y z&JTPFH(sjve|X98iM>ABFL-Tm?(Qbz18rOTZ-viKL=WcItY#bmfb_ud(K7cNZ5P?@Voqb%0Alsihvt(0YtbR8#@wUD}_o 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

S^062Bl(BZW=#rBtpZ4F8iMZmBz=_E~=M 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

w@s5-~DOR-_1mi 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

ZB>u@rOj;zPyviUUGvnagqn zY^7yUT@cSwYE}=3PpJ^qId$9C5#fqd@j+FW1@JFm7krk1ta#qhj>v<^M3cbKm)&uZ zkpM+o!8Di&P9PJqVcgk-6@A=>hHCh5$zo?zKzT(&Z1T9RGOjhyw`Ud^?t?(_%e$}q zML!|AV>l`>~cz_MQB{HB?sM4@#i06rcA$Ju2E zF!eAC_UP*dQh~lg1T1k%BreE=9Z^>NE~uYak~F37X#cp&OuWoVF)K5ZU-@vm5*KGl zrh^_E!Wf5C$>OqdwJgIZ(wRW33UKwaNQ`&Wu2&ggwBoItb|}snxd<3>5;MvGS~}&j zXst@X#Ucrtz9?Q~WNA{I*_*pXNI+-wb-_U4Uox^4D9f~(^Vn1I-G)yBRv|!cSJ9gb zuPS`)`(A+OJavv{#$}4uA?SVxEky`MK&n+}e?6l2jqn}q@I4W!?lf6gB;a1?p(`3N4j7IX!J6%l*RNY& zICDMjd*x`>`~gWYh4GS(vI!{prkc>PLY?mkth2L9Mi!<7X{FI^N!QTnOJFwWn0)G7bXdOEbV(z&o!c3DDS>OXL0yN z15@gQxS*?yp%&4k98)z<6{6nODg*)}G7W+VjByt5+ouE$3Of%ITmbeKqvrRXWq^)| z_np46DS9T+OIX%_5X4WCnFI;b%**EtISW;mFQFQ+6Ubly(Q`kVBynyUaHB_S23xD&>x# zBUn~Je6nTRrhcL8+HXI|mj2N4a+n98S*^j<>hkV5x^w#d-1Y-y-@7eji#c*D5in;O zqs@!SLS@5p;^%L@c6zq z28$6SeH3i#8>Qq^hESIU?u6i)hR#ZS37DP{7ngNyD}dZt4%5T|3_s1_SH(DKJ6+UF z^_>k7Kpq?yH5slq3nI9B97tjS*ycbg1t85E8UW~!aNUz~o*E$ZH1_w^nNgiljU(El)c|m@ z&!j$;|BO!kSCW81j_^Oy1#dbMJo(<(gbKm4g+2N8{6Gicf`|>%bR8c(c)jz+HC{H) z4VJ2nBbp5#e^1TpZ9D~mpWEm3e$Rf-)}f@xVTjbr`O@d7pR-j`z_Gkw_I7opdox&- z%KWylf%D0fu<-Kzz9+P-lJRBw3C=X-mMe_Hd96HvGZIL8mU+07899YDGR}I_JXcfA zc+KhFh3PcW9~@m4vg7pT5t}+QHrJgrP)vvz;sg2QA(aT@!K zuw`=CIkhgjTTjc2M%Vf8av*U1EkIpNAeqA<&I`3^GgJ3wS@w()upQc8RbWg#3H%*7 z>fU2te*D%`DvPEM6ahHfikyx-$F#)B58u%u{9y8&2ata1nrRCGe3I)XyY2OKNY

  • r1NF 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

    b76UH^84)8iAOIA!b;%bZ!&+zy%MZz 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

    +W@kUgVmDkBEF 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 Wke0rm>-ul6KhiVREr0O*?f(VPR39<` literal 219715 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.kUAkUUM2sx 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 Date: Tue, 17 Dec 2024 18:03:57 -0600 Subject: [PATCH 21/60] Reindex status api updates (#118803) --- .../ReindexDataStreamTransportActionIT.java | 9 +- .../GetMigrationReindexStatusAction.java | 26 ++- ...MigrationReindexStatusTransportAction.java | 115 +++++++++++- .../task/ReindexDataStreamEnrichedStatus.java | 104 +++++++++++ ...indexDataStreamPersistentTaskExecutor.java | 4 +- .../migrate/task/ReindexDataStreamStatus.java | 17 +- .../migrate/task/ReindexDataStreamTask.java | 19 +- ...ationReindexStatusActionResponseTests.java | 112 ++++-------- .../ReindexDataStreamEnrichedStatusTests.java | 165 ++++++++++++++++++ .../task/ReindexDataStreamStatusTests.java | 18 +- .../test/migrate/20_reindex_status.yml | 4 +- 11 files changed, 464 insertions(+), 129 deletions(-) create mode 100644 x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamEnrichedStatus.java create mode 100644 x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamEnrichedStatusTests.java diff --git a/x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamTransportActionIT.java b/x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamTransportActionIT.java index 6e24e644cb2af..b32a6efb854d7 100644 --- a/x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamTransportActionIT.java +++ b/x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamTransportActionIT.java @@ -29,7 +29,7 @@ import org.elasticsearch.xpack.migrate.MigratePlugin; import org.elasticsearch.xpack.migrate.action.ReindexDataStreamAction.ReindexDataStreamRequest; import org.elasticsearch.xpack.migrate.action.ReindexDataStreamAction.ReindexDataStreamResponse; -import org.elasticsearch.xpack.migrate.task.ReindexDataStreamStatus; +import org.elasticsearch.xpack.migrate.task.ReindexDataStreamEnrichedStatus; import org.elasticsearch.xpack.migrate.task.ReindexDataStreamTask; import java.util.Collection; @@ -37,6 +37,7 @@ import java.util.Locale; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicReference; @@ -100,7 +101,7 @@ public void testAlreadyUpToDateDataStream() throws Exception { assertThat(task.getStatus().complete(), equalTo(true)); assertNull(task.getStatus().exception()); assertThat(task.getStatus().pending(), equalTo(0)); - assertThat(task.getStatus().inProgress(), equalTo(0)); + assertThat(task.getStatus().inProgress(), equalTo(Set.of())); assertThat(task.getStatus().errors().size(), equalTo(0)); assertBusy(() -> { @@ -108,12 +109,12 @@ public void testAlreadyUpToDateDataStream() throws Exception { new ActionType(GetMigrationReindexStatusAction.NAME), new GetMigrationReindexStatusAction.Request(dataStreamName) ).actionGet(); - ReindexDataStreamStatus status = (ReindexDataStreamStatus) statusResponse.getTask().getTask().status(); + ReindexDataStreamEnrichedStatus status = statusResponse.getEnrichedStatus(); assertThat(status.complete(), equalTo(true)); assertThat(status.errors(), equalTo(List.of())); assertThat(status.exception(), equalTo(null)); assertThat(status.pending(), equalTo(0)); - assertThat(status.inProgress(), equalTo(0)); + assertThat(status.inProgress().size(), equalTo(0)); assertThat(status.totalIndices(), equalTo(backingIndexCount)); assertThat(status.totalIndicesToBeUpgraded(), equalTo(0)); }); diff --git a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/GetMigrationReindexStatusAction.java b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/GetMigrationReindexStatusAction.java index 68ccaef4bf02c..bc084f3e0b5d6 100644 --- a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/GetMigrationReindexStatusAction.java +++ b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/GetMigrationReindexStatusAction.java @@ -16,10 +16,9 @@ import org.elasticsearch.common.Strings; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.tasks.Task; -import org.elasticsearch.tasks.TaskResult; import org.elasticsearch.xcontent.ToXContentObject; import org.elasticsearch.xcontent.XContentBuilder; +import org.elasticsearch.xpack.migrate.task.ReindexDataStreamEnrichedStatus; import java.io.IOException; import java.util.Objects; @@ -36,46 +35,43 @@ public GetMigrationReindexStatusAction() { } public static class Response extends ActionResponse implements ToXContentObject { - private final TaskResult task; + private final ReindexDataStreamEnrichedStatus enrichedStatus; - public Response(TaskResult task) { - this.task = requireNonNull(task, "task is required"); + public Response(ReindexDataStreamEnrichedStatus enrichedStatus) { + this.enrichedStatus = requireNonNull(enrichedStatus, "status is required"); } public Response(StreamInput in) throws IOException { super(in); - task = in.readOptionalWriteable(TaskResult::new); + enrichedStatus = in.readOptionalWriteable(ReindexDataStreamEnrichedStatus::new); } @Override public void writeTo(StreamOutput out) throws IOException { - out.writeOptionalWriteable(task); + out.writeOptionalWriteable(enrichedStatus); } /** * Get the actual result of the fetch. */ - public TaskResult getTask() { - return task; + public ReindexDataStreamEnrichedStatus getEnrichedStatus() { + return enrichedStatus; } @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - Task.Status status = task.getTask().status(); - if (status != null) { - task.getTask().status().toXContent(builder, params); - } + enrichedStatus.toXContent(builder, params); return builder; } @Override public int hashCode() { - return Objects.hashCode(task); + return Objects.hashCode(enrichedStatus); } @Override public boolean equals(Object other) { - return other instanceof Response && task.equals(((Response) other).task); + return other instanceof Response && enrichedStatus.equals(((Response) other).enrichedStatus); } @Override diff --git a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/GetMigrationReindexStatusTransportAction.java b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/GetMigrationReindexStatusTransportAction.java index ca81a03fc5630..64864491191e5 100644 --- a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/GetMigrationReindexStatusTransportAction.java +++ b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/GetMigrationReindexStatusTransportAction.java @@ -11,40 +11,55 @@ import org.elasticsearch.ResourceNotFoundException; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionListenerResponseHandler; +import org.elasticsearch.action.admin.indices.stats.IndexStats; +import org.elasticsearch.action.admin.indices.stats.IndicesStatsAction; +import org.elasticsearch.action.admin.indices.stats.IndicesStatsRequest; +import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.HandledTransportAction; +import org.elasticsearch.action.support.IndicesOptions; +import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.util.concurrent.EsExecutors; import org.elasticsearch.core.Strings; +import org.elasticsearch.core.Tuple; +import org.elasticsearch.index.shard.DocsStats; import org.elasticsearch.injection.guice.Inject; import org.elasticsearch.persistent.AllocatedPersistentTask; import org.elasticsearch.persistent.PersistentTasksCustomMetadata; import org.elasticsearch.tasks.CancellableTask; import org.elasticsearch.tasks.Task; import org.elasticsearch.tasks.TaskInfo; -import org.elasticsearch.tasks.TaskResult; import org.elasticsearch.transport.TransportRequestOptions; import org.elasticsearch.transport.TransportService; import org.elasticsearch.xpack.migrate.action.GetMigrationReindexStatusAction.Request; import org.elasticsearch.xpack.migrate.action.GetMigrationReindexStatusAction.Response; +import org.elasticsearch.xpack.migrate.task.ReindexDataStreamEnrichedStatus; +import org.elasticsearch.xpack.migrate.task.ReindexDataStreamStatus; +import java.util.HashMap; import java.util.Map; import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; public class GetMigrationReindexStatusTransportAction extends HandledTransportAction { private final ClusterService clusterService; private final TransportService transportService; + private final Client client; @Inject public GetMigrationReindexStatusTransportAction( ClusterService clusterService, TransportService transportService, - ActionFilters actionFilters + ActionFilters actionFilters, + Client client ) { super(GetMigrationReindexStatusAction.NAME, transportService, actionFilters, Request::new, EsExecutors.DIRECT_EXECUTOR_SERVICE); this.clusterService = clusterService; this.transportService = transportService; + this.client = client; } @Override @@ -60,9 +75,9 @@ protected void doExecute(Task task, Request request, ActionListener li } else if (persistentTask.isAssigned()) { String nodeId = persistentTask.getExecutorNode(); if (clusterService.localNode().getId().equals(nodeId)) { - getRunningTaskFromNode(persistentTaskId, listener); + fetchAndReportStatusForTaskOnThisNode(persistentTaskId, listener); } else { - runOnNodeWithTaskIfPossible(task, request, nodeId, listener); + fetchAndReportStatusForTaskOnRemoteNode(task, request, nodeId, listener); } } else { listener.onFailure(new ElasticsearchException("Persistent task with id [{}] is not assigned to a node", persistentTaskId)); @@ -82,7 +97,7 @@ private Task getRunningPersistentTaskFromTaskManager(String persistentTaskId) { return optionalTask.map(Map.Entry::getValue).orElse(null); } - void getRunningTaskFromNode(String persistentTaskId, ActionListener listener) { + void fetchAndReportStatusForTaskOnThisNode(String persistentTaskId, ActionListener listener) { Task runningTask = getRunningPersistentTaskFromTaskManager(persistentTaskId); if (runningTask == null) { listener.onFailure( @@ -96,11 +111,97 @@ void getRunningTaskFromNode(String persistentTaskId, ActionListener li ); } else { TaskInfo info = runningTask.taskInfo(clusterService.localNode().getId(), true); - listener.onResponse(new Response(new TaskResult(false, info))); + ReindexDataStreamStatus status = (ReindexDataStreamStatus) info.status(); + Set inProgressIndices = status.inProgress(); + if (inProgressIndices.isEmpty()) { + // We have no reason to fetch index stats since there are no in progress indices + reportStatus(Map.of(), status, listener); + } else { + fetchInProgressStatsAndReportStatus(inProgressIndices, status, listener); + } } } - private void runOnNodeWithTaskIfPossible(Task thisTask, Request request, String nodeId, ActionListener listener) { + /* + * The status is enriched with the information from inProgressMap to create a new ReindexDataStreamEnrichedStatus, which is used in the + * response sent to the listener. + */ + private void reportStatus( + Map> inProgressMap, + ReindexDataStreamStatus status, + ActionListener listener + ) { + ReindexDataStreamEnrichedStatus enrichedStatus = new ReindexDataStreamEnrichedStatus( + status.persistentTaskStartTime(), + status.totalIndices(), + status.totalIndicesToBeUpgraded(), + status.complete(), + status.exception(), + inProgressMap, + status.pending(), + status.errors() + ); + listener.onResponse(new Response(enrichedStatus)); + } + + /* + * This method feches doc counts for all indices in inProgressIndices (and the indices they are being reindexed into). After + * successfully fetching those, reportStatus is called. + */ + private void fetchInProgressStatsAndReportStatus( + Set inProgressIndices, + ReindexDataStreamStatus status, + ActionListener listener + ) { + IndicesStatsRequest indicesStatsRequest = new IndicesStatsRequest(); + String[] indices = inProgressIndices.stream() + .flatMap(index -> Stream.of(index, ReindexDataStreamIndexTransportAction.generateDestIndexName(index))) + .toList() + .toArray(new String[0]); + indicesStatsRequest.indices(indices); + /* + * It is possible that the destination index will not exist yet, so we want to ignore the fact that it is missing + */ + indicesStatsRequest.indicesOptions(IndicesOptions.fromOptions(true, true, true, true)); + client.execute(IndicesStatsAction.INSTANCE, indicesStatsRequest, new ActionListener() { + @Override + public void onResponse(IndicesStatsResponse indicesStatsResponse) { + Map> inProgressMap = new HashMap<>(); + for (String index : inProgressIndices) { + IndexStats sourceIndexStats = indicesStatsResponse.getIndex(index); + final long totalDocsInIndex; + if (sourceIndexStats == null) { + totalDocsInIndex = 0; + } else { + DocsStats totalDocsStats = sourceIndexStats.getTotal().getDocs(); + totalDocsInIndex = totalDocsStats == null ? 0 : totalDocsStats.getCount(); + } + IndexStats migratedIndexStats = indicesStatsResponse.getIndex( + ReindexDataStreamIndexTransportAction.generateDestIndexName(index) + ); + final long reindexedDocsInIndex; + if (migratedIndexStats == null) { + reindexedDocsInIndex = 0; + } else { + DocsStats reindexedDocsStats = migratedIndexStats.getTotal().getDocs(); + reindexedDocsInIndex = reindexedDocsStats == null ? 0 : reindexedDocsStats.getCount(); + } + inProgressMap.put(index, Tuple.tuple(totalDocsInIndex, reindexedDocsInIndex)); + } + reportStatus(inProgressMap, status, listener); + } + + @Override + public void onFailure(Exception e) { + listener.onFailure(e); + } + }); + } + + /* + * The task and its status exist on some other node, so this method forwards the request to that node. + */ + private void fetchAndReportStatusForTaskOnRemoteNode(Task thisTask, Request request, String nodeId, ActionListener listener) { DiscoveryNode node = clusterService.state().nodes().get(nodeId); if (node == null) { listener.onFailure( diff --git a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamEnrichedStatus.java b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamEnrichedStatus.java new file mode 100644 index 0000000000000..9dbe1f0c8eebc --- /dev/null +++ b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamEnrichedStatus.java @@ -0,0 +1,104 @@ +/* + * 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.migrate.task; + +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.core.Tuple; +import org.elasticsearch.xcontent.ToXContentObject; +import org.elasticsearch.xcontent.XContentBuilder; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/* + * This class represents information similar to that in ReindexDataStreamStatus, but enriched from other sources besides just the task + * itself. + */ +public record ReindexDataStreamEnrichedStatus( + long persistentTaskStartTime, + int totalIndices, + int totalIndicesToBeUpgraded, + boolean complete, + Exception exception, + Map> inProgress, + int pending, + List> errors +) implements ToXContentObject, Writeable { + public ReindexDataStreamEnrichedStatus { + Objects.requireNonNull(inProgress); + Objects.requireNonNull(errors); + } + + public ReindexDataStreamEnrichedStatus(StreamInput in) throws IOException { + this( + in.readLong(), + in.readInt(), + in.readInt(), + in.readBoolean(), + in.readException(), + in.readMap(StreamInput::readString, in2 -> Tuple.tuple(in2.readLong(), in2.readLong())), + in.readInt(), + in.readCollectionAsList(in1 -> Tuple.tuple(in1.readString(), in1.readException())) + ); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeLong(persistentTaskStartTime); + out.writeInt(totalIndices); + out.writeInt(totalIndicesToBeUpgraded); + out.writeBoolean(complete); + out.writeException(exception); + out.writeMap(inProgress, StreamOutput::writeString, (out2, tuple) -> { + out2.writeLong(tuple.v1()); + out2.writeLong(tuple.v2()); + }); + out.writeInt(pending); + out.writeCollection(errors, (out1, tuple) -> { + out1.writeString(tuple.v1()); + out1.writeException(tuple.v2()); + }); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.timestampFieldsFromUnixEpochMillis("start_time_millis", "start_time", persistentTaskStartTime); + builder.field("complete", complete); + builder.field("total_indices_in_data_stream", totalIndices); + builder.field("total_indices_requiring_upgrade", totalIndicesToBeUpgraded); + builder.field("successes", totalIndicesToBeUpgraded - (inProgress.size() + pending + errors.size())); + builder.startArray("in_progress"); + for (Map.Entry> inProgressEntry : inProgress.entrySet()) { + builder.startObject(); + builder.field("index", inProgressEntry.getKey()); + builder.field("total_doc_count", inProgressEntry.getValue().v1()); + builder.field("reindexed_doc_count", inProgressEntry.getValue().v2()); + builder.endObject(); + } + builder.endArray(); + builder.field("pending", pending); + builder.startArray("errors"); + for (Tuple error : errors) { + builder.startObject(); + builder.field("index", error.v1()); + builder.field("message", error.v2() == null ? "unknown" : error.v2().getMessage()); + builder.endObject(); + } + builder.endArray(); + if (exception != null) { + builder.field("exception", exception.getMessage()); + } + builder.endObject(); + return builder; + } +} diff --git a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamPersistentTaskExecutor.java b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamPersistentTaskExecutor.java index 176220a1ccae8..494be303980a7 100644 --- a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamPersistentTaskExecutor.java +++ b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamPersistentTaskExecutor.java @@ -78,9 +78,9 @@ protected void nodeOperation(AllocatedPersistentTask task, ReindexDataStreamTask .toList(); reindexDataStreamTask.setPendingIndicesCount(indicesToBeReindexed.size()); for (Index index : indicesToBeReindexed) { - reindexDataStreamTask.incrementInProgressIndicesCount(); + reindexDataStreamTask.incrementInProgressIndicesCount(index.getName()); // TODO This is just a placeholder. This is where the real data stream reindex logic will go - reindexDataStreamTask.reindexSucceeded(); + reindexDataStreamTask.reindexSucceeded(index.getName()); } completeSuccessfulPersistentTask(reindexDataStreamTask); diff --git a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamStatus.java b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamStatus.java index 358062550b50a..632aea076ea5a 100644 --- a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamStatus.java +++ b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamStatus.java @@ -16,6 +16,7 @@ import java.io.IOException; import java.util.List; import java.util.Objects; +import java.util.Set; public record ReindexDataStreamStatus( long persistentTaskStartTime, @@ -23,11 +24,12 @@ public record ReindexDataStreamStatus( int totalIndicesToBeUpgraded, boolean complete, Exception exception, - int inProgress, + Set inProgress, int pending, List> errors ) implements Task.Status { public ReindexDataStreamStatus { + Objects.requireNonNull(inProgress); Objects.requireNonNull(errors); } @@ -40,7 +42,7 @@ public ReindexDataStreamStatus(StreamInput in) throws IOException { in.readInt(), in.readBoolean(), in.readException(), - in.readInt(), + in.readCollectionAsSet((Reader) StreamInput::readString), in.readInt(), in.readCollectionAsList(in1 -> Tuple.tuple(in1.readString(), in1.readException())) ); @@ -58,7 +60,7 @@ public void writeTo(StreamOutput out) throws IOException { out.writeInt(totalIndicesToBeUpgraded); out.writeBoolean(complete); out.writeException(exception); - out.writeInt(inProgress); + out.writeStringCollection(inProgress); out.writeInt(pending); out.writeCollection(errors, (out1, tuple) -> { out1.writeString(tuple.v1()); @@ -69,12 +71,13 @@ public void writeTo(StreamOutput out) throws IOException { @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); - builder.field("start_time", persistentTaskStartTime); + builder.timestampFieldsFromUnixEpochMillis("start_time_millis", "start_time", persistentTaskStartTime); builder.field("complete", complete); - builder.field("total_indices", totalIndices); + builder.field("total_indices_in_data_stream", totalIndices); builder.field("total_indices_requiring_upgrade", totalIndicesToBeUpgraded); - builder.field("successes", totalIndicesToBeUpgraded - (inProgress + pending + errors.size())); - builder.field("in_progress", inProgress); + final int inProgressSize = inProgress.size(); + builder.field("successes", totalIndicesToBeUpgraded - (inProgressSize + pending + errors.size())); + builder.field("in_progress", inProgressSize); builder.field("pending", pending); builder.startArray("errors"); for (Tuple error : errors) { diff --git a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamTask.java b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamTask.java index 844f24f45ab77..7a2b759dfd17a 100644 --- a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamTask.java +++ b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamTask.java @@ -15,8 +15,11 @@ import org.elasticsearch.threadpool.ThreadPool; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; public class ReindexDataStreamTask extends AllocatedPersistentTask { @@ -26,9 +29,9 @@ public class ReindexDataStreamTask extends AllocatedPersistentTask { private final int totalIndicesToBeUpgraded; private volatile boolean complete = false; private volatile Exception exception; - private final AtomicInteger inProgress = new AtomicInteger(0); + private final Set inProgress = Collections.synchronizedSet(new HashSet<>()); private final AtomicInteger pending = new AtomicInteger(); - private final List> errors = new ArrayList<>(); + private final List> errors = Collections.synchronizedList(new ArrayList<>()); private final RunOnce completeTask; @SuppressWarnings("this-escape") @@ -64,7 +67,7 @@ public ReindexDataStreamStatus getStatus() { totalIndicesToBeUpgraded, complete, exception, - inProgress.get(), + inProgress, pending.get(), errors ); @@ -84,17 +87,17 @@ public void taskFailed(ThreadPool threadPool, TimeValue timeToLive, Exception e) allReindexesCompleted(threadPool, timeToLive); } - public void reindexSucceeded() { - inProgress.decrementAndGet(); + public void reindexSucceeded(String index) { + inProgress.remove(index); } public void reindexFailed(String index, Exception error) { this.errors.add(Tuple.tuple(index, error)); - inProgress.decrementAndGet(); + inProgress.remove(index); } - public void incrementInProgressIndicesCount() { - inProgress.incrementAndGet(); + public void incrementInProgressIndicesCount(String index) { + inProgress.add(index); pending.decrementAndGet(); } diff --git a/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/action/GetMigrationReindexStatusActionResponseTests.java b/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/action/GetMigrationReindexStatusActionResponseTests.java index a18030edbf42c..1361f30840c87 100644 --- a/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/action/GetMigrationReindexStatusActionResponseTests.java +++ b/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/action/GetMigrationReindexStatusActionResponseTests.java @@ -7,25 +7,17 @@ package org.elasticsearch.xpack.migrate.action; -import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.network.NetworkModule; -import org.elasticsearch.tasks.RawTaskStatus; -import org.elasticsearch.tasks.Task; -import org.elasticsearch.tasks.TaskId; -import org.elasticsearch.tasks.TaskInfo; -import org.elasticsearch.tasks.TaskResult; +import org.elasticsearch.core.Tuple; import org.elasticsearch.test.AbstractWireSerializingTestCase; -import org.elasticsearch.xcontent.ToXContent; -import org.elasticsearch.xcontent.XContentBuilder; -import org.elasticsearch.xcontent.XContentType; import org.elasticsearch.xpack.migrate.action.GetMigrationReindexStatusAction.Response; +import org.elasticsearch.xpack.migrate.task.ReindexDataStreamEnrichedStatus; import java.io.IOException; -import java.util.Collections; +import java.util.List; import java.util.Map; -import java.util.TreeMap; public class GetMigrationReindexStatusActionResponseTests extends AbstractWireSerializingTestCase { @Override @@ -35,11 +27,7 @@ protected Writeable.Reader instanceReader() { @Override protected Response createTestInstance() { - try { - return new Response(randomTaskResult()); - } catch (IOException e) { - throw new RuntimeException(e); - } + return new Response(getRandomStatus()); } @Override @@ -47,76 +35,44 @@ protected Response mutateInstance(Response instance) throws IOException { return createTestInstance(); // There's only one field } - private static TaskResult randomTaskResult() throws IOException { - return switch (between(0, 2)) { - case 0 -> new TaskResult(randomBoolean(), randomTaskInfo()); - case 1 -> new TaskResult(randomTaskInfo(), new RuntimeException("error")); - case 2 -> new TaskResult(randomTaskInfo(), randomTaskResponse()); - default -> throw new UnsupportedOperationException("Unsupported random TaskResult constructor"); - }; - } - - static TaskInfo randomTaskInfo() { - String nodeId = randomAlphaOfLength(5); - TaskId taskId = randomTaskId(nodeId); - String type = randomAlphaOfLength(5); - String action = randomAlphaOfLength(5); - Task.Status status = randomBoolean() ? randomRawTaskStatus() : null; - String description = randomBoolean() ? randomAlphaOfLength(5) : null; - long startTime = randomLong(); - long runningTimeNanos = randomNonNegativeLong(); - boolean cancellable = randomBoolean(); - boolean cancelled = cancellable && randomBoolean(); - TaskId parentTaskId = randomBoolean() ? TaskId.EMPTY_TASK_ID : randomTaskId(randomAlphaOfLength(5)); - Map headers = randomBoolean() - ? Collections.emptyMap() - : Collections.singletonMap(randomAlphaOfLength(5), randomAlphaOfLength(5)); - return new TaskInfo( - taskId, - type, - nodeId, - action, - description, - status, - startTime, - runningTimeNanos, - cancellable, - cancelled, - parentTaskId, - headers + private ReindexDataStreamEnrichedStatus getRandomStatus() { + return new ReindexDataStreamEnrichedStatus( + randomLong(), + randomNegativeInt(), + randomNegativeInt(), + randomBoolean(), + nullableTestException(), + randomInProgressMap(), + randomNegativeInt(), + randomErrorList() ); } - private static TaskId randomTaskId(String nodeId) { - return new TaskId(nodeId, randomLong()); + private Map> randomInProgressMap() { + return randomMap(1, 50, () -> Tuple.tuple(randomAlphaOfLength(50), Tuple.tuple(randomNonNegativeLong(), randomNonNegativeLong()))); } - private static RawTaskStatus randomRawTaskStatus() { - try (XContentBuilder builder = XContentBuilder.builder(XContentType.JSON.xContent())) { - builder.startObject(); - int fields = between(0, 10); - for (int f = 0; f < fields; f++) { - builder.field(randomAlphaOfLength(5), randomAlphaOfLength(5)); - } - builder.endObject(); - return new RawTaskStatus(BytesReference.bytes(builder)); - } catch (IOException e) { - throw new IllegalStateException(e); + private Exception nullableTestException() { + if (randomBoolean()) { + return testException(); } + return null; } - private static ToXContent randomTaskResponse() { - Map result = new TreeMap<>(); - int fields = between(0, 10); - for (int f = 0; f < fields; f++) { - result.put(randomAlphaOfLength(5), randomAlphaOfLength(5)); - } - return (builder, params) -> { - for (Map.Entry entry : result.entrySet()) { - builder.field(entry.getKey(), entry.getValue()); - } - return builder; - }; + private Exception testException() { + /* + * Unfortunately ElasticsearchException doesn't have an equals and just falls back to Object::equals. So we can't test for equality + * when we're using an exception. So always just use null. + */ + return null; + } + + private List> randomErrorList() { + return randomErrorList(0); + } + + private List> randomErrorList(int minSize) { + return randomList(minSize, Math.max(minSize, 100), () -> Tuple.tuple(randomAlphaOfLength(30), testException())); } @Override diff --git a/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamEnrichedStatusTests.java b/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamEnrichedStatusTests.java new file mode 100644 index 0000000000000..acd8cd1a6add2 --- /dev/null +++ b/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamEnrichedStatusTests.java @@ -0,0 +1,165 @@ +/* + * 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.migrate.task; + +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.core.Tuple; +import org.elasticsearch.test.AbstractWireSerializingTestCase; +import org.elasticsearch.xcontent.XContentBuilder; +import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xcontent.json.JsonXContent; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static java.util.Map.entry; +import static org.elasticsearch.xcontent.ToXContent.EMPTY_PARAMS; +import static org.hamcrest.Matchers.equalTo; + +public class ReindexDataStreamEnrichedStatusTests extends AbstractWireSerializingTestCase { + + @Override + protected Writeable.Reader instanceReader() { + return ReindexDataStreamEnrichedStatus::new; + } + + @Override + protected ReindexDataStreamEnrichedStatus createTestInstance() { + return new ReindexDataStreamEnrichedStatus( + randomLong(), + randomNegativeInt(), + randomNegativeInt(), + randomBoolean(), + nullableTestException(), + randomInProgressMap(), + randomNegativeInt(), + randomErrorList() + ); + } + + private Map> randomInProgressMap() { + return randomMap(1, 50, () -> Tuple.tuple(randomAlphaOfLength(50), Tuple.tuple(randomNonNegativeLong(), randomNonNegativeLong()))); + } + + private Exception nullableTestException() { + if (randomBoolean()) { + return testException(); + } + return null; + } + + private Exception testException() { + /* + * Unfortunately ElasticsearchException doesn't have an equals and just falls back to Object::equals. So we can't test for equality + * when we're using an exception. So always just use null. + */ + return null; + } + + private List randomList() { + return randomList(0); + } + + private List randomList(int minSize) { + return randomList(minSize, Math.max(minSize, 100), () -> randomAlphaOfLength(50)); + } + + private Set randomSet(int minSize) { + return randomSet(minSize, 100, () -> randomAlphaOfLength(50)); + } + + private List> randomErrorList() { + return randomErrorList(0); + } + + private List> randomErrorList(int minSize) { + return randomList(minSize, Math.max(minSize, 100), () -> Tuple.tuple(randomAlphaOfLength(30), testException())); + } + + @Override + protected ReindexDataStreamEnrichedStatus mutateInstance(ReindexDataStreamEnrichedStatus instance) throws IOException { + long startTime = instance.persistentTaskStartTime(); + int totalIndices = instance.totalIndices(); + int totalIndicesToBeUpgraded = instance.totalIndicesToBeUpgraded(); + boolean complete = instance.complete(); + Exception exception = instance.exception(); + Map> inProgress = instance.inProgress(); + int pending = instance.pending(); + List> errors = instance.errors(); + switch (randomIntBetween(0, 6)) { + case 0 -> startTime = randomLong(); + case 1 -> totalIndices = totalIndices + 1; + case 2 -> totalIndicesToBeUpgraded = totalIndicesToBeUpgraded + 1; + case 3 -> complete = complete == false; + case 4 -> inProgress = randomInProgressMap(); + case 5 -> pending = pending + 1; + case 6 -> errors = randomErrorList(errors.size() + 1); + default -> throw new UnsupportedOperationException(); + } + return new ReindexDataStreamEnrichedStatus( + startTime, + totalIndices, + totalIndicesToBeUpgraded, + complete, + exception, + inProgress, + pending, + errors + ); + } + + public void testToXContent() throws IOException { + ReindexDataStreamEnrichedStatus status = new ReindexDataStreamEnrichedStatus( + 1234L, + 200, + 100, + true, + new ElasticsearchException("the whole task failed"), + Map.of("index-1", Tuple.tuple(10L, 8L)), + 8, + List.of( + Tuple.tuple("index7", new ElasticsearchException("index7 failed")), + Tuple.tuple("index8", new ElasticsearchException("index8 " + "failed")) + ) + ); + try (XContentBuilder builder = XContentBuilder.builder(JsonXContent.jsonXContent)) { + builder.humanReadable(true); + status.toXContent(builder, EMPTY_PARAMS); + try (XContentParser parser = createParser(JsonXContent.jsonXContent, BytesReference.bytes(builder))) { + Map parserMap = parser.map(); + assertThat( + parserMap, + equalTo( + Map.ofEntries( + entry("start_time", "1970-01-01T00:00:01.234Z"), + entry("start_time_millis", 1234), + entry("total_indices_in_data_stream", 200), + entry("total_indices_requiring_upgrade", 100), + entry("complete", true), + entry("exception", "the whole task failed"), + entry("successes", 89), + entry("in_progress", List.of(Map.of("index", "index-1", "total_doc_count", 10, "reindexed_doc_count", 8))), + entry("pending", 8), + entry( + "errors", + List.of( + Map.of("index", "index7", "message", "index7 failed"), + Map.of("index", "index8", "message", "index8 failed") + ) + ) + ) + ) + ); + } + } + } +} diff --git a/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamStatusTests.java b/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamStatusTests.java index d81e9d35cd490..47e2d02bee3b0 100644 --- a/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamStatusTests.java +++ b/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamStatusTests.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.util.List; import java.util.Map; +import java.util.Set; import static java.util.Map.entry; import static org.elasticsearch.xcontent.ToXContent.EMPTY_PARAMS; @@ -39,7 +40,7 @@ protected ReindexDataStreamStatus createTestInstance() { randomNegativeInt(), randomBoolean(), nullableTestException(), - randomNegativeInt(), + randomSet(0), randomNegativeInt(), randomErrorList() ); @@ -68,6 +69,10 @@ private List randomList(int minSize) { return randomList(minSize, Math.max(minSize, 100), () -> randomAlphaOfLength(50)); } + private Set randomSet(int minSize) { + return randomSet(minSize, 100, () -> randomAlphaOfLength(50)); + } + private List> randomErrorList() { return randomErrorList(0); } @@ -83,7 +88,7 @@ protected ReindexDataStreamStatus mutateInstance(ReindexDataStreamStatus instanc int totalIndicesToBeUpgraded = instance.totalIndicesToBeUpgraded(); boolean complete = instance.complete(); Exception exception = instance.exception(); - int inProgress = instance.inProgress(); + Set inProgress = instance.inProgress(); int pending = instance.pending(); List> errors = instance.errors(); switch (randomIntBetween(0, 6)) { @@ -91,7 +96,7 @@ protected ReindexDataStreamStatus mutateInstance(ReindexDataStreamStatus instanc case 1 -> totalIndices = totalIndices + 1; case 2 -> totalIndicesToBeUpgraded = totalIndicesToBeUpgraded + 1; case 3 -> complete = complete == false; - case 4 -> inProgress = inProgress + 1; + case 4 -> inProgress = randomSet(inProgress.size() + 1); case 5 -> pending = pending + 1; case 6 -> errors = randomErrorList(errors.size() + 1); default -> throw new UnsupportedOperationException(); @@ -115,7 +120,7 @@ public void testToXContent() throws IOException { 100, true, new ElasticsearchException("the whole task failed"), - 12, + randomSet(12, 12, () -> randomAlphaOfLength(50)), 8, List.of( Tuple.tuple("index7", new ElasticsearchException("index7 failed")), @@ -131,8 +136,9 @@ public void testToXContent() throws IOException { parserMap, equalTo( Map.ofEntries( - entry("start_time", 1234), - entry("total_indices", 200), + entry("start_time", "1970-01-01T00:00:01.234Z"), + entry("start_time_millis", 1234), + entry("total_indices_in_data_stream", 200), entry("total_indices_requiring_upgrade", 100), entry("complete", true), entry("exception", "the whole task failed"), diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/migrate/20_reindex_status.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/migrate/20_reindex_status.yml index c94ce8dd211ae..80ca95d631491 100644 --- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/migrate/20_reindex_status.yml +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/migrate/20_reindex_status.yml @@ -61,10 +61,10 @@ setup: migrate.get_reindex_status: index: "my-data-stream" - match: { complete: true } - - match: { total_indices: 1 } + - match: { total_indices_in_data_stream: 1 } - match: { total_indices_requiring_upgrade: 0 } - match: { successes: 0 } - - match: { in_progress: 0 } + - match: { in_progress: [] } - match: { pending: 0 } - match: { errors: [] } From 15bec3cefa48c958dada0fba42f452fd278c1ab6 Mon Sep 17 00:00:00 2001 From: Kathleen DeRusso Date: Tue, 17 Dec 2024 19:06:54 -0500 Subject: [PATCH 22/60] Add support for sparse_vector queries against semantic_text fields (#118617) --- docs/changelog/118617.yaml | 5 + .../ml/search/SparseVectorQueryBuilder.java | 38 ++- .../search/SparseVectorQueryBuilderTests.java | 6 +- .../xpack/inference/InferenceFeatures.java | 7 +- .../xpack/inference/InferencePlugin.java | 3 +- .../SemanticMatchQueryRewriteInterceptor.java | 88 ++----- .../queries/SemanticQueryBuilder.java | 8 + .../SemanticQueryRewriteInterceptor.java | 148 +++++++++++ ...icSparseVectorQueryRewriteInterceptor.java | 124 +++++++++ ...nticMatchQueryRewriteInterceptorTests.java | 110 ++++++++ ...rseVectorQueryRewriteInterceptorTests.java | 137 ++++++++++ .../46_semantic_text_sparse_vector.yml | 249 ++++++++++++++++++ .../test/ml/sparse_vector_search.yml | 40 ++- 13 files changed, 887 insertions(+), 76 deletions(-) create mode 100644 docs/changelog/118617.yaml create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/queries/SemanticQueryRewriteInterceptor.java create mode 100644 x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/queries/SemanticSparseVectorQueryRewriteInterceptor.java create mode 100644 x-pack/plugin/inference/src/test/java/org/elasticsearch/index/query/SemanticMatchQueryRewriteInterceptorTests.java create mode 100644 x-pack/plugin/inference/src/test/java/org/elasticsearch/index/query/SemanticSparseVectorQueryRewriteInterceptorTests.java create mode 100644 x-pack/plugin/inference/src/yamlRestTest/resources/rest-api-spec/test/inference/46_semantic_text_sparse_vector.yml diff --git a/docs/changelog/118617.yaml b/docs/changelog/118617.yaml new file mode 100644 index 0000000000000..a8793a114e913 --- /dev/null +++ b/docs/changelog/118617.yaml @@ -0,0 +1,5 @@ +pr: 118617 +summary: Add support for `sparse_vector` queries against `semantic_text` fields +area: "Search" +type: enhancement +issues: [] diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java index e9e4e90421adc..35cba890e5e0c 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilder.java @@ -90,7 +90,8 @@ public SparseVectorQueryBuilder( : (this.shouldPruneTokens ? new TokenPruningConfig() : null)); this.weightedTokensSupplier = null; - if (queryVectors == null ^ inferenceId == null == false) { + // Preserve BWC error messaging + if (queryVectors != null && inferenceId != null) { throw new IllegalArgumentException( "[" + NAME @@ -98,18 +99,24 @@ public SparseVectorQueryBuilder( + QUERY_VECTOR_FIELD.getPreferredName() + "] or [" + INFERENCE_ID_FIELD.getPreferredName() - + "]" + + "] for " + + ALLOWED_FIELD_TYPE + + " fields" ); } - if (inferenceId != null && query == null) { + + // Preserve BWC error messaging + if ((queryVectors == null) == (query == null)) { throw new IllegalArgumentException( "[" + NAME - + "] requires [" - + QUERY_FIELD.getPreferredName() - + "] when [" + + "] requires one of [" + + QUERY_VECTOR_FIELD.getPreferredName() + + "] or [" + INFERENCE_ID_FIELD.getPreferredName() - + "] is specified" + + "] for " + + ALLOWED_FIELD_TYPE + + " fields" ); } } @@ -143,6 +150,14 @@ public List getQueryVectors() { return queryVectors; } + public String getInferenceId() { + return inferenceId; + } + + public String getQuery() { + return query; + } + public boolean shouldPruneTokens() { return shouldPruneTokens; } @@ -176,7 +191,9 @@ protected void doXContent(XContentBuilder builder, Params params) throws IOExcep } builder.endObject(); } else { - builder.field(INFERENCE_ID_FIELD.getPreferredName(), inferenceId); + if (inferenceId != null) { + builder.field(INFERENCE_ID_FIELD.getPreferredName(), inferenceId); + } builder.field(QUERY_FIELD.getPreferredName(), query); } builder.field(PRUNE_FIELD.getPreferredName(), shouldPruneTokens); @@ -228,6 +245,11 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) { shouldPruneTokens, tokenPruningConfig ); + } else if (inferenceId == null) { + // Edge case, where inference_id was not specified in the request, + // but we did not intercept this and rewrite to a query o field with + // pre-configured inference. So we trap here and output a nicer error message. + throw new IllegalArgumentException("inference_id required to perform vector search on query string"); } // TODO move this to xpack core and use inference APIs diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilderTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilderTests.java index a5c1ba45d90b7..af557ed6b7f82 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilderTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/search/SparseVectorQueryBuilderTests.java @@ -260,16 +260,16 @@ public void testIllegalValues() { { IllegalArgumentException e = expectThrows( IllegalArgumentException.class, - () -> new SparseVectorQueryBuilder("field name", null, "model id") + () -> new SparseVectorQueryBuilder("field name", null, null) ); - assertEquals("[sparse_vector] requires one of [query_vector] or [inference_id]", e.getMessage()); + assertEquals("[sparse_vector] requires one of [query_vector] or [inference_id] for sparse_vector fields", e.getMessage()); } { IllegalArgumentException e = expectThrows( IllegalArgumentException.class, () -> new SparseVectorQueryBuilder("field name", "model text", null) ); - assertEquals("[sparse_vector] requires [query] when [inference_id] is specified", e.getMessage()); + assertEquals("[sparse_vector] requires one of [query_vector] or [inference_id] for sparse_vector fields", e.getMessage()); } } diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferenceFeatures.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferenceFeatures.java index 3b7613b8b0e1f..876ff01812064 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferenceFeatures.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferenceFeatures.java @@ -10,13 +10,15 @@ import org.elasticsearch.features.FeatureSpecification; import org.elasticsearch.features.NodeFeature; import org.elasticsearch.xpack.inference.mapper.SemanticTextFieldMapper; -import org.elasticsearch.xpack.inference.queries.SemanticMatchQueryRewriteInterceptor; import org.elasticsearch.xpack.inference.queries.SemanticQueryBuilder; import org.elasticsearch.xpack.inference.rank.random.RandomRankRetrieverBuilder; import org.elasticsearch.xpack.inference.rank.textsimilarity.TextSimilarityRankRetrieverBuilder; import java.util.Set; +import static org.elasticsearch.xpack.inference.queries.SemanticMatchQueryRewriteInterceptor.SEMANTIC_MATCH_QUERY_REWRITE_INTERCEPTION_SUPPORTED; +import static org.elasticsearch.xpack.inference.queries.SemanticSparseVectorQueryRewriteInterceptor.SEMANTIC_SPARSE_VECTOR_QUERY_REWRITE_INTERCEPTION_SUPPORTED; + /** * Provides inference features. */ @@ -45,7 +47,8 @@ public Set getTestFeatures() { SemanticTextFieldMapper.SEMANTIC_TEXT_ZERO_SIZE_FIX, SemanticTextFieldMapper.SEMANTIC_TEXT_ALWAYS_EMIT_INFERENCE_ID_FIX, SEMANTIC_TEXT_HIGHLIGHTER, - SemanticMatchQueryRewriteInterceptor.SEMANTIC_MATCH_QUERY_REWRITE_INTERCEPTION_SUPPORTED + SEMANTIC_MATCH_QUERY_REWRITE_INTERCEPTION_SUPPORTED, + SEMANTIC_SPARSE_VECTOR_QUERY_REWRITE_INTERCEPTION_SUPPORTED ); } } diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java index 93743a5485c2c..169c8f87043e8 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java @@ -80,6 +80,7 @@ import org.elasticsearch.xpack.inference.mapper.SemanticTextFieldMapper; import org.elasticsearch.xpack.inference.queries.SemanticMatchQueryRewriteInterceptor; import org.elasticsearch.xpack.inference.queries.SemanticQueryBuilder; +import org.elasticsearch.xpack.inference.queries.SemanticSparseVectorQueryRewriteInterceptor; import org.elasticsearch.xpack.inference.rank.random.RandomRankBuilder; import org.elasticsearch.xpack.inference.rank.random.RandomRankRetrieverBuilder; import org.elasticsearch.xpack.inference.rank.textsimilarity.TextSimilarityRankBuilder; @@ -440,7 +441,7 @@ public List> getQueries() { @Override public List getQueryRewriteInterceptors() { - return List.of(new SemanticMatchQueryRewriteInterceptor()); + return List.of(new SemanticMatchQueryRewriteInterceptor(), new SemanticSparseVectorQueryRewriteInterceptor()); } @Override diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/queries/SemanticMatchQueryRewriteInterceptor.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/queries/SemanticMatchQueryRewriteInterceptor.java index a4a8123935c3e..fd1d65d00faf5 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/queries/SemanticMatchQueryRewriteInterceptor.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/queries/SemanticMatchQueryRewriteInterceptor.java @@ -7,24 +7,12 @@ package org.elasticsearch.xpack.inference.queries; -import org.elasticsearch.action.ResolvedIndices; -import org.elasticsearch.cluster.metadata.IndexMetadata; -import org.elasticsearch.cluster.metadata.InferenceFieldMetadata; import org.elasticsearch.features.NodeFeature; -import org.elasticsearch.index.mapper.IndexFieldMapper; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.MatchQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; -import org.elasticsearch.index.query.QueryRewriteContext; -import org.elasticsearch.index.query.TermQueryBuilder; -import org.elasticsearch.index.query.TermsQueryBuilder; -import org.elasticsearch.plugins.internal.rewriter.QueryRewriteInterceptor; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -public class SemanticMatchQueryRewriteInterceptor implements QueryRewriteInterceptor { +public class SemanticMatchQueryRewriteInterceptor extends SemanticQueryRewriteInterceptor { public static final NodeFeature SEMANTIC_MATCH_QUERY_REWRITE_INTERCEPTION_SUPPORTED = new NodeFeature( "search.semantic_match_query_rewrite_interception_supported" @@ -33,63 +21,45 @@ public class SemanticMatchQueryRewriteInterceptor implements QueryRewriteInterce public SemanticMatchQueryRewriteInterceptor() {} @Override - public QueryBuilder interceptAndRewrite(QueryRewriteContext context, QueryBuilder queryBuilder) { + protected String getFieldName(QueryBuilder queryBuilder) { assert (queryBuilder instanceof MatchQueryBuilder); MatchQueryBuilder matchQueryBuilder = (MatchQueryBuilder) queryBuilder; - QueryBuilder rewritten = queryBuilder; - ResolvedIndices resolvedIndices = context.getResolvedIndices(); - if (resolvedIndices != null) { - Collection indexMetadataCollection = resolvedIndices.getConcreteLocalIndicesMetadata().values(); - List inferenceIndices = new ArrayList<>(); - List nonInferenceIndices = new ArrayList<>(); - for (IndexMetadata indexMetadata : indexMetadataCollection) { - String indexName = indexMetadata.getIndex().getName(); - InferenceFieldMetadata inferenceFieldMetadata = indexMetadata.getInferenceFields().get(matchQueryBuilder.fieldName()); - if (inferenceFieldMetadata != null) { - inferenceIndices.add(indexName); - } else { - nonInferenceIndices.add(indexName); - } - } - - if (inferenceIndices.isEmpty()) { - return rewritten; - } else if (nonInferenceIndices.isEmpty() == false) { - BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); - for (String inferenceIndexName : inferenceIndices) { - // Add a separate clause for each semantic query, because they may be using different inference endpoints - // TODO - consolidate this to a single clause once the semantic query supports multiple inference endpoints - boolQueryBuilder.should( - createSemanticSubQuery(inferenceIndexName, matchQueryBuilder.fieldName(), (String) matchQueryBuilder.value()) - ); - } - boolQueryBuilder.should(createMatchSubQuery(nonInferenceIndices, matchQueryBuilder)); - rewritten = boolQueryBuilder; - } else { - rewritten = new SemanticQueryBuilder(matchQueryBuilder.fieldName(), (String) matchQueryBuilder.value(), false); - } - } - - return rewritten; + return matchQueryBuilder.fieldName(); + } + @Override + protected String getQuery(QueryBuilder queryBuilder) { + assert (queryBuilder instanceof MatchQueryBuilder); + MatchQueryBuilder matchQueryBuilder = (MatchQueryBuilder) queryBuilder; + return (String) matchQueryBuilder.value(); } @Override - public String getQueryName() { - return MatchQueryBuilder.NAME; + protected QueryBuilder buildInferenceQuery(QueryBuilder queryBuilder, InferenceIndexInformationForField indexInformation) { + return new SemanticQueryBuilder(indexInformation.fieldName(), getQuery(queryBuilder), false); } - private QueryBuilder createSemanticSubQuery(String indexName, String fieldName, String value) { + @Override + protected QueryBuilder buildCombinedInferenceAndNonInferenceQuery( + QueryBuilder queryBuilder, + InferenceIndexInformationForField indexInformation + ) { + assert (queryBuilder instanceof MatchQueryBuilder); + MatchQueryBuilder matchQueryBuilder = (MatchQueryBuilder) queryBuilder; BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); - boolQueryBuilder.must(new SemanticQueryBuilder(fieldName, value, true)); - boolQueryBuilder.filter(new TermQueryBuilder(IndexFieldMapper.NAME, indexName)); + boolQueryBuilder.should( + createSemanticSubQuery( + indexInformation.getInferenceIndices(), + matchQueryBuilder.fieldName(), + (String) matchQueryBuilder.value() + ) + ); + boolQueryBuilder.should(createSubQueryForIndices(indexInformation.nonInferenceIndices(), matchQueryBuilder)); return boolQueryBuilder; } - private QueryBuilder createMatchSubQuery(List indices, MatchQueryBuilder matchQueryBuilder) { - BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); - boolQueryBuilder.must(matchQueryBuilder); - boolQueryBuilder.filter(new TermsQueryBuilder(IndexFieldMapper.NAME, indices)); - return boolQueryBuilder; + @Override + public String getQueryName() { + return MatchQueryBuilder.NAME; } } diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/queries/SemanticQueryBuilder.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/queries/SemanticQueryBuilder.java index 2a34651efcd9d..dd0f6fe59ab23 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/queries/SemanticQueryBuilder.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/queries/SemanticQueryBuilder.java @@ -148,6 +148,14 @@ public String getWriteableName() { return NAME; } + public String getFieldName() { + return fieldName; + } + + public String getQuery() { + return query; + } + @Override public TransportVersion getMinimalSupportedVersion() { return TransportVersions.V_8_15_0; diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/queries/SemanticQueryRewriteInterceptor.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/queries/SemanticQueryRewriteInterceptor.java new file mode 100644 index 0000000000000..bb76ef0be24e9 --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/queries/SemanticQueryRewriteInterceptor.java @@ -0,0 +1,148 @@ +/* + * 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.inference.queries; + +import org.elasticsearch.action.ResolvedIndices; +import org.elasticsearch.cluster.metadata.IndexMetadata; +import org.elasticsearch.cluster.metadata.InferenceFieldMetadata; +import org.elasticsearch.index.mapper.IndexFieldMapper; +import org.elasticsearch.index.query.BoolQueryBuilder; +import org.elasticsearch.index.query.QueryBuilder; +import org.elasticsearch.index.query.QueryRewriteContext; +import org.elasticsearch.index.query.TermsQueryBuilder; +import org.elasticsearch.plugins.internal.rewriter.QueryRewriteInterceptor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Intercepts and adapts a query to be rewritten to work seamlessly on a semantic_text field. + */ +public abstract class SemanticQueryRewriteInterceptor implements QueryRewriteInterceptor { + + public SemanticQueryRewriteInterceptor() {} + + @Override + public QueryBuilder interceptAndRewrite(QueryRewriteContext context, QueryBuilder queryBuilder) { + String fieldName = getFieldName(queryBuilder); + ResolvedIndices resolvedIndices = context.getResolvedIndices(); + + if (resolvedIndices == null) { + // No resolved indices, so return the original query. + return queryBuilder; + } + + InferenceIndexInformationForField indexInformation = resolveIndicesForField(fieldName, resolvedIndices); + if (indexInformation.getInferenceIndices().isEmpty()) { + // No inference fields were identified, so return the original query. + return queryBuilder; + } else if (indexInformation.nonInferenceIndices().isEmpty() == false) { + // Combined case where the field name requested by this query contains both + // semantic_text and non-inference fields, so we have to combine queries per index + // containing each field type. + return buildCombinedInferenceAndNonInferenceQuery(queryBuilder, indexInformation); + } else { + // The only fields we've identified are inference fields (e.g. semantic_text), + // so rewrite the entire query to work on a semantic_text field. + return buildInferenceQuery(queryBuilder, indexInformation); + } + } + + /** + * @param queryBuilder {@link QueryBuilder} + * @return The singular field name requested by the provided query builder. + */ + protected abstract String getFieldName(QueryBuilder queryBuilder); + + /** + * @param queryBuilder {@link QueryBuilder} + * @return The text/query string requested by the provided query builder. + */ + protected abstract String getQuery(QueryBuilder queryBuilder); + + /** + * Builds the inference query + * + * @param queryBuilder {@link QueryBuilder} + * @param indexInformation {@link InferenceIndexInformationForField} + * @return {@link QueryBuilder} + */ + protected abstract QueryBuilder buildInferenceQuery(QueryBuilder queryBuilder, InferenceIndexInformationForField indexInformation); + + /** + * Builds a combined inference and non-inference query, + * which separates the different queries into appropriate indices based on field type. + * @param queryBuilder {@link QueryBuilder} + * @param indexInformation {@link InferenceIndexInformationForField} + * @return {@link QueryBuilder} + */ + protected abstract QueryBuilder buildCombinedInferenceAndNonInferenceQuery( + QueryBuilder queryBuilder, + InferenceIndexInformationForField indexInformation + ); + + private InferenceIndexInformationForField resolveIndicesForField(String fieldName, ResolvedIndices resolvedIndices) { + Collection indexMetadataCollection = resolvedIndices.getConcreteLocalIndicesMetadata().values(); + Map inferenceIndicesMetadata = new HashMap<>(); + List nonInferenceIndices = new ArrayList<>(); + for (IndexMetadata indexMetadata : indexMetadataCollection) { + String indexName = indexMetadata.getIndex().getName(); + InferenceFieldMetadata inferenceFieldMetadata = indexMetadata.getInferenceFields().get(fieldName); + if (inferenceFieldMetadata != null) { + inferenceIndicesMetadata.put(indexName, inferenceFieldMetadata); + } else { + nonInferenceIndices.add(indexName); + } + } + + return new InferenceIndexInformationForField(fieldName, inferenceIndicesMetadata, nonInferenceIndices); + } + + protected QueryBuilder createSubQueryForIndices(Collection indices, QueryBuilder queryBuilder) { + BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); + boolQueryBuilder.must(queryBuilder); + boolQueryBuilder.filter(new TermsQueryBuilder(IndexFieldMapper.NAME, indices)); + return boolQueryBuilder; + } + + protected QueryBuilder createSemanticSubQuery(Collection indices, String fieldName, String value) { + BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); + boolQueryBuilder.must(new SemanticQueryBuilder(fieldName, value, true)); + boolQueryBuilder.filter(new TermsQueryBuilder(IndexFieldMapper.NAME, indices)); + return boolQueryBuilder; + } + + /** + * Represents the indices and associated inference information for a field. + */ + public record InferenceIndexInformationForField( + String fieldName, + Map inferenceIndicesMetadata, + List nonInferenceIndices + ) { + + public Collection getInferenceIndices() { + return inferenceIndicesMetadata.keySet(); + } + + public Map> getInferenceIdsIndices() { + return inferenceIndicesMetadata.entrySet() + .stream() + .collect( + Collectors.groupingBy( + entry -> entry.getValue().getSearchInferenceId(), + Collectors.mapping(Map.Entry::getKey, Collectors.toList()) + ) + ); + } + } +} diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/queries/SemanticSparseVectorQueryRewriteInterceptor.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/queries/SemanticSparseVectorQueryRewriteInterceptor.java new file mode 100644 index 0000000000000..a35e83450c55a --- /dev/null +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/queries/SemanticSparseVectorQueryRewriteInterceptor.java @@ -0,0 +1,124 @@ +/* + * 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.inference.queries; + +import org.apache.lucene.search.join.ScoreMode; +import org.elasticsearch.features.NodeFeature; +import org.elasticsearch.index.query.BoolQueryBuilder; +import org.elasticsearch.index.query.QueryBuilder; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.xpack.core.ml.search.SparseVectorQueryBuilder; +import org.elasticsearch.xpack.inference.mapper.SemanticTextField; + +import java.util.List; +import java.util.Map; + +public class SemanticSparseVectorQueryRewriteInterceptor extends SemanticQueryRewriteInterceptor { + + public static final NodeFeature SEMANTIC_SPARSE_VECTOR_QUERY_REWRITE_INTERCEPTION_SUPPORTED = new NodeFeature( + "search.semantic_sparse_vector_query_rewrite_interception_supported" + ); + + public SemanticSparseVectorQueryRewriteInterceptor() {} + + @Override + protected String getFieldName(QueryBuilder queryBuilder) { + assert (queryBuilder instanceof SparseVectorQueryBuilder); + SparseVectorQueryBuilder sparseVectorQueryBuilder = (SparseVectorQueryBuilder) queryBuilder; + return sparseVectorQueryBuilder.getFieldName(); + } + + @Override + protected String getQuery(QueryBuilder queryBuilder) { + assert (queryBuilder instanceof SparseVectorQueryBuilder); + SparseVectorQueryBuilder sparseVectorQueryBuilder = (SparseVectorQueryBuilder) queryBuilder; + return sparseVectorQueryBuilder.getQuery(); + } + + @Override + protected QueryBuilder buildInferenceQuery(QueryBuilder queryBuilder, InferenceIndexInformationForField indexInformation) { + Map> inferenceIdsIndices = indexInformation.getInferenceIdsIndices(); + if (inferenceIdsIndices.size() == 1) { + // Simple case, everything uses the same inference ID + String searchInferenceId = inferenceIdsIndices.keySet().iterator().next(); + return buildNestedQueryFromSparseVectorQuery(queryBuilder, searchInferenceId); + } else { + // Multiple inference IDs, construct a boolean query + return buildInferenceQueryWithMultipleInferenceIds(queryBuilder, inferenceIdsIndices); + } + } + + private QueryBuilder buildInferenceQueryWithMultipleInferenceIds( + QueryBuilder queryBuilder, + Map> inferenceIdsIndices + ) { + BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); + for (String inferenceId : inferenceIdsIndices.keySet()) { + boolQueryBuilder.should( + createSubQueryForIndices( + inferenceIdsIndices.get(inferenceId), + buildNestedQueryFromSparseVectorQuery(queryBuilder, inferenceId) + ) + ); + } + return boolQueryBuilder; + } + + @Override + protected QueryBuilder buildCombinedInferenceAndNonInferenceQuery( + QueryBuilder queryBuilder, + InferenceIndexInformationForField indexInformation + ) { + assert (queryBuilder instanceof SparseVectorQueryBuilder); + SparseVectorQueryBuilder sparseVectorQueryBuilder = (SparseVectorQueryBuilder) queryBuilder; + Map> inferenceIdsIndices = indexInformation.getInferenceIdsIndices(); + + BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder(); + boolQueryBuilder.should( + createSubQueryForIndices( + indexInformation.nonInferenceIndices(), + createSubQueryForIndices(indexInformation.nonInferenceIndices(), sparseVectorQueryBuilder) + ) + ); + // We always perform nested subqueries on semantic_text fields, to support + // sparse_vector queries using query vectors. + for (String inferenceId : inferenceIdsIndices.keySet()) { + boolQueryBuilder.should( + createSubQueryForIndices( + inferenceIdsIndices.get(inferenceId), + buildNestedQueryFromSparseVectorQuery(sparseVectorQueryBuilder, inferenceId) + ) + ); + } + return boolQueryBuilder; + } + + private QueryBuilder buildNestedQueryFromSparseVectorQuery(QueryBuilder queryBuilder, String searchInferenceId) { + assert (queryBuilder instanceof SparseVectorQueryBuilder); + SparseVectorQueryBuilder sparseVectorQueryBuilder = (SparseVectorQueryBuilder) queryBuilder; + return QueryBuilders.nestedQuery( + SemanticTextField.getChunksFieldName(sparseVectorQueryBuilder.getFieldName()), + new SparseVectorQueryBuilder( + SemanticTextField.getEmbeddingsFieldName(sparseVectorQueryBuilder.getFieldName()), + sparseVectorQueryBuilder.getQueryVectors(), + (sparseVectorQueryBuilder.getInferenceId() == null && sparseVectorQueryBuilder.getQuery() != null) + ? searchInferenceId + : sparseVectorQueryBuilder.getInferenceId(), + sparseVectorQueryBuilder.getQuery(), + sparseVectorQueryBuilder.shouldPruneTokens(), + sparseVectorQueryBuilder.getTokenPruningConfig() + ), + ScoreMode.Max + ); + } + + @Override + public String getQueryName() { + return SparseVectorQueryBuilder.NAME; + } +} diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/index/query/SemanticMatchQueryRewriteInterceptorTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/index/query/SemanticMatchQueryRewriteInterceptorTests.java new file mode 100644 index 0000000000000..47705c14d5941 --- /dev/null +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/index/query/SemanticMatchQueryRewriteInterceptorTests.java @@ -0,0 +1,110 @@ +/* + * 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.index.query; + +import org.elasticsearch.action.MockResolvedIndices; +import org.elasticsearch.action.OriginalIndices; +import org.elasticsearch.action.ResolvedIndices; +import org.elasticsearch.action.support.IndicesOptions; +import org.elasticsearch.cluster.metadata.IndexMetadata; +import org.elasticsearch.cluster.metadata.InferenceFieldMetadata; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.index.Index; +import org.elasticsearch.index.IndexVersion; +import org.elasticsearch.plugins.internal.rewriter.QueryRewriteInterceptor; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.test.client.NoOpClient; +import org.elasticsearch.threadpool.TestThreadPool; +import org.elasticsearch.xpack.inference.queries.SemanticMatchQueryRewriteInterceptor; +import org.elasticsearch.xpack.inference.queries.SemanticQueryBuilder; +import org.junit.After; +import org.junit.Before; + +import java.io.IOException; +import java.util.Map; + +public class SemanticMatchQueryRewriteInterceptorTests extends ESTestCase { + + private TestThreadPool threadPool; + private NoOpClient client; + private Index index; + + private static final String FIELD_NAME = "fieldName"; + private static final String VALUE = "value"; + + @Before + public void setup() { + threadPool = createThreadPool(); + client = new NoOpClient(threadPool); + index = new Index(randomAlphaOfLength(10), randomAlphaOfLength(10)); + } + + @After + public void cleanup() { + threadPool.close(); + } + + public void testMatchQueryOnInferenceFieldIsInterceptedAndRewrittenToSemanticQuery() throws IOException { + Map inferenceFields = Map.of( + FIELD_NAME, + new InferenceFieldMetadata(index.getName(), "inferenceId", new String[] { FIELD_NAME }) + ); + QueryRewriteContext context = createQueryRewriteContext(inferenceFields); + QueryBuilder original = createTestQueryBuilder(); + QueryBuilder rewritten = original.rewrite(context); + assertTrue( + "Expected query to be intercepted, but was [" + rewritten.getClass().getName() + "]", + rewritten instanceof InterceptedQueryBuilderWrapper + ); + InterceptedQueryBuilderWrapper intercepted = (InterceptedQueryBuilderWrapper) rewritten; + assertTrue(intercepted.queryBuilder instanceof SemanticQueryBuilder); + SemanticQueryBuilder semanticQueryBuilder = (SemanticQueryBuilder) intercepted.queryBuilder; + assertEquals(FIELD_NAME, semanticQueryBuilder.getFieldName()); + assertEquals(VALUE, semanticQueryBuilder.getQuery()); + } + + public void testMatchQueryOnNonInferenceFieldRemainsMatchQuery() throws IOException { + QueryRewriteContext context = createQueryRewriteContext(Map.of()); // No inference fields + QueryBuilder original = createTestQueryBuilder(); + QueryBuilder rewritten = original.rewrite(context); + assertTrue( + "Expected query to remain match but was [" + rewritten.getClass().getName() + "]", + rewritten instanceof MatchQueryBuilder + ); + assertEquals(original, rewritten); + } + + private MatchQueryBuilder createTestQueryBuilder() { + return new MatchQueryBuilder(FIELD_NAME, VALUE); + } + + private QueryRewriteContext createQueryRewriteContext(Map inferenceFields) { + IndexMetadata indexMetadata = IndexMetadata.builder(index.getName()) + .settings( + Settings.builder() + .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersion.current()) + .put(IndexMetadata.SETTING_INDEX_UUID, index.getUUID()) + ) + .numberOfShards(1) + .numberOfReplicas(0) + .putInferenceFields(inferenceFields) + .build(); + + ResolvedIndices resolvedIndices = new MockResolvedIndices( + Map.of(), + new OriginalIndices(new String[] { index.getName() }, IndicesOptions.DEFAULT), + Map.of(index, indexMetadata) + ); + + return new QueryRewriteContext(null, client, null, resolvedIndices, null, createRewriteInterceptor()); + } + + private QueryRewriteInterceptor createRewriteInterceptor() { + return new SemanticMatchQueryRewriteInterceptor(); + } +} diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/index/query/SemanticSparseVectorQueryRewriteInterceptorTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/index/query/SemanticSparseVectorQueryRewriteInterceptorTests.java new file mode 100644 index 0000000000000..1adad1df7b29b --- /dev/null +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/index/query/SemanticSparseVectorQueryRewriteInterceptorTests.java @@ -0,0 +1,137 @@ +/* + * 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.index.query; + +import org.elasticsearch.action.MockResolvedIndices; +import org.elasticsearch.action.OriginalIndices; +import org.elasticsearch.action.ResolvedIndices; +import org.elasticsearch.action.support.IndicesOptions; +import org.elasticsearch.cluster.metadata.IndexMetadata; +import org.elasticsearch.cluster.metadata.InferenceFieldMetadata; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.index.Index; +import org.elasticsearch.index.IndexVersion; +import org.elasticsearch.plugins.internal.rewriter.QueryRewriteInterceptor; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.test.client.NoOpClient; +import org.elasticsearch.threadpool.TestThreadPool; +import org.elasticsearch.xpack.core.ml.search.SparseVectorQueryBuilder; +import org.elasticsearch.xpack.inference.mapper.SemanticTextField; +import org.elasticsearch.xpack.inference.queries.SemanticSparseVectorQueryRewriteInterceptor; +import org.junit.After; +import org.junit.Before; + +import java.io.IOException; +import java.util.Map; + +public class SemanticSparseVectorQueryRewriteInterceptorTests extends ESTestCase { + + private TestThreadPool threadPool; + private NoOpClient client; + private Index index; + + private static final String FIELD_NAME = "fieldName"; + private static final String INFERENCE_ID = "inferenceId"; + private static final String QUERY = "query"; + + @Before + public void setup() { + threadPool = createThreadPool(); + client = new NoOpClient(threadPool); + index = new Index(randomAlphaOfLength(10), randomAlphaOfLength(10)); + } + + @After + public void cleanup() { + threadPool.close(); + } + + public void testSparseVectorQueryOnInferenceFieldIsInterceptedAndRewritten() throws IOException { + Map inferenceFields = Map.of( + FIELD_NAME, + new InferenceFieldMetadata(index.getName(), "inferenceId", new String[] { FIELD_NAME }) + ); + QueryRewriteContext context = createQueryRewriteContext(inferenceFields); + QueryBuilder original = new SparseVectorQueryBuilder(FIELD_NAME, INFERENCE_ID, QUERY); + QueryBuilder rewritten = original.rewrite(context); + assertTrue( + "Expected query to be intercepted, but was [" + rewritten.getClass().getName() + "]", + rewritten instanceof InterceptedQueryBuilderWrapper + ); + InterceptedQueryBuilderWrapper intercepted = (InterceptedQueryBuilderWrapper) rewritten; + assertTrue(intercepted.queryBuilder instanceof NestedQueryBuilder); + NestedQueryBuilder nestedQueryBuilder = (NestedQueryBuilder) intercepted.queryBuilder; + assertEquals(SemanticTextField.getChunksFieldName(FIELD_NAME), nestedQueryBuilder.path()); + QueryBuilder innerQuery = nestedQueryBuilder.query(); + assertTrue(innerQuery instanceof SparseVectorQueryBuilder); + SparseVectorQueryBuilder sparseVectorQueryBuilder = (SparseVectorQueryBuilder) innerQuery; + assertEquals(SemanticTextField.getEmbeddingsFieldName(FIELD_NAME), sparseVectorQueryBuilder.getFieldName()); + assertEquals(INFERENCE_ID, sparseVectorQueryBuilder.getInferenceId()); + assertEquals(QUERY, sparseVectorQueryBuilder.getQuery()); + } + + public void testSparseVectorQueryOnInferenceFieldWithoutInferenceIdIsInterceptedAndRewritten() throws IOException { + Map inferenceFields = Map.of( + FIELD_NAME, + new InferenceFieldMetadata(index.getName(), "inferenceId", new String[] { FIELD_NAME }) + ); + QueryRewriteContext context = createQueryRewriteContext(inferenceFields); + QueryBuilder original = new SparseVectorQueryBuilder(FIELD_NAME, null, QUERY); + QueryBuilder rewritten = original.rewrite(context); + assertTrue( + "Expected query to be intercepted, but was [" + rewritten.getClass().getName() + "]", + rewritten instanceof InterceptedQueryBuilderWrapper + ); + InterceptedQueryBuilderWrapper intercepted = (InterceptedQueryBuilderWrapper) rewritten; + assertTrue(intercepted.queryBuilder instanceof NestedQueryBuilder); + NestedQueryBuilder nestedQueryBuilder = (NestedQueryBuilder) intercepted.queryBuilder; + assertEquals(SemanticTextField.getChunksFieldName(FIELD_NAME), nestedQueryBuilder.path()); + QueryBuilder innerQuery = nestedQueryBuilder.query(); + assertTrue(innerQuery instanceof SparseVectorQueryBuilder); + SparseVectorQueryBuilder sparseVectorQueryBuilder = (SparseVectorQueryBuilder) innerQuery; + assertEquals(SemanticTextField.getEmbeddingsFieldName(FIELD_NAME), sparseVectorQueryBuilder.getFieldName()); + assertEquals(INFERENCE_ID, sparseVectorQueryBuilder.getInferenceId()); + assertEquals(QUERY, sparseVectorQueryBuilder.getQuery()); + } + + public void testSparseVectorQueryOnNonInferenceFieldRemainsUnchanged() throws IOException { + QueryRewriteContext context = createQueryRewriteContext(Map.of()); // No inference fields + QueryBuilder original = new SparseVectorQueryBuilder(FIELD_NAME, INFERENCE_ID, QUERY); + QueryBuilder rewritten = original.rewrite(context); + assertTrue( + "Expected query to remain sparse_vector but was [" + rewritten.getClass().getName() + "]", + rewritten instanceof SparseVectorQueryBuilder + ); + assertEquals(original, rewritten); + } + + private QueryRewriteContext createQueryRewriteContext(Map inferenceFields) { + IndexMetadata indexMetadata = IndexMetadata.builder(index.getName()) + .settings( + Settings.builder() + .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersion.current()) + .put(IndexMetadata.SETTING_INDEX_UUID, index.getUUID()) + ) + .numberOfShards(1) + .numberOfReplicas(0) + .putInferenceFields(inferenceFields) + .build(); + + ResolvedIndices resolvedIndices = new MockResolvedIndices( + Map.of(), + new OriginalIndices(new String[] { index.getName() }, IndicesOptions.DEFAULT), + Map.of(index, indexMetadata) + ); + + return new QueryRewriteContext(null, client, null, resolvedIndices, null, createRewriteInterceptor()); + } + + private QueryRewriteInterceptor createRewriteInterceptor() { + return new SemanticSparseVectorQueryRewriteInterceptor(); + } +} diff --git a/x-pack/plugin/inference/src/yamlRestTest/resources/rest-api-spec/test/inference/46_semantic_text_sparse_vector.yml b/x-pack/plugin/inference/src/yamlRestTest/resources/rest-api-spec/test/inference/46_semantic_text_sparse_vector.yml new file mode 100644 index 0000000000000..f1cff512fd209 --- /dev/null +++ b/x-pack/plugin/inference/src/yamlRestTest/resources/rest-api-spec/test/inference/46_semantic_text_sparse_vector.yml @@ -0,0 +1,249 @@ +setup: + - requires: + cluster_features: "search.semantic_sparse_vector_query_rewrite_interception_supported" + reason: semantic_text sparse_vector support introduced in 8.18.0 + + - do: + inference.put: + task_type: sparse_embedding + inference_id: sparse-inference-id + body: > + { + "service": "test_service", + "service_settings": { + "model": "my_model", + "api_key": "abc64" + }, + "task_settings": { + } + } + + - do: + inference.put: + task_type: sparse_embedding + inference_id: sparse-inference-id-2 + body: > + { + "service": "test_service", + "service_settings": { + "model": "my_model", + "api_key": "abc64" + }, + "task_settings": { + } + } + + - do: + indices.create: + index: test-semantic-text-index + body: + mappings: + properties: + inference_field: + type: semantic_text + inference_id: sparse-inference-id + + - do: + indices.create: + index: test-semantic-text-index-2 + body: + mappings: + properties: + inference_field: + type: semantic_text + inference_id: sparse-inference-id-2 + + - do: + indices.create: + index: test-sparse-vector-index + body: + mappings: + properties: + inference_field: + type: sparse_vector + + - do: + index: + index: test-semantic-text-index + id: doc_1 + body: + inference_field: [ "inference test", "another inference test" ] + refresh: true + + - do: + index: + index: test-semantic-text-index-2 + id: doc_3 + body: + inference_field: [ "inference test", "another inference test" ] + refresh: true + + - do: + index: + index: test-sparse-vector-index + id: doc_2 + body: + inference_field: { "feature_0": 1, "feature_1": 2, "feature_2": 3, "feature_3": 4, "feature_4": 5 } + refresh: true + +--- +"Nested sparse_vector queries using the old format on semantic_text embeddings and inference still work": + - skip: + features: [ "headers" ] + + - do: + headers: + # Force JSON content type so that we use a parser that interprets the floating-point score as a double + Content-Type: application/json + search: + index: test-semantic-text-index + body: + query: + nested: + path: inference_field.inference.chunks + query: + sparse_vector: + field: inference_field.inference.chunks.embeddings + inference_id: sparse-inference-id + query: test + + - match: { hits.total.value: 1 } + - match: { hits.hits.0._id: "doc_1" } + +--- +"Nested sparse_vector queries using the old format on semantic_text embeddings and query vectors still work": + - skip: + features: [ "headers" ] + + - do: + headers: + # Force JSON content type so that we use a parser that interprets the floating-point score as a double + Content-Type: application/json + search: + index: test-semantic-text-index + body: + query: + nested: + path: inference_field.inference.chunks + query: + sparse_vector: + field: inference_field.inference.chunks.embeddings + query_vector: { "feature_0": 1, "feature_1": 2, "feature_2": 3, "feature_3": 4, "feature_4": 5 } + + - match: { hits.total.value: 1 } + - match: { hits.hits.0._id: "doc_1" } + +--- +"sparse_vector query against semantic_text field using a specified inference ID": + + - do: + search: + index: test-semantic-text-index + body: + query: + sparse_vector: + field: inference_field + inference_id: sparse-inference-id + query: "inference test" + + - match: { hits.total.value: 1 } + - match: { hits.hits.0._id: "doc_1" } + +--- +"sparse_vector query against semantic_text field using inference ID configured in semantic_text field": + + - do: + search: + index: test-semantic-text-index + body: + query: + sparse_vector: + field: inference_field + query: "inference test" + + - match: { hits.total.value: 1 } + - match: { hits.hits.0._id: "doc_1" } + +--- +"sparse_vector query against semantic_text field using query vectors": + + - do: + search: + index: test-semantic-text-index + body: + query: + sparse_vector: + field: inference_field + query_vector: { "feature_0": 1, "feature_1": 2, "feature_2": 3, "feature_3": 4, "feature_4": 5 } + + - match: { hits.total.value: 1 } + - match: { hits.hits.0._id: "doc_1" } + +--- +"sparse_vector query against combined sparse_vector and semantic_text fields using inference": + + - do: + search: + index: + - test-semantic-text-index + - test-sparse-vector-index + body: + query: + sparse_vector: + field: inference_field + inference_id: sparse-inference-id + query: "inference test" + + - match: { hits.total.value: 2 } + +--- +"sparse_vector query against combined sparse_vector and semantic_text fields still requires inference ID": + + - do: + catch: bad_request + search: + index: + - test-semantic-text-index + - test-sparse-vector-index + body: + query: + sparse_vector: + field: inference_field + query: "inference test" + + - match: { error.type: "illegal_argument_exception" } + - match: { error.reason: "inference_id required to perform vector search on query string" } + +--- +"sparse_vector query against combined sparse_vector and semantic_text fields using query vectors": + + - do: + search: + index: + - test-semantic-text-index + - test-sparse-vector-index + body: + query: + sparse_vector: + field: inference_field + query_vector: { "feature_0": 1, "feature_1": 2, "feature_2": 3, "feature_3": 4, "feature_4": 5 } + + - match: { hits.total.value: 2 } + + +--- +"sparse_vector query against multiple semantic_text fields with multiple inference IDs specified in semantic_text fields": + + - do: + search: + index: + - test-semantic-text-index + - test-semantic-text-index-2 + body: + query: + sparse_vector: + field: inference_field + query: "inference test" + + - match: { hits.total.value: 2 } + diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/ml/sparse_vector_search.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/ml/sparse_vector_search.yml index 332981a580802..3481773b0bab3 100644 --- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/ml/sparse_vector_search.yml +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/ml/sparse_vector_search.yml @@ -268,7 +268,7 @@ setup: - match: { hits.hits.0._score: 0.25 } --- -"Test sparse_vector requires one of inference_id or query_vector": +"Test sparse_vector requires one of query or query_vector": - do: catch: /\[sparse_vector\] requires one of \[query_vector\] or \[inference_id\]/ search: @@ -281,7 +281,41 @@ setup: - match: { status: 400 } --- -"Test sparse_vector only allows one of inference_id or query_vector": +"Test sparse_vector returns an error if inference ID not specified with query": + - do: + catch: bad_request # This is for BWC, the actual error message is tested in a subsequent test + search: + index: index-with-sparse-vector + body: + query: + sparse_vector: + field: text + query: "octopus comforter smells" + + - match: { status: 400 } + +--- +"Test sparse_vector requires an inference ID to be specified on sparse_vector fields": + - requires: + cluster_features: [ "search.semantic_sparse_vector_query_rewrite_interception_supported" ] + reason: "Error message changed in 8.18" + - do: + catch: /inference_id required to perform vector search on query string/ + search: + index: index-with-sparse-vector + body: + query: + sparse_vector: + field: text + query: "octopus comforter smells" + + - match: { status: 400 } + +--- +"Test sparse_vector only allows one of query or query_vector (note the error message is misleading)": + - requires: + cluster_features: [ "search.semantic_sparse_vector_query_rewrite_interception_supported" ] + reason: "sparse vector inference checks updated in 8.18 to support sparse_vector on semantic_text fields" - do: catch: /\[sparse_vector\] requires one of \[query_vector\] or \[inference_id\]/ search: @@ -290,7 +324,7 @@ setup: query: sparse_vector: field: text - inference_id: text_expansion_model + query: "octopus comforter smells" query_vector: the: 1.0 comforter: 1.0 From a6dcaee4199353d8cbd4a2fd67df9d833684b8ab Mon Sep 17 00:00:00 2001 From: Nick Tindall Date: Wed, 18 Dec 2024 11:58:16 +1100 Subject: [PATCH 23/60] Add test for GCS fixture (#118737) Relates: ES-5679 --- .../org/elasticsearch/rest/RestUtils.java | 8 + test/fixtures/gcs-fixture/build.gradle | 1 - .../gcs/GoogleCloudStorageHttpHandler.java | 8 +- .../GoogleCloudStorageHttpHandlerTests.java | 509 ++++++++++++++++++ 4 files changed, 520 insertions(+), 6 deletions(-) create mode 100644 test/fixtures/gcs-fixture/src/test/java/fixture/gcs/GoogleCloudStorageHttpHandlerTests.java diff --git a/server/src/main/java/org/elasticsearch/rest/RestUtils.java b/server/src/main/java/org/elasticsearch/rest/RestUtils.java index df51b57f0859c..bbca086e345f7 100644 --- a/server/src/main/java/org/elasticsearch/rest/RestUtils.java +++ b/server/src/main/java/org/elasticsearch/rest/RestUtils.java @@ -15,6 +15,7 @@ import org.elasticsearch.core.Nullable; import org.elasticsearch.core.TimeValue; +import java.net.URI; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Arrays; @@ -35,6 +36,13 @@ public class RestUtils { public static final UnaryOperator REST_DECODER = RestUtils::decodeComponent; + public static void decodeQueryString(URI uri, Map params) { + final var rawQuery = uri.getRawQuery(); + if (Strings.hasLength(rawQuery)) { + decodeQueryString(rawQuery, 0, params); + } + } + public static void decodeQueryString(String s, int fromIndex, Map params) { if (fromIndex < 0) { return; diff --git a/test/fixtures/gcs-fixture/build.gradle b/test/fixtures/gcs-fixture/build.gradle index e8f1a2e15a4e0..6cf2e1ee52c2c 100644 --- a/test/fixtures/gcs-fixture/build.gradle +++ b/test/fixtures/gcs-fixture/build.gradle @@ -9,7 +9,6 @@ apply plugin: 'elasticsearch.java' description = 'Fixture for Google Cloud Storage service' -tasks.named("test").configure { enabled = false } dependencies { api project(':server') diff --git a/test/fixtures/gcs-fixture/src/main/java/fixture/gcs/GoogleCloudStorageHttpHandler.java b/test/fixtures/gcs-fixture/src/main/java/fixture/gcs/GoogleCloudStorageHttpHandler.java index f6b52a32a9a1d..163712fb05a50 100644 --- a/test/fixtures/gcs-fixture/src/main/java/fixture/gcs/GoogleCloudStorageHttpHandler.java +++ b/test/fixtures/gcs-fixture/src/main/java/fixture/gcs/GoogleCloudStorageHttpHandler.java @@ -95,7 +95,7 @@ public void handle(final HttpExchange exchange) throws IOException { } else if (Regex.simpleMatch("GET /storage/v1/b/" + bucket + "/o*", request)) { // List Objects https://cloud.google.com/storage/docs/json_api/v1/objects/list final Map params = new HashMap<>(); - RestUtils.decodeQueryString(exchange.getRequestURI().getQuery(), 0, params); + RestUtils.decodeQueryString(exchange.getRequestURI(), params); final String prefix = params.getOrDefault("prefix", ""); final String delimiter = params.get("delimiter"); @@ -212,7 +212,7 @@ public void handle(final HttpExchange exchange) throws IOException { } else if (Regex.simpleMatch("POST /upload/storage/v1/b/" + bucket + "/*uploadType=resumable*", request)) { // Resumable upload initialization https://cloud.google.com/storage/docs/json_api/v1/how-tos/resumable-upload final Map params = new HashMap<>(); - RestUtils.decodeQueryString(exchange.getRequestURI().getQuery(), 0, params); + RestUtils.decodeQueryString(exchange.getRequestURI(), params); final String blobName = params.get("name"); blobs.put(blobName, BytesArray.EMPTY); @@ -237,7 +237,7 @@ public void handle(final HttpExchange exchange) throws IOException { } else if (Regex.simpleMatch("PUT /upload/storage/v1/b/" + bucket + "/o?*uploadType=resumable*", request)) { // Resumable upload https://cloud.google.com/storage/docs/json_api/v1/how-tos/resumable-upload final Map params = new HashMap<>(); - RestUtils.decodeQueryString(exchange.getRequestURI().getQuery(), 0, params); + RestUtils.decodeQueryString(exchange.getRequestURI(), params); final String blobName = params.get("test_blob_name"); if (blobs.containsKey(blobName) == false) { @@ -269,8 +269,6 @@ public void handle(final HttpExchange exchange) throws IOException { exchange.sendResponseHeaders(RestStatus.NOT_FOUND.getStatus(), -1); } } finally { - int read = exchange.getRequestBody().read(); - assert read == -1 : "Request body should have been fully read here but saw [" + read + "]"; exchange.close(); } } diff --git a/test/fixtures/gcs-fixture/src/test/java/fixture/gcs/GoogleCloudStorageHttpHandlerTests.java b/test/fixtures/gcs-fixture/src/test/java/fixture/gcs/GoogleCloudStorageHttpHandlerTests.java new file mode 100644 index 0000000000000..0caaa983f76df --- /dev/null +++ b/test/fixtures/gcs-fixture/src/test/java/fixture/gcs/GoogleCloudStorageHttpHandlerTests.java @@ -0,0 +1,509 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +package fixture.gcs; + +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpContext; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpPrincipal; + +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.bytes.BytesArray; +import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.bytes.CompositeBytesReference; +import org.elasticsearch.common.io.stream.BytesStreamOutput; +import org.elasticsearch.core.Nullable; +import org.elasticsearch.rest.RestStatus; +import org.elasticsearch.test.ESTestCase; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.zip.GZIPOutputStream; + +public class GoogleCloudStorageHttpHandlerTests extends ESTestCase { + + private static final String HOST = "http://127.0.0.1:12345"; + private static final int RESUME_INCOMPLETE = 308; + + public void testRejectsBadUri() { + assertEquals( + RestStatus.NOT_FOUND.getStatus(), + handleRequest(new GoogleCloudStorageHttpHandler("bucket"), randomFrom("GET", "PUT", "POST", "DELETE", "HEAD"), "/not-in-bucket") + .status() + ); + } + + public void testCheckEndpoint() { + final var handler = new GoogleCloudStorageHttpHandler("bucket"); + + assertEquals( + RestStatus.OK, + handleRequest(handler, "GET", "/", BytesArray.EMPTY, Headers.of("Metadata-Flavor", "Google")).restStatus() + ); + } + + public void testSimpleObjectOperations() { + final var bucket = randomAlphaOfLength(10); + final var handler = new GoogleCloudStorageHttpHandler(bucket); + + assertEquals(RestStatus.NOT_FOUND, handleRequest(handler, "GET", "/download/storage/v1/b/" + bucket + "/o/blob").restStatus()); + + assertEquals( + new TestHttpResponse(RestStatus.OK, "{\"kind\":\"storage#objects\",\"items\":[],\"prefixes\":[]}"), + handleRequest(handler, "GET", "/storage/v1/b/" + bucket + "/o") + ); + + // Multipart upload + final var body = randomAlphaOfLength(50); + assertEquals( + RestStatus.OK, + handleRequest( + handler, + "POST", + "/upload/storage/v1/b/" + bucket + "/?uploadType=multipart", + createGzipCompressedMultipartUploadBody(bucket, "path/blob", body) + ).restStatus() + ); + assertEquals( + new TestHttpResponse(RestStatus.OK, body), + handleRequest(handler, "GET", "/download/storage/v1/b/" + bucket + "/o/path/blob") + ); + + assertEquals(new TestHttpResponse(RestStatus.OK, Strings.format(""" + {"kind":"storage#objects","items":[{"kind":"storage#object","bucket":"%s","name":"path/blob","id":"path/blob","size":"50"} + ],"prefixes":[]}""", bucket)), handleRequest(handler, "GET", "/storage/v1/b/" + bucket + "/o")); + + assertEquals(new TestHttpResponse(RestStatus.OK, Strings.format(""" + {"kind":"storage#objects","items":[{"kind":"storage#object","bucket":"%s","name":"path/blob","id":"path/blob","size":"50"} + ],"prefixes":[]}""", bucket)), handleRequest(handler, "GET", "/storage/v1/b/" + bucket + "/o?prefix=path/")); + + assertEquals( + new TestHttpResponse(RestStatus.OK, """ + {"kind":"storage#objects","items":[],"prefixes":[]}"""), + handleRequest(handler, "GET", "/storage/v1/b/" + bucket + "/o?prefix=path/other") + ); + + assertEquals( + new TestHttpResponse(RestStatus.OK, """ + --__END_OF_PART__d8b50acb-87dc-4630-a3d3-17d187132ebc__ + Content-Length: 162 + Content-Type: application/http + content-id: 1 + content-transfer-encoding: binary + + HTTP/1.1 204 NO_CONTENT + + + + + --__END_OF_PART__d8b50acb-87dc-4630-a3d3-17d187132ebc__ + """.replaceAll("\n", "\r\n")), + handleRequest( + handler, + "POST", + "/batch/storage/v1", + createBatchDeleteRequest(bucket, "path/blob"), + Headers.of("Content-Type", "mixed/multipart") + ) + ); + assertEquals( + RestStatus.OK, + handleRequest( + handler, + "POST", + "/batch/storage/v1", + createBatchDeleteRequest(bucket, "path/blob"), + Headers.of("Content-Type", "mixed/multipart") + ).restStatus() + ); + + assertEquals( + new TestHttpResponse(RestStatus.OK, """ + {"kind":"storage#objects","items":[],"prefixes":[]}"""), + handleRequest(handler, "GET", "/storage/v1/b/" + bucket + "/o?prefix=path/") + ); + } + + public void testGetWithBytesRange() { + final var bucket = randomIdentifier(); + final var handler = new GoogleCloudStorageHttpHandler(bucket); + final var blobName = "blob_name_" + randomIdentifier(); + final var blobPath = "/download/storage/v1/b/" + bucket + "/o/" + blobName; + final var blobBytes = randomBytesReference(256); + + assertEquals( + RestStatus.OK, + handleRequest( + handler, + "POST", + "/upload/storage/v1/b/" + bucket + "/?uploadType=multipart", + createGzipCompressedMultipartUploadBody(bucket, blobName, blobBytes) + ).restStatus() + ); + + assertEquals( + "No Range", + new TestHttpResponse(RestStatus.OK, blobBytes, TestHttpExchange.EMPTY_HEADERS), + handleRequest(handler, "GET", blobPath) + ); + + var end = blobBytes.length() - 1; + assertEquals( + "Exact Range: bytes=0-" + end, + new TestHttpResponse(RestStatus.OK, blobBytes, TestHttpExchange.EMPTY_HEADERS), + handleRequest(handler, "GET", blobPath, BytesArray.EMPTY, rangeHeader(0, end)) + ); + + end = randomIntBetween(blobBytes.length() - 1, Integer.MAX_VALUE); + assertEquals( + "Larger Range: bytes=0-" + end, + new TestHttpResponse(RestStatus.OK, blobBytes, TestHttpExchange.EMPTY_HEADERS), + handleRequest(handler, "GET", blobPath, BytesArray.EMPTY, rangeHeader(0, end)) + ); + + var start = randomIntBetween(blobBytes.length(), Integer.MAX_VALUE - 1); + end = randomIntBetween(start, Integer.MAX_VALUE); + assertEquals( + "Invalid Range: bytes=" + start + '-' + end, + new TestHttpResponse(RestStatus.REQUESTED_RANGE_NOT_SATISFIED, BytesArray.EMPTY, TestHttpExchange.EMPTY_HEADERS), + handleRequest(handler, "GET", blobPath, BytesArray.EMPTY, rangeHeader(start, end)) + ); + + start = randomIntBetween(0, blobBytes.length() - 1); + var length = randomIntBetween(1, blobBytes.length() - start); + end = start + length - 1; + assertEquals( + "Range: bytes=" + start + '-' + end, + new TestHttpResponse(RestStatus.OK, blobBytes.slice(start, length), TestHttpExchange.EMPTY_HEADERS), + handleRequest(handler, "GET", blobPath, BytesArray.EMPTY, rangeHeader(start, end)) + ); + } + + public void testResumableUpload() { + final var bucket = randomIdentifier(); + final var handler = new GoogleCloudStorageHttpHandler(bucket); + final var blobName = "blob_name_" + randomIdentifier(); + + final var createUploadResponse = handleRequest( + handler, + "POST", + "/upload/storage/v1/b/" + bucket + "/?uploadType=resumable&name=" + blobName + ); + final var locationHeader = createUploadResponse.headers.getFirst("Location"); + final var sessionURI = locationHeader.substring(locationHeader.indexOf(HOST) + HOST.length()); + assertEquals(RestStatus.OK, createUploadResponse.restStatus()); + + final var part1 = randomAlphaOfLength(50); + final var uploadPart1Response = handleRequest(handler, "PUT", sessionURI, part1, contentRangeHeader(0, 50, null)); + assertEquals(new TestHttpResponse(RESUME_INCOMPLETE, rangeHeader(0, 50)), uploadPart1Response); + + assertEquals( + new TestHttpResponse(RESUME_INCOMPLETE, TestHttpExchange.EMPTY_HEADERS), + handleRequest(handler, "PUT", sessionURI, BytesArray.EMPTY, contentRangeHeader(null, null, null)) + ); + + final var part2 = randomAlphaOfLength(50); + final var uploadPart2Response = handleRequest(handler, "PUT", sessionURI, part2, contentRangeHeader(51, 100, null)); + assertEquals(new TestHttpResponse(RESUME_INCOMPLETE, rangeHeader(51, 100)), uploadPart2Response); + + final var part3 = randomAlphaOfLength(30); + final var uploadPart3Response = handleRequest(handler, "PUT", sessionURI, part3, contentRangeHeader(101, 130, 130)); + assertEquals(new TestHttpResponse(RestStatus.OK, TestHttpExchange.EMPTY_HEADERS), uploadPart3Response); + + // complete upload should be visible now + + // can download contents + assertEquals( + new TestHttpResponse(RestStatus.OK, part1 + part2 + part3), + handleRequest(handler, "GET", "/download/storage/v1/b/" + bucket + "/o/" + blobName) + ); + + // can see in listing + assertEquals(new TestHttpResponse(RestStatus.OK, Strings.format(""" + {"kind":"storage#objects","items":[{"kind":"storage#object","bucket":"%s","name":"%s","id":"%s","size":"130"} + ],"prefixes":[]}""", bucket, blobName, blobName)), handleRequest(handler, "GET", "/storage/v1/b/" + bucket + "/o")); + + // can get metadata + assertEquals(new TestHttpResponse(RestStatus.OK, Strings.format(""" + {"kind":"storage#object","bucket":"%s","name":"%s","id":"%s","size":"130"} + """, bucket, blobName, blobName)), handleRequest(handler, "GET", "/storage/v1/b/" + bucket + "/o/" + blobName)); + } + + private record TestHttpResponse(int status, BytesReference body, Headers headers) { + TestHttpResponse(RestStatus status, BytesReference body, Headers headers) { + this(status.getStatus(), body, headers); + } + + TestHttpResponse(RestStatus status, String body) { + this(status.getStatus(), new BytesArray(body.getBytes(StandardCharsets.UTF_8)), TestHttpExchange.EMPTY_HEADERS); + } + + TestHttpResponse(RestStatus status, Headers headers) { + this(status.getStatus(), BytesArray.EMPTY, headers); + } + + TestHttpResponse(int statusCode, Headers headers) { + this(statusCode, BytesArray.EMPTY, headers); + } + + RestStatus restStatus() { + return Objects.requireNonNull(RestStatus.fromCode(status)); + } + + @Override + public String toString() { + return "TestHttpResponse{" + "status=" + status + ", body={size=" + body.utf8ToString() + "}, headers=" + headers + '}'; + } + } + + private static TestHttpResponse handleRequest(GoogleCloudStorageHttpHandler handler, String method, String uri) { + return handleRequest(handler, method, uri, ""); + } + + private static TestHttpResponse handleRequest(GoogleCloudStorageHttpHandler handler, String method, String uri, String requestBody) { + return handleRequest(handler, method, uri, new BytesArray(requestBody.getBytes(StandardCharsets.UTF_8))); + } + + private static TestHttpResponse handleRequest( + GoogleCloudStorageHttpHandler handler, + String method, + String uri, + String requestBody, + Headers headers + ) { + return handleRequest(handler, method, uri, new BytesArray(requestBody.getBytes(StandardCharsets.UTF_8)), headers); + } + + private static TestHttpResponse handleRequest( + GoogleCloudStorageHttpHandler handler, + String method, + String uri, + BytesReference requestBody + ) { + return handleRequest(handler, method, uri, requestBody, TestHttpExchange.EMPTY_HEADERS); + } + + private static TestHttpResponse handleRequest( + GoogleCloudStorageHttpHandler handler, + String method, + String uri, + BytesReference requestBody, + Headers requestHeaders + ) { + final var httpExchange = new TestHttpExchange(method, uri, requestBody, requestHeaders); + try { + handler.handle(httpExchange); + } catch (IOException e) { + fail(e); + } + assertNotEquals(0, httpExchange.getResponseCode()); + var responseHeaders = new Headers(); + httpExchange.getResponseHeaders().forEach((header, values) -> { + // com.sun.net.httpserver.Headers.Headers() normalize keys + if ("Range".equals(header) || "Content-range".equals(header) || "Location".equals(header)) { + responseHeaders.put(header, List.copyOf(values)); + } + }); + return new TestHttpResponse(httpExchange.getResponseCode(), httpExchange.getResponseBodyContents(), responseHeaders); + } + + private static Headers contentRangeHeader(@Nullable Integer startInclusive, @Nullable Integer endInclusive, @Nullable Integer limit) { + final String rangeString = startInclusive != null && endInclusive != null ? startInclusive + "-" + endInclusive : "*"; + final String limitString = limit == null ? "*" : limit.toString(); + return Headers.of("Content-Range", "bytes " + rangeString + "/" + limitString); + } + + private static Headers rangeHeader(long start, long end) { + return Headers.of("Range", Strings.format("bytes=%d-%d", start, end)); + } + + private static BytesReference createGzipCompressedMultipartUploadBody(String bucketName, String path, String content) { + return createGzipCompressedMultipartUploadBody(bucketName, path, new BytesArray(content.getBytes(StandardCharsets.UTF_8))); + } + + private static BytesReference createGzipCompressedMultipartUploadBody(String bucketName, String path, BytesReference content) { + final String metadataString = Strings.format("{\"bucket\":\"%s\", \"name\":\"%s\"}", bucketName, path); + final BytesReference header = new BytesArray(Strings.format(""" + --__END_OF_PART__a607a67c-6df7-4b87-b8a1-81f639a75a97__ + Content-Length: %d + Content-Type: application/json; charset=UTF-8 + content-transfer-encoding: binary + + %s + --__END_OF_PART__a607a67c-6df7-4b87-b8a1-81f639a75a97__ + Content-Type: application/octet-stream + content-transfer-encoding: binary + + """.replaceAll("\n", "\r\n"), metadataString.length(), metadataString).getBytes(StandardCharsets.UTF_8)); + + final BytesReference footer = new BytesArray(""" + + --__END_OF_PART__a607a67c-6df7-4b87-b8a1-81f639a75a97__-- + """.replaceAll("\n", "\r\n")); + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(out)) { + gzipOutputStream.write(BytesReference.toBytes(CompositeBytesReference.of(header, content, footer))); + } catch (IOException e) { + fail(e); + } + return new BytesArray(out.toByteArray()); + } + + private static String createBatchDeleteRequest(String bucketName, String... paths) { + final String deleteRequestTemplate = """ + DELETE %s/storage/v1/b/%s/o/%s HTTP/1.1 + Authorization: Bearer foo + x-goog-api-client: gl-java/23.0.0 gdcl/2.1.1 mac-os-x/15.2 + + + """; + final String partTemplate = """ + --__END_OF_PART__d8b50acb-87dc-4630-a3d3-17d187132ebc__ + Content-Length: %d + Content-Type: application/http + content-id: %d + content-transfer-encoding: binary + + %s + """; + StringBuilder builder = new StringBuilder(); + AtomicInteger contentId = new AtomicInteger(); + Arrays.stream(paths).forEach(p -> { + final String deleteRequest = Strings.format(deleteRequestTemplate, HOST, bucketName, p); + final String part = Strings.format(partTemplate, deleteRequest.length(), contentId.incrementAndGet(), deleteRequest); + builder.append(part); + }); + builder.append("--__END_OF_PART__d8b50acb-87dc-4630-a3d3-17d187132ebc__"); + return builder.toString(); + } + + private static class TestHttpExchange extends HttpExchange { + + private static final Headers EMPTY_HEADERS = new Headers(); + + private final String method; + private final URI uri; + private final BytesReference requestBody; + private final Headers requestHeaders; + + private final Headers responseHeaders = new Headers(); + private final BytesStreamOutput responseBody = new BytesStreamOutput(); + private int responseCode; + + TestHttpExchange(String method, String uri, BytesReference requestBody, Headers requestHeaders) { + this.method = method; + this.uri = URI.create(uri); + this.requestBody = requestBody; + this.requestHeaders = new Headers(requestHeaders); + this.requestHeaders.add("Host", HOST); + } + + @Override + public Headers getRequestHeaders() { + return requestHeaders; + } + + @Override + public Headers getResponseHeaders() { + return responseHeaders; + } + + @Override + public URI getRequestURI() { + return uri; + } + + @Override + public String getRequestMethod() { + return method; + } + + @Override + public HttpContext getHttpContext() { + return null; + } + + @Override + public void close() {} + + @Override + public InputStream getRequestBody() { + try { + return requestBody.streamInput(); + } catch (IOException e) { + throw new AssertionError(e); + } + } + + @Override + public OutputStream getResponseBody() { + return responseBody; + } + + @Override + public void sendResponseHeaders(int rCode, long responseLength) { + this.responseCode = rCode; + } + + @Override + public InetSocketAddress getRemoteAddress() { + return null; + } + + @Override + public int getResponseCode() { + return responseCode; + } + + public BytesReference getResponseBodyContents() { + return responseBody.bytes(); + } + + @Override + public InetSocketAddress getLocalAddress() { + return null; + } + + @Override + public String getProtocol() { + return "HTTP/1.1"; + } + + @Override + public Object getAttribute(String name) { + return null; + } + + @Override + public void setAttribute(String name, Object value) { + fail("setAttribute not implemented"); + } + + @Override + public void setStreams(InputStream i, OutputStream o) { + fail("setStreams not implemented"); + } + + @Override + public HttpPrincipal getPrincipal() { + fail("getPrincipal not implemented"); + throw new UnsupportedOperationException("getPrincipal not implemented"); + } + } +} From ffe9002d3252315b2af453b662ad5c10bc626768 Mon Sep 17 00:00:00 2001 From: Quentin Pradet Date: Wed, 18 Dec 2024 08:17:37 +0400 Subject: [PATCH 24/60] Add missing timeouts to rest-api-spec ILM APIs (#118837) --- docs/changelog/118837.yaml | 5 +++++ .../rest-api-spec/api/ilm.delete_lifecycle.json | 11 ++++++++++- .../rest-api-spec/api/ilm.explain_lifecycle.json | 4 ++++ .../rest-api-spec/api/ilm.get_lifecycle.json | 11 ++++++++++- .../rest-api-spec/api/ilm.put_lifecycle.json | 11 ++++++++++- .../main/resources/rest-api-spec/api/ilm.start.json | 11 ++++++++++- .../main/resources/rest-api-spec/api/ilm.stop.json | 11 ++++++++++- 7 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 docs/changelog/118837.yaml diff --git a/docs/changelog/118837.yaml b/docs/changelog/118837.yaml new file mode 100644 index 0000000000000..38cd32f3a3513 --- /dev/null +++ b/docs/changelog/118837.yaml @@ -0,0 +1,5 @@ +pr: 118837 +summary: Add missing timeouts to rest-api-spec ILM APIs +area: "ILM+SLM" +type: bug +issues: [] diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.delete_lifecycle.json b/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.delete_lifecycle.json index 2ff1031ad5c52..cd6397fb61586 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.delete_lifecycle.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.delete_lifecycle.json @@ -25,6 +25,15 @@ } ] }, - "params":{} + "params":{ + "master_timeout":{ + "type":"time", + "description":"Explicit operation timeout for connection to master node" + }, + "timeout":{ + "type":"time", + "description":"Explicit operation timeout" + } + } } } diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.explain_lifecycle.json b/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.explain_lifecycle.json index c793ed09281ae..94c37adb802f6 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.explain_lifecycle.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.explain_lifecycle.json @@ -33,6 +33,10 @@ "only_errors": { "type": "boolean", "description": "filters the indices included in the response to ones in an ILM error state, implies only_managed" + }, + "master_timeout":{ + "type":"time", + "description":"Explicit operation timeout for connection to master node" } } } diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.get_lifecycle.json b/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.get_lifecycle.json index 17bf813093dd6..5abdfac7f5b30 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.get_lifecycle.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.get_lifecycle.json @@ -31,6 +31,15 @@ } ] }, - "params":{} + "params":{ + "master_timeout":{ + "type":"time", + "description":"Explicit operation timeout for connection to master node" + }, + "timeout":{ + "type":"time", + "description":"Explicit operation timeout" + } + } } } diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.put_lifecycle.json b/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.put_lifecycle.json index 5a12a778241b3..b7fdbe04a0ffb 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.put_lifecycle.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.put_lifecycle.json @@ -26,7 +26,16 @@ } ] }, - "params":{}, + "params":{ + "master_timeout":{ + "type":"time", + "description":"Explicit operation timeout for connection to master node" + }, + "timeout":{ + "type":"time", + "description":"Explicit operation timeout" + } + }, "body":{ "description":"The lifecycle policy definition to register" } diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.start.json b/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.start.json index 88b020071ab82..7141673ff9a9d 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.start.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.start.json @@ -19,6 +19,15 @@ } ] }, - "params":{} + "params":{ + "master_timeout":{ + "type":"time", + "description":"Explicit operation timeout for connection to master node" + }, + "timeout":{ + "type":"time", + "description":"Explicit operation timeout" + } + } } } diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.stop.json b/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.stop.json index 8401f93badfc4..962fa77263ee4 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.stop.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/ilm.stop.json @@ -19,6 +19,15 @@ } ] }, - "params":{} + "params":{ + "master_timeout":{ + "type":"time", + "description":"Explicit operation timeout for connection to master node" + }, + "timeout":{ + "type":"time", + "description":"Explicit operation timeout" + } + } } } From 2ceade4234ab2323184cfb9ff11259542508453f Mon Sep 17 00:00:00 2001 From: Quentin Pradet Date: Wed, 18 Dec 2024 08:18:43 +0400 Subject: [PATCH 25/60] Add missing timeouts to rest-api-spec ingest APIs (#118844) --- docs/changelog/118844.yaml | 5 +++++ .../rest-api-spec/api/ingest.delete_geoip_database.json | 8 ++++++++ .../api/ingest.delete_ip_location_database.json | 8 ++++++++ .../rest-api-spec/api/ingest.put_geoip_database.json | 8 ++++++++ .../api/ingest.put_ip_location_database.json | 8 ++++++++ 5 files changed, 37 insertions(+) create mode 100644 docs/changelog/118844.yaml diff --git a/docs/changelog/118844.yaml b/docs/changelog/118844.yaml new file mode 100644 index 0000000000000..f9f92bcaeb8cb --- /dev/null +++ b/docs/changelog/118844.yaml @@ -0,0 +1,5 @@ +pr: 118844 +summary: Add missing timeouts to rest-api-spec ingest APIs +area: Ingest Node +type: bug +issues: [] diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/ingest.delete_geoip_database.json b/rest-api-spec/src/main/resources/rest-api-spec/api/ingest.delete_geoip_database.json index fe50da720a4da..f76d328836d90 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/ingest.delete_geoip_database.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/ingest.delete_geoip_database.json @@ -26,6 +26,14 @@ ] }, "params":{ + "master_timeout":{ + "type":"time", + "description":"Explicit operation timeout for connection to master node" + }, + "timeout":{ + "type":"time", + "description":"Explicit operation timeout" + } } } } diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/ingest.delete_ip_location_database.json b/rest-api-spec/src/main/resources/rest-api-spec/api/ingest.delete_ip_location_database.json index e97d1da276906..341ff5081e270 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/ingest.delete_ip_location_database.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/ingest.delete_ip_location_database.json @@ -26,6 +26,14 @@ ] }, "params":{ + "master_timeout":{ + "type":"time", + "description":"Explicit operation timeout for connection to master node" + }, + "timeout":{ + "type":"time", + "description":"Explicit operation timeout" + } } } } diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/ingest.put_geoip_database.json b/rest-api-spec/src/main/resources/rest-api-spec/api/ingest.put_geoip_database.json index 6d088e3f164f4..9c2677d1f7b2f 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/ingest.put_geoip_database.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/ingest.put_geoip_database.json @@ -27,6 +27,14 @@ ] }, "params":{ + "master_timeout":{ + "type":"time", + "description":"Explicit operation timeout for connection to master node" + }, + "timeout":{ + "type":"time", + "description":"Explicit operation timeout" + } }, "body":{ "description":"The database configuration definition", diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/ingest.put_ip_location_database.json b/rest-api-spec/src/main/resources/rest-api-spec/api/ingest.put_ip_location_database.json index 18487969b1a90..782048b98160a 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/ingest.put_ip_location_database.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/ingest.put_ip_location_database.json @@ -27,6 +27,14 @@ ] }, "params":{ + "master_timeout":{ + "type":"time", + "description":"Explicit operation timeout for connection to master node" + }, + "timeout":{ + "type":"time", + "description":"Explicit operation timeout" + } }, "body":{ "description":"The database configuration definition", From a0ce7420af1bad48ffd0c5f19978b5943b4b32aa Mon Sep 17 00:00:00 2001 From: elasticsearchmachine <58790826+elasticsearchmachine@users.noreply.github.com> Date: Wed, 18 Dec 2024 16:30:02 +1100 Subject: [PATCH 26/60] Mute org.elasticsearch.cluster.service.MasterServiceTests testThreadContext #118914 --- muted-tests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/muted-tests.yml b/muted-tests.yml index b5712b22fe583..ef302671de998 100644 --- a/muted-tests.yml +++ b/muted-tests.yml @@ -305,6 +305,9 @@ tests: - class: org.elasticsearch.smoketest.DocsClientYamlTestSuiteIT method: test {yaml=reference/indices/shard-stores/line_150} issue: https://github.com/elastic/elasticsearch/issues/118896 +- class: org.elasticsearch.cluster.service.MasterServiceTests + method: testThreadContext + issue: https://github.com/elastic/elasticsearch/issues/118914 # Examples: # From 3f1fed0f0900e486d328c6aaede5578a3a1f9919 Mon Sep 17 00:00:00 2001 From: Carlos Delgado <6339205+carlosdelest@users.noreply.github.com> Date: Wed, 18 Dec 2024 07:50:54 +0100 Subject: [PATCH 27/60] ESQL - Remove restrictions for disjunctions in full text functions (#118544) --- docs/changelog/118544.yaml | 5 + x-pack/plugin/build.gradle | 1 + .../main/resources/match-function.csv-spec | 74 +++++++++++ .../main/resources/match-operator.csv-spec | 121 ++++++++++++++---- .../xpack/esql/plugin/MatchFunctionIT.java | 29 +++-- .../xpack/esql/plugin/MatchOperatorIT.java | 3 +- .../xpack/esql/action/EsqlCapabilities.java | 7 +- .../xpack/esql/analysis/Verifier.java | 81 ++++++++---- .../xpack/esql/analysis/VerifierTests.java | 84 ++++++------ .../LocalPhysicalPlanOptimizerTests.java | 42 ++++++ .../test/esql/180_match_operator.yml | 17 ++- 11 files changed, 364 insertions(+), 100 deletions(-) create mode 100644 docs/changelog/118544.yaml diff --git a/docs/changelog/118544.yaml b/docs/changelog/118544.yaml new file mode 100644 index 0000000000000..d59783c4e6194 --- /dev/null +++ b/docs/changelog/118544.yaml @@ -0,0 +1,5 @@ +pr: 118544 +summary: ESQL - Remove restrictions for disjunctions in full text functions +area: ES|QL +type: enhancement +issues: [] diff --git a/x-pack/plugin/build.gradle b/x-pack/plugin/build.gradle index fb37fb3575551..aa6e8de4ec27c 100644 --- a/x-pack/plugin/build.gradle +++ b/x-pack/plugin/build.gradle @@ -94,5 +94,6 @@ tasks.named("yamlRestCompatTestTransform").configure({ task -> task.skipTest("privileges/11_builtin/Test get builtin privileges" ,"unnecessary to test compatibility") task.skipTest("esql/61_enrich_ip/Invalid IP strings", "We switched from exceptions to null+warnings for ENRICH runtime errors") task.skipTest("esql/180_match_operator/match with non text field", "Match operator can now be used on non-text fields") + task.skipTest("esql/180_match_operator/match with functions", "Error message changed") }) diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-function.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-function.csv-spec index 03b24555dbeff..5ea169e1b110d 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-function.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-function.csv-spec @@ -115,6 +115,80 @@ book_no:keyword | title:text 7140 |The Lord of the Rings Poster Collection: Six Paintings by Alan Lee (No. 1) ; +matchWithDisjunction +required_capability: match_function +required_capability: full_text_functions_disjunctions + +from books +| where match(author, "Vonnegut") or match(author, "Guinane") +| keep book_no, author; +ignoreOrder:true + +book_no:keyword | author:text +2464 | Kurt Vonnegut +6970 | Edith Vonnegut +8956 | Kurt Vonnegut +3950 | Kurt Vonnegut +4382 | Carole Guinane +; + +matchWithDisjunctionAndFiltersConjunction +required_capability: match_function +required_capability: full_text_functions_disjunctions + +from books +| where (match(author, "Vonnegut") or match(author, "Guinane")) and year > 1997 +| keep book_no, author, year; +ignoreOrder:true + +book_no:keyword | author:text | year:integer +6970 | Edith Vonnegut | 1998 +4382 | Carole Guinane | 2001 +; + +matchWithDisjunctionAndConjunction +required_capability: match_function +required_capability: full_text_functions_disjunctions + +from books +| where (match(author, "Vonnegut") or match(author, "Marquez")) and match(description, "realism") +| keep book_no; + +book_no:keyword +4814 +; + +matchWithMoreComplexDisjunctionAndConjunction +required_capability: match_function +required_capability: full_text_functions_disjunctions + +from books +| where (match(author, "Vonnegut") and match(description, "charming")) or (match(author, "Marquez") and match(description, "realism")) +| keep book_no; +ignoreOrder:true + +book_no:keyword +6970 +4814 +; + +matchWithDisjunctionIncludingConjunction +required_capability: match_function +required_capability: full_text_functions_disjunctions + +from books +| where match(author, "Vonnegut") or (match(author, "Marquez") and match(description, "realism")) +| keep book_no; +ignoreOrder:true + +book_no:keyword +2464 +6970 +4814 +8956 +3950 +; + matchWithFunctionPushedToLucene required_capability: match_function diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-operator.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-operator.csv-spec index 56f7f5ccd8823..7906f8b69162b 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-operator.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-operator.csv-spec @@ -102,6 +102,81 @@ book_no:keyword | title:text 7140 |The Lord of the Rings Poster Collection: Six Paintings by Alan Lee (No. 1) ; + +matchWithDisjunction +required_capability: match_operator_colon +required_capability: full_text_functions_disjunctions + +from books +| where author : "Vonnegut" or author : "Guinane" +| keep book_no, author; +ignoreOrder:true + +book_no:keyword | author:text +2464 | Kurt Vonnegut +6970 | Edith Vonnegut +8956 | Kurt Vonnegut +3950 | Kurt Vonnegut +4382 | Carole Guinane +; + +matchWithDisjunctionAndFiltersConjunction +required_capability: match_operator_colon +required_capability: full_text_functions_disjunctions + +from books +| where (author : "Vonnegut" or author : "Guinane") and year > 1997 +| keep book_no, author, year; +ignoreOrder:true + +book_no:keyword | author:text | year:integer +6970 | Edith Vonnegut | 1998 +4382 | Carole Guinane | 2001 +; + +matchWithDisjunctionAndConjunction +required_capability: match_operator_colon +required_capability: full_text_functions_disjunctions + +from books +| where (author : "Vonnegut" or author : "Marquez") and description : "realism" +| keep book_no; + +book_no:keyword +4814 +; + +matchWithMoreComplexDisjunctionAndConjunction +required_capability: match_function +required_capability: full_text_functions_disjunctions + +from books +| where (author : "Vonnegut" and description : "charming") or (author : "Marquez" and description : "realism") +| keep book_no; +ignoreOrder:true + +book_no:keyword +6970 +4814 +; + +matchWithDisjunctionIncludingConjunction +required_capability: match_operator_colon +required_capability: full_text_functions_disjunctions + +from books +| where author : "Vonnegut" or (author : "Marquez" and description : "realism") +| keep book_no; +ignoreOrder:true + +book_no:keyword +2464 +6970 +4814 +8956 +3950 +; + matchWithFunctionPushedToLucene required_capability: match_operator_colon @@ -219,7 +294,7 @@ count(*): long | author.keyword:keyword ; testMatchBooleanField -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from employees @@ -235,7 +310,7 @@ Amabile | true | 2.09 ; testMatchIntegerField -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from employees @@ -247,7 +322,7 @@ emp_no:integer | first_name:keyword ; testMatchDoubleField -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from employees @@ -259,7 +334,7 @@ emp_no:integer | salary_change:double ; testMatchLongField -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from date_nanos @@ -271,7 +346,7 @@ num:long ; testMatchUnsignedLongField -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from ul_logs @@ -283,7 +358,7 @@ bytes_out:unsigned_long ; testMatchIpFieldAsString -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from sample_data @@ -295,7 +370,7 @@ client_ip:ip | message:keyword ; testMatchDateFieldAsString -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from date_nanos @@ -307,7 +382,7 @@ millis:date ; testMatchDateNanosFieldAsString -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from date_nanos @@ -319,7 +394,7 @@ nanos:date_nanos ; testMatchBooleanFieldAsString -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from employees @@ -335,7 +410,7 @@ Amabile | true | 2.09 ; testMatchIntegerFieldAsString -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from employees @@ -347,7 +422,7 @@ emp_no:integer | first_name:keyword ; testMatchDoubleFieldAsString -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from employees @@ -359,7 +434,7 @@ emp_no:integer | salary_change:double ; testMatchLongFieldAsString -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from date_nanos @@ -371,7 +446,7 @@ num:long ; testMatchUnsignedLongFieldAsString -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from ul_logs @@ -383,7 +458,7 @@ bytes_out:unsigned_long ; testMatchVersionFieldAsString -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from apps @@ -395,7 +470,7 @@ bbbbb | 2.1 ; testMatchIntegerAsDouble -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from employees @@ -408,7 +483,7 @@ emp_no:integer | first_name:keyword ; testMatchDoubleAsIntegerField -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from employees @@ -423,7 +498,7 @@ emp_no:integer | height:double ; testMatchMultipleFieldTypes -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from employees,employees_incompatible @@ -440,7 +515,7 @@ emp_as_int:integer | name_as_kw:keyword testMatchMultipleFieldTypesKeywordText -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from employees,employees_incompatible @@ -455,7 +530,7 @@ Kazuhito ; testMatchMultipleFieldTypesDoubleFloat -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from employees,employees_incompatible @@ -474,7 +549,7 @@ emp_no:integer | height_dbl:double ; testMatchMultipleFieldTypesBooleanKeyword -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from employees,employees_incompatible @@ -491,7 +566,7 @@ true ; testMatchMultipleFieldTypesLongUnsignedLong -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from employees,employees_incompatible @@ -506,7 +581,7 @@ avg_worked_seconds_ul:unsigned_long ; testMatchMultipleFieldTypesDateNanosDate -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from employees,employees_incompatible @@ -521,7 +596,7 @@ hire_date_nanos:date_nanos ; testMatchWithWrongFieldValue -required_capability: match_function +required_capability: match_operator_colon required_capability: match_additional_types from employees,employees_incompatible diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/MatchFunctionIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/MatchFunctionIT.java index 58b1652653ca3..ad90bbf6ae9db 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/MatchFunctionIT.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/MatchFunctionIT.java @@ -168,7 +168,7 @@ public void testWhereMatchWithScoringNoSort() { var query = """ FROM test METADATA _score - | WHERE content:"fox" + | WHERE match(content, "fox") | KEEP id, _score """; @@ -182,7 +182,7 @@ public void testWhereMatchWithScoringNoSort() { public void testNonExistingColumn() { var query = """ FROM test - | WHERE something:"fox" + | WHERE match(something, "fox") """; var error = expectThrows(VerificationException.class, () -> run(query)); @@ -193,14 +193,14 @@ public void testWhereMatchEvalColumn() { var query = """ FROM test | EVAL upper_content = to_upper(content) - | WHERE upper_content:"FOX" + | WHERE match(upper_content, "FOX") | KEEP id """; var error = expectThrows(VerificationException.class, () -> run(query)); assertThat( error.getMessage(), - containsString("[:] operator cannot operate on [upper_content], which is not a field from an index mapping") + containsString("[MATCH] function cannot operate on [upper_content], which is not a field from an index mapping") ); } @@ -209,13 +209,13 @@ public void testWhereMatchOverWrittenColumn() { FROM test | DROP content | EVAL content = CONCAT("document with ID ", to_str(id)) - | WHERE content:"document" + | WHERE match(content, "document") """; var error = expectThrows(VerificationException.class, () -> run(query)); assertThat( error.getMessage(), - containsString("[:] operator cannot operate on [content], which is not a field from an index mapping") + containsString("[MATCH] function cannot operate on [content], which is not a field from an index mapping") ); } @@ -223,7 +223,7 @@ public void testWhereMatchAfterStats() { var query = """ FROM test | STATS count(*) - | WHERE content:"fox" + | WHERE match(content, "fox") """; var error = expectThrows(VerificationException.class, () -> run(query)); @@ -233,14 +233,15 @@ public void testWhereMatchAfterStats() { public void testWhereMatchWithFunctions() { var query = """ FROM test - | WHERE content:"fox" OR to_upper(content) == "FOX" + | WHERE match(content, "fox") OR to_upper(content) == "FOX" """; var error = expectThrows(ElasticsearchException.class, () -> run(query)); assertThat( error.getMessage(), containsString( - "Invalid condition [content:\"fox\" OR to_upper(content) == \"FOX\"]. " - + "[:] operator can't be used as part of an or condition" + "Invalid condition [match(content, \"fox\") OR to_upper(content) == \"FOX\"]. " + + "Full text functions can be used in an OR condition," + + " but only if just full text functions are used in the OR condition" ) ); } @@ -248,24 +249,24 @@ public void testWhereMatchWithFunctions() { public void testWhereMatchWithRow() { var query = """ ROW content = "a brown fox" - | WHERE content:"fox" + | WHERE match(content, "fox") """; var error = expectThrows(ElasticsearchException.class, () -> run(query)); assertThat( error.getMessage(), - containsString("[:] operator cannot operate on [\"a brown fox\"], which is not a field from an index mapping") + containsString("[MATCH] function cannot operate on [\"a brown fox\"], which is not a field from an index mapping") ); } public void testMatchWithinEval() { var query = """ FROM test - | EVAL matches_query = content:"fox" + | EVAL matches_query = match(content, "fox") """; var error = expectThrows(VerificationException.class, () -> run(query)); - assertThat(error.getMessage(), containsString("[:] operator is only supported in WHERE commands")); + assertThat(error.getMessage(), containsString("[MATCH] function is only supported in WHERE commands")); } private void createAndPopulateIndex() { diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/MatchOperatorIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/MatchOperatorIT.java index d0a641f086fe4..758878b46d51f 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/MatchOperatorIT.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/MatchOperatorIT.java @@ -216,7 +216,8 @@ public void testWhereMatchWithFunctions() { error.getMessage(), containsString( "Invalid condition [content:\"fox\" OR to_upper(content) == \"FOX\"]. " - + "[:] operator can't be used as part of an or condition" + + "Full text functions can be used in an OR condition, " + + "but only if just full text functions are used in the OR condition" ) ); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java index f766beb76dd3d..8c7e381d33322 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java @@ -585,7 +585,12 @@ public enum Cap { /** * Fix for regex folding with case-insensitive pattern https://github.com/elastic/elasticsearch/issues/118371 */ - FIXED_REGEX_FOLD; + FIXED_REGEX_FOLD, + + /** + * Full text functions can be used in disjunctions + */ + FULL_TEXT_FUNCTIONS_DISJUNCTIONS; private final boolean enabled; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java index f01cc265e330b..6b98b7d69834f 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java @@ -766,41 +766,78 @@ private static void checkRemoteEnrich(LogicalPlan plan, Set failures) { } /** - * Checks whether a condition contains a disjunction with the specified typeToken. Adds to failure if it does. + * Checks whether a condition contains a disjunction with a full text search. + * If it does, check that every element of the disjunction is a full text search or combinations (AND, OR, NOT) of them. + * If not, add a failure to the failures collection. * - * @param condition condition to check for disjunctions + * @param condition condition to check for disjunctions of full text searches * @param typeNameProvider provider for the type name to add in the failure message * @param failures failures collection to add to */ - private static void checkNotPresentInDisjunctions( + private static void checkFullTextSearchDisjunctions( Expression condition, java.util.function.Function typeNameProvider, Set failures ) { - condition.forEachUp(Or.class, or -> { - checkNotPresentInDisjunctions(or.left(), or, typeNameProvider, failures); - checkNotPresentInDisjunctions(or.right(), or, typeNameProvider, failures); + int failuresCount = failures.size(); + condition.forEachDown(Or.class, or -> { + if (failures.size() > failuresCount) { + // Exit early if we already have a failures + return; + } + boolean hasFullText = or.anyMatch(FullTextFunction.class::isInstance); + if (hasFullText) { + boolean hasOnlyFullText = onlyFullTextFunctionsInExpression(or); + if (hasOnlyFullText == false) { + failures.add( + fail( + or, + "Invalid condition [{}]. Full text functions can be used in an OR condition, " + + "but only if just full text functions are used in the OR condition", + or.sourceText() + ) + ); + } + } }); } /** - * Checks whether a condition contains a disjunction with the specified typeToken. Adds to failure if it does. + * Checks whether an expression contains just full text functions or negations (NOT) and combinations (AND, OR) of full text functions * - * @param parentExpression parent expression to add to the failure message - * @param or disjunction that is being checked - * @param failures failures collection to add to + * @param expression expression to check + * @return true if all children are full text functions or negations of full text functions, false otherwise */ - private static void checkNotPresentInDisjunctions( - Expression parentExpression, - Or or, - java.util.function.Function elementName, - Set failures - ) { - parentExpression.forEachDown(FullTextFunction.class, ftp -> { - failures.add( - fail(or, "Invalid condition [{}]. {} can't be used as part of an or condition", or.sourceText(), elementName.apply(ftp)) - ); - }); + private static boolean onlyFullTextFunctionsInExpression(Expression expression) { + if (expression instanceof FullTextFunction) { + return true; + } else if (expression instanceof Not) { + return onlyFullTextFunctionsInExpression(expression.children().get(0)); + } else if (expression instanceof BinaryLogic binaryLogic) { + return onlyFullTextFunctionsInExpression(binaryLogic.left()) && onlyFullTextFunctionsInExpression(binaryLogic.right()); + } + + return false; + } + + /** + * Checks whether an expression contains a full text function as part of it + * + * @param expression expression to check + * @return true if the expression or any of its children is a full text function, false otherwise + */ + private static boolean anyFullTextFunctionsInExpression(Expression expression) { + if (expression instanceof FullTextFunction) { + return true; + } + + for (Expression child : expression.children()) { + if (anyFullTextFunctionsInExpression(child)) { + return true; + } + } + + return false; } /** @@ -870,7 +907,7 @@ private static void checkFullTextQueryFunctions(LogicalPlan plan, Set f m -> "[" + m.functionName() + "] " + m.functionType(), failures ); - checkNotPresentInDisjunctions(condition, ftf -> "[" + ftf.functionName() + "] " + ftf.functionType(), failures); + checkFullTextSearchDisjunctions(condition, ftf -> "[" + ftf.functionName() + "] " + ftf.functionType(), failures); checkFullTextFunctionsParents(condition, failures); } else { plan.forEachExpression(FullTextFunction.class, ftf -> { diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java index 182e87d1ab9dd..a1e29117a25d3 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java @@ -1166,12 +1166,14 @@ public void testMatchInsideEval() throws Exception { public void testMatchFilter() throws Exception { assertEquals( "1:19: Invalid condition [first_name:\"Anna\" or starts_with(first_name, \"Anne\")]. " - + "[:] operator can't be used as part of an or condition", + + "Full text functions can be used in an OR condition, " + + "but only if just full text functions are used in the OR condition", error("from test | where first_name:\"Anna\" or starts_with(first_name, \"Anne\")") ); assertEquals( - "1:51: Invalid condition [first_name:\"Anna\" OR new_salary > 100]. " + "[:] operator can't be used as part of an or condition", + "1:51: Invalid condition [first_name:\"Anna\" OR new_salary > 100]. Full text functions can be" + + " used in an OR condition, but only if just full text functions are used in the OR condition", error("from test | eval new_salary = salary + 10 | where first_name:\"Anna\" OR new_salary > 100") ); } @@ -1409,48 +1411,56 @@ public void testMatchOperatorWithDisjunctions() { } private void checkWithDisjunctions(String functionName, String functionInvocation, String functionType) { + String expression = functionInvocation + " or length(first_name) > 12"; + checkdisjunctionError("1:19", expression, functionName, functionType); + expression = "(" + functionInvocation + " or first_name is not null) or (length(first_name) > 12 and match(last_name, \"Smith\"))"; + checkdisjunctionError("1:19", expression, functionName, functionType); + expression = functionInvocation + " or (last_name is not null and first_name is null)"; + checkdisjunctionError("1:19", expression, functionName, functionType); + } + + private void checkdisjunctionError(String position, String expression, String functionName, String functionType) { assertEquals( LoggerMessageFormat.format( null, - "1:19: Invalid condition [{} or length(first_name) > 12]. " - + "[{}] " - + functionType - + " can't be used as part of an or condition", - functionInvocation, - functionName - ), - error("from test | where " + functionInvocation + " or length(first_name) > 12") - ); - assertEquals( - LoggerMessageFormat.format( - null, - "1:19: Invalid condition [({} and first_name is not null) or (length(first_name) > 12 and first_name is null)]. " - + "[{}] " - + functionType - + " can't be used as part of an or condition", - functionInvocation, - functionName - ), - error( - "from test | where (" - + functionInvocation - + " and first_name is not null) or (length(first_name) > 12 and first_name is null)" - ) - ); - assertEquals( - LoggerMessageFormat.format( - null, - "1:19: Invalid condition [({} and first_name is not null) or first_name is null]. " - + "[{}] " - + functionType - + " can't be used as part of an or condition", - functionInvocation, - functionName + "{}: Invalid condition [{}]. Full text functions can be used in an OR condition, " + + "but only if just full text functions are used in the OR condition", + position, + expression ), - error("from test | where (" + functionInvocation + " and first_name is not null) or first_name is null") + error("from test | where " + expression) ); } + public void testFullTextFunctionsDisjunctions() { + checkWithFullTextFunctionsDisjunctions("MATCH", "match(last_name, \"Smith\")", "function"); + checkWithFullTextFunctionsDisjunctions(":", "last_name : \"Smith\"", "operator"); + checkWithFullTextFunctionsDisjunctions("QSTR", "qstr(\"last_name: Smith\")", "function"); + + assumeTrue("KQL function capability not available", EsqlCapabilities.Cap.KQL_FUNCTION.isEnabled()); + checkWithFullTextFunctionsDisjunctions("KQL", "kql(\"last_name: Smith\")", "function"); + } + + private void checkWithFullTextFunctionsDisjunctions(String functionName, String functionInvocation, String functionType) { + + String expression = functionInvocation + " or length(first_name) > 10"; + checkdisjunctionError("1:19", expression, functionName, functionType); + + expression = "match(last_name, \"Anneke\") or (" + functionInvocation + " and length(first_name) > 10)"; + checkdisjunctionError("1:19", expression, functionName, functionType); + + expression = "(" + + functionInvocation + + " and length(first_name) > 0) or (match(last_name, \"Anneke\") and length(first_name) > 10)"; + checkdisjunctionError("1:19", expression, functionName, functionType); + + query("from test | where " + functionInvocation + " or match(first_name, \"Anna\")"); + query("from test | where " + functionInvocation + " or not match(first_name, \"Anna\")"); + query("from test | where (" + functionInvocation + " or match(first_name, \"Anna\")) and length(first_name) > 10"); + query("from test | where (" + functionInvocation + " or match(first_name, \"Anna\")) and match(last_name, \"Smith\")"); + query("from test | where " + functionInvocation + " or (match(first_name, \"Anna\") and match(last_name, \"Smith\"))"); + } + public void testQueryStringFunctionWithNonBooleanFunctions() { checkFullTextFunctionsWithNonBooleanFunctions("QSTR", "qstr(\"first_name: Anna\")", "function"); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalPhysicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalPhysicalPlanOptimizerTests.java index 879a413615202..406e27c1517e5 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalPhysicalPlanOptimizerTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalPhysicalPlanOptimizerTests.java @@ -21,6 +21,7 @@ import org.elasticsearch.index.query.MatchQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.index.query.QueryStringQueryBuilder; import org.elasticsearch.index.query.RangeQueryBuilder; import org.elasticsearch.index.query.SearchExecutionContext; import org.elasticsearch.license.XPackLicenseState; @@ -57,6 +58,7 @@ import org.elasticsearch.xpack.esql.plan.physical.EvalExec; import org.elasticsearch.xpack.esql.plan.physical.ExchangeExec; import org.elasticsearch.xpack.esql.plan.physical.FieldExtractExec; +import org.elasticsearch.xpack.esql.plan.physical.FilterExec; import org.elasticsearch.xpack.esql.plan.physical.LimitExec; import org.elasticsearch.xpack.esql.plan.physical.LocalSourceExec; import org.elasticsearch.xpack.esql.plan.physical.PhysicalPlan; @@ -1543,6 +1545,46 @@ public void testMultipleMatchFilterPushdown() { assertThat(actualLuceneQuery.toString(), is(expectedLuceneQuery.toString())); } + public void testFullTextFunctionsDisjunctionPushdown() { + String query = """ + from test + | where (match(first_name, "Anna") or qstr("first_name: Anneke")) and last_name: "Smith" + | sort emp_no + """; + var plan = plannerOptimizer.plan(query); + var topNExec = as(plan, TopNExec.class); + var exchange = as(topNExec.child(), ExchangeExec.class); + var project = as(exchange.child(), ProjectExec.class); + var fieldExtract = as(project.child(), FieldExtractExec.class); + var actualLuceneQuery = as(fieldExtract.child(), EsQueryExec.class).query(); + var expectedLuceneQuery = new BoolQueryBuilder().must( + new BoolQueryBuilder().should(new MatchQueryBuilder("first_name", "Anna").lenient(true)) + .should(new QueryStringQueryBuilder("first_name: Anneke")) + ).must(new MatchQueryBuilder("last_name", "Smith").lenient(true)); + assertThat(actualLuceneQuery.toString(), is(expectedLuceneQuery.toString())); + } + + public void testFullTextFunctionsDisjunctionWithFiltersPushdown() { + String query = """ + from test + | where (first_name:"Anna" or first_name:"Anneke") and length(last_name) > 5 + | sort emp_no + """; + var plan = plannerOptimizer.plan(query); + var topNExec = as(plan, TopNExec.class); + var exchange = as(topNExec.child(), ExchangeExec.class); + var project = as(exchange.child(), ProjectExec.class); + var fieldExtract = as(project.child(), FieldExtractExec.class); + var secondTopNExec = as(fieldExtract.child(), TopNExec.class); + var secondFieldExtract = as(secondTopNExec.child(), FieldExtractExec.class); + var filterExec = as(secondFieldExtract.child(), FilterExec.class); + var thirdFilterExtract = as(filterExec.child(), FieldExtractExec.class); + var actualLuceneQuery = as(thirdFilterExtract.child(), EsQueryExec.class).query(); + var expectedLuceneQuery = new BoolQueryBuilder().should(new MatchQueryBuilder("first_name", "Anna").lenient(true)) + .should(new MatchQueryBuilder("first_name", "Anneke").lenient(true)); + assertThat(actualLuceneQuery.toString(), is(expectedLuceneQuery.toString())); + } + /** * Expecting * LimitExec[1000[INTEGER]] diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/180_match_operator.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/180_match_operator.yml index 663c0dc78acb3..118783b412d48 100644 --- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/180_match_operator.yml +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/180_match_operator.yml @@ -170,7 +170,7 @@ setup: - match: { error.reason: "Found 1 problem\nline 1:36: Unknown column [content], did you mean [count(*)]?" } --- -"match with functions": +"match with disjunctions": - do: catch: bad_request allowed_warnings_regex: @@ -181,7 +181,20 @@ setup: - match: { status: 400 } - match: { error.type: verification_exception } - - match: { error.reason: "Found 1 problem\nline 1:19: Invalid condition [content:\"fox\" OR to_upper(content) == \"FOX\"]. [:] operator can't be used as part of an or condition" } + - match: { error.reason: "/.+Invalid\\ condition\\ \\[content\\:\"fox\"\\ OR\\ to_upper\\(content\\)\\ ==\\ \"FOX\"\\]\\./" } + + - do: + catch: bad_request + allowed_warnings_regex: + - "No limit defined, adding default limit of \\[.*\\]" + esql.query: + body: + query: 'FROM test | WHERE content:"fox" OR to_upper(content) == "FOX"' + + - match: { status: 400 } + - match: { error.type: verification_exception } + - match: { error.reason: "/.+Invalid\\ condition\\ \\[content\\:\"fox\"\\ OR\\ to_upper\\(content\\)\\ ==\\ \"FOX\"\\]\\./" } + --- "match within eval": From d118cbf529ec4da9f9d7378cb48e4355ee61c9ab Mon Sep 17 00:00:00 2001 From: Rene Groeschke Date: Wed, 18 Dec 2024 09:22:08 +0100 Subject: [PATCH 28/60] [Build] Make ThirdPartyAudit task uptodate more effective (#118723) We should basically be able to skip the third party dependency audit tasks if no third party dependency has changed. Filtering out the project dependencies allows way better uptodate and caching behaviour. We are only interested in thirdparty libs anyhow in this context. A positive side effect of the reduced class path is a quicker execution of the task --- .../ThirdPartyAuditPrecommitPlugin.java | 9 +++-- .../precommit/ThirdPartyAuditTask.java | 15 ++------ .../internal/util/DependenciesUtils.java | 36 ++++++++++++++++--- 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/ThirdPartyAuditPrecommitPlugin.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/ThirdPartyAuditPrecommitPlugin.java index e45a1d3dd25b1..7046a22204efa 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/ThirdPartyAuditPrecommitPlugin.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/ThirdPartyAuditPrecommitPlugin.java @@ -16,12 +16,14 @@ import org.gradle.api.Task; import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.component.ModuleComponentIdentifier; +import org.gradle.api.file.FileCollection; import org.gradle.api.tasks.TaskProvider; import java.io.File; import java.nio.file.Path; import static org.elasticsearch.gradle.internal.util.DependenciesUtils.createFileCollectionFromNonTransitiveArtifactsView; +import static org.elasticsearch.gradle.internal.util.DependenciesUtils.thirdPartyDependenciesView; import static org.elasticsearch.gradle.internal.util.ParamsUtils.loadBuildParams; public class ThirdPartyAuditPrecommitPlugin extends PrecommitPlugin { @@ -47,7 +49,6 @@ public TaskProvider createTask(Project project) { project.getDependencies().add(JDK_JAR_HELL_CONFIG_NAME, elasticsearchCoreProject); } } - TaskProvider resourcesTask = project.getTasks() .register("thirdPartyAuditResources", ExportElasticsearchBuildResourcesTask.class); Path resourcesDir = project.getBuildDir().toPath().resolve("third-party-audit-config"); @@ -59,9 +60,11 @@ public TaskProvider createTask(Project project) { // usually only one task is created. but this construct makes our integTests easier to setup project.getTasks().withType(ThirdPartyAuditTask.class).configureEach(t -> { Configuration runtimeConfiguration = project.getConfigurations().getByName("runtimeClasspath"); + FileCollection runtimeThirdParty = thirdPartyDependenciesView(runtimeConfiguration); Configuration compileOnly = project.getConfigurations() .getByName(CompileOnlyResolvePlugin.RESOLVEABLE_COMPILE_ONLY_CONFIGURATION_NAME); - t.setClasspath(runtimeConfiguration.plus(compileOnly)); + FileCollection compileOnlyThirdParty = thirdPartyDependenciesView(compileOnly); + t.getThirdPartyClasspath().from(runtimeThirdParty, compileOnlyThirdParty); t.getJarsToScan() .from( createFileCollectionFromNonTransitiveArtifactsView( @@ -78,7 +81,7 @@ public TaskProvider createTask(Project project) { t.getJavaHome().set(buildParams.flatMap(params -> params.getRuntimeJavaHome()).map(File::getPath)); t.setSignatureFile(resourcesDir.resolve("forbidden/third-party-audit.txt").toFile()); t.getJdkJarHellClasspath().from(jdkJarHellConfig); - t.getForbiddenAPIsClasspath().from(project.getConfigurations().getByName("forbiddenApisCliJar").plus(compileOnly)); + t.getForbiddenAPIsClasspath().from(project.getConfigurations().getByName("forbiddenApisCliJar").plus(compileOnlyThirdParty)); }); return audit; } diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/ThirdPartyAuditTask.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/ThirdPartyAuditTask.java index 442797775de2f..59ba9bae0a57d 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/ThirdPartyAuditTask.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/precommit/ThirdPartyAuditTask.java @@ -17,7 +17,6 @@ import org.gradle.api.JavaVersion; import org.gradle.api.file.ArchiveOperations; import org.gradle.api.file.ConfigurableFileCollection; -import org.gradle.api.file.FileCollection; import org.gradle.api.file.FileSystemOperations; import org.gradle.api.file.FileTree; import org.gradle.api.file.ProjectLayout; @@ -96,8 +95,6 @@ public abstract class ThirdPartyAuditTask extends DefaultTask { private final ProjectLayout projectLayout; - private FileCollection classpath; - @Inject public ThirdPartyAuditTask( ArchiveOperations archiveOperations, @@ -198,9 +195,7 @@ public Set getMissingClassExcludes() { public abstract Property getRuntimeJavaVersion(); @Classpath - public FileCollection getClasspath() { - return classpath; - } + public abstract ConfigurableFileCollection getThirdPartyClasspath(); @TaskAction public void runThirdPartyAudit() throws IOException { @@ -345,7 +340,7 @@ private String runForbiddenAPIsCli() throws IOException { if (javaHome.isPresent()) { spec.setExecutable(javaHome.get() + "/bin/java"); } - spec.classpath(getForbiddenAPIsClasspath(), classpath); + spec.classpath(getForbiddenAPIsClasspath(), getThirdPartyClasspath()); // Enable explicitly for each release as appropriate. Just JDK 20/21/22/23 for now, and just the vector module. if (isJavaVersion(VERSION_20) || isJavaVersion(VERSION_21) || isJavaVersion(VERSION_22) || isJavaVersion(VERSION_23)) { spec.jvmArgs("--add-modules", "jdk.incubator.vector"); @@ -383,7 +378,7 @@ private boolean isJavaVersion(JavaVersion version) { private Set runJdkJarHellCheck() throws IOException { ByteArrayOutputStream standardOut = new ByteArrayOutputStream(); ExecResult execResult = execOperations.javaexec(spec -> { - spec.classpath(getJdkJarHellClasspath(), classpath); + spec.classpath(getJdkJarHellClasspath(), getThirdPartyClasspath()); spec.getMainClass().set(JDK_JAR_HELL_MAIN_CLASS); spec.args(getJarExpandDir()); spec.setIgnoreExitValue(true); @@ -402,8 +397,4 @@ private Set runJdkJarHellCheck() throws IOException { return new TreeSet<>(Arrays.asList(jdkJarHellCheckList.split("\\r?\\n"))); } - public void setClasspath(FileCollection classpath) { - this.classpath = classpath; - } - } diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/util/DependenciesUtils.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/util/DependenciesUtils.java index 9080f62f19937..5d7386e2c2150 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/util/DependenciesUtils.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/util/DependenciesUtils.java @@ -9,12 +9,16 @@ package org.elasticsearch.gradle.internal.util; +import com.github.jengelman.gradle.plugins.shadow.ShadowBasePlugin; + import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.ResolvableDependencies; import org.gradle.api.artifacts.component.ComponentIdentifier; +import org.gradle.api.artifacts.component.ProjectComponentIdentifier; import org.gradle.api.artifacts.result.ResolvedComponentResult; import org.gradle.api.artifacts.result.ResolvedDependencyResult; import org.gradle.api.file.FileCollection; +import org.gradle.api.provider.Provider; import org.gradle.api.specs.AndSpec; import org.gradle.api.specs.Spec; @@ -29,7 +33,7 @@ public static FileCollection createFileCollectionFromNonTransitiveArtifactsView( ) { ResolvableDependencies incoming = configuration.getIncoming(); return incoming.artifactView(viewConfiguration -> { - Set firstLevelDependencyComponents = incoming.getResolutionResult() + Provider> firstLevelDependencyComponents = incoming.getResolutionResult() .getRootComponent() .map( rootComponent -> rootComponent.getDependencies() @@ -39,12 +43,36 @@ public static FileCollection createFileCollectionFromNonTransitiveArtifactsView( .filter(dependency -> dependency.getSelected() instanceof ResolvedComponentResult) .map(dependency -> dependency.getSelected().getId()) .collect(Collectors.toSet()) - ) - .get(); + ); viewConfiguration.componentFilter( - new AndSpec<>(identifier -> firstLevelDependencyComponents.contains(identifier), componentFilter) + new AndSpec<>(identifier -> firstLevelDependencyComponents.get().contains(identifier), componentFilter) ); }).getFiles(); } + /** + * This method gives us an artifact view of a configuration that filters out all + * project dependencies that are not shadowed jars. + * Basically a thirdparty only view of the dependency tree. + */ + public static FileCollection thirdPartyDependenciesView(Configuration configuration) { + ResolvableDependencies incoming = configuration.getIncoming(); + return incoming.artifactView(v -> { + // resolve componentIdentifier for all shadowed project dependencies + Provider> shadowedDependencies = incoming.getResolutionResult() + .getRootComponent() + .map( + root -> root.getDependencies() + .stream() + .filter(dep -> dep instanceof ResolvedDependencyResult) + .map(dep -> (ResolvedDependencyResult) dep) + .filter(dep -> dep.getResolvedVariant().getDisplayName() == ShadowBasePlugin.COMPONENT_NAME) + .filter(dep -> dep.getSelected() instanceof ResolvedComponentResult) + .map(dep -> dep.getSelected().getId()) + .collect(Collectors.toSet()) + ); + // filter out project dependencies if they are not a shadowed dependency + v.componentFilter(i -> (i instanceof ProjectComponentIdentifier == false || shadowedDependencies.get().contains(i))); + }).getFiles(); + } } From 140beb11849b42ceae311b34f2865f3db68df578 Mon Sep 17 00:00:00 2001 From: Tommaso Teofili Date: Wed, 18 Dec 2024 09:42:51 +0100 Subject: [PATCH 29/60] Make ES|QL scoring tests running consistently in serverless (#118854) * make scoring tests running consistently in serverless enforce _id in books dataset to make doc distribution across shards consistent. books settings with 3 shards to accomodate serverless settings. unmuting scoring tests. scoring test fixed. --- muted-tests.yml | 18 -- .../xpack/esql/CsvTestsDataLoader.java | 2 +- .../src/main/resources/books-settings.json | 5 + .../testFixtures/src/main/resources/books.csv | 160 +++++++++--------- .../src/main/resources/scoring.csv-spec | 104 ++++++------ 5 files changed, 140 insertions(+), 149 deletions(-) create mode 100644 x-pack/plugin/esql/qa/testFixtures/src/main/resources/books-settings.json diff --git a/muted-tests.yml b/muted-tests.yml index ef302671de998..2677b3e75d86e 100644 --- a/muted-tests.yml +++ b/muted-tests.yml @@ -153,24 +153,6 @@ tests: issue: https://github.com/elastic/elasticsearch/issues/117473 - class: org.elasticsearch.repositories.s3.RepositoryS3EcsClientYamlTestSuiteIT issue: https://github.com/elastic/elasticsearch/issues/117525 -- class: "org.elasticsearch.xpack.esql.qa.multi_node.EsqlSpecIT" - method: "test {scoring.*}" - issue: https://github.com/elastic/elasticsearch/issues/117641 -- class: "org.elasticsearch.xpack.esql.qa.single_node.EsqlSpecIT" - method: "test {scoring.*}" - issue: https://github.com/elastic/elasticsearch/issues/117641 -- class: "org.elasticsearch.xpack.esql.qa.mixed.MixedClusterEsqlSpecIT" - method: "test {scoring.*}" - issue: https://github.com/elastic/elasticsearch/issues/117641 -- class: "org.elasticsearch.xpack.esql.qa.mixed.MultiClusterEsqlSpecIT" - method: "test {scoring.*}" - issue: https://github.com/elastic/elasticsearch/issues/118460 -- class: "org.elasticsearch.xpack.esql.ccq.MultiClusterSpecIT" - method: "test {scoring.*}" - issue: https://github.com/elastic/elasticsearch/issues/118460 -- class: org.elasticsearch.xpack.esql.ccq.MultiClusterSpecIT - method: test {scoring.QstrWithFieldAndScoringSortedEval} - issue: https://github.com/elastic/elasticsearch/issues/117751 - class: org.elasticsearch.search.ccs.CrossClusterIT method: testCancel issue: https://github.com/elastic/elasticsearch/issues/108061 diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestsDataLoader.java b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestsDataLoader.java index abfe90f80e372..8e81d14b4dfd7 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestsDataLoader.java +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestsDataLoader.java @@ -104,7 +104,7 @@ public class CsvTestsDataLoader { private static final TestsDataset DISTANCES = new TestsDataset("distances"); private static final TestsDataset K8S = new TestsDataset("k8s", "k8s-mappings.json", "k8s.csv").withSetting("k8s-settings.json"); private static final TestsDataset ADDRESSES = new TestsDataset("addresses"); - private static final TestsDataset BOOKS = new TestsDataset("books"); + private static final TestsDataset BOOKS = new TestsDataset("books").withSetting("books-settings.json"); private static final TestsDataset SEMANTIC_TEXT = new TestsDataset("semantic_text").withInferenceEndpoint(true); public static final Map CSV_DATASET_MAP = Map.ofEntries( diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/books-settings.json b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/books-settings.json new file mode 100644 index 0000000000000..b324c27b40653 --- /dev/null +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/books-settings.json @@ -0,0 +1,5 @@ +{ + "index": { + "number_of_shards": 3 + } +} diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/books.csv b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/books.csv index 1deefaa3c6475..1cb01687e6511 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/books.csv +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/books.csv @@ -1,80 +1,80 @@ -book_no:keyword,title:text,author:text,year:integer,publisher:text,ratings:float,description:text -2924,A Gentle Creature and Other Stories: White Nights\, A Gentle Creature\, and The Dream of a Ridiculous Man (The World's Classics),[Fyodor Dostoevsky, Alan Myers, W. J. Leatherbarrow],2009,Oxford Paperbacks,4.00,In these stories Dostoevsky explores both the figure of the dreamer divorced from reality and also his own ambiguous attitude to utopianism\, themes central to many of his great novels. This new translation captures the power and lyricism of Dostoevsky's writing\, while the introduction examines the stories in relation to one another and to his novels. -7670,A Middle English Reader and Vocabulary,[Kenneth Sisam, J. R. R. Tolkien],2011,Courier Corporation,4.33,This highly respected anthology of medieval English literature features poetry\, prose and popular tales from Arthurian legend and classical mythology. Includes notes on each extract\, appendices\, and an extensive glossary by J. R. R. Tolkien. -7381,A Psychic in the Heartland: The Extraordinary Experiences of a Small Town Doctor,Bettilu Stein Faulkner,2003,Red Wheel/Weiser,4.50,The true story of a small-town doctor destined to live his life along two paths: one as a successful physician\, the other as a psychic with ever more interesting adventures. Experiencing a wide range of spiritual phenomena\, Dr. Riblet Hout learned about the connection between the healer and the healed\, our individual missions on earth\, free will\, and our relationship with God. He also paints a vivid picture of life on the other side as well as the moment of transition from physical life to afterlife. -2883,A Summer of Faulkner: As I Lay Dying/The Sound and the Fury/Light in August (Oprah's Book Club),William Faulkner,2005,Vintage Books,3.89,Presents three novels\, including As I Lay Dying\, in which the Bundren family journeys across Mississippi to bury their mother\, The Sound and the Fury\, in which Caddy Compson's story is narrated by her three brothers\, and Light in August\, in which th -4023,A Tolkien Compass: Including J. R. R. Tolkien's Guide to the Names in The Lord of the Rings,[Walter Scheps, Agnes Perkins, Charles Adolph Huttar, John Ronald Reuel Tolkien],1975,Open Court Publishing,4.67,The structure\, content\, and character of Tolkien's The Hobbit and The Lord of the Rings are dealt with in ten critical essays. -2382,A Wizard of Earthsea (Earthsea Trilogy Ser.),Ursula K. Le Guin,1991,Atheneum Books for Young Readers,4.01,A boy grows to manhood while attempting to subdue the evil he unleashed on the world as an apprentice to the Master Wizard. -7541,A Writer's Diary (Volume 1: 1873-1876),Fyodor Dostoevsky,1997,Northwestern University Press,4.50,Winner of the AATSEEL Outstanding Translation Award This is the first paperback edition of the complete collection of writings that has been called Dostoevsky's boldest experiment with literary form\, it is a uniquely encyclopedic forum of fictional and nonfictional genres. The Diary's radical format was matched by the extreme range of its contents. In a single frame it incorporated an astonishing variety of material: short stories\, humorous sketches\, reports on sensational crimes\, historical predictions\, portraits of famous people\, autobiographical pieces\, and plans for stories\, some of which were never written while others appeared in the Diary itself. -7400,Anna Karenina: Television Tie-In Edition (Signet classics),[Leo Tolstoy, SBP Editors],2019,Samaira Book Publishers,4.45,The Russian novelist and moral philosopher Leo Tolstoy (1828-1910) ranks as one of the world s great writers\, and his 'War and Peace' has been called the greatest novel ever written. But during his long lifetime\, Tolstoy also wrote enough shorter works to fill many volumes. The message in all his stories is presented with such humour that the reader hardly realises that it is strongly didactic. These stories give a snapshot of Russia and its people in the late nineteenth century. -4917,Autumn of the Patriarch,Gabriel Garcia Marquez,2014,Penguin UK,4.33,Gabriel Garcia Marquez\, winner of the 1982 Nobel Prize for Literature and author of One Hundred Years of Solitude\, explores the loneliness of power in Autumn of the Patriarch. 'Over the weekend the vultures got into the presidential palace by pecking through the screens on the balcony windows and the flapping of their wings stirred up the stagnant time inside' As the citizens of an unnamed Caribbean nation creep through dusty corridors in search of their tyrannical leader\, they cannot comprehend that the frail and withered man lying dead on the floor can be the self-styled General of the Universe. Their arrogant\, manically violent leader\, known for serving up traitors to dinner guests and drowning young children at sea\, can surely not die the humiliating death of a mere mortal? Tracing the demands of a man whose egocentric excesses mask the loneliness of isolation and whose lies have become so ingrained that they are indistinguishable from truth\, Marquez has created a fantastical portrait of despotism that rings with an air of reality. 'Delights with its quirky humanity and black humour and impresses by its total originality' Vogue 'Captures perfectly the moral squalor and political paralysis that enshrouds a society awaiting the death of a long-term dictator' Guardian 'Marquez writes in this lyrical\, magical language that no-one else can do' Salman Rushdie -9896,Barn burning (A tale blazer book),William Faulkner,1979,Perfection Learning,3.50,Reprinted from Collected Stories of William Faulkner\, by permission of Random House\, Inc. -9607,Beowolf: The monsters and the critics,John Ronald Reuel Tolkien,1997,HarperCollins UK,4.12,A collection of seven essays by J.R.R. Tolkien arising out of Tolkien's work in medieval literature -1985,Brothers Karamazov,Fyodor Dostoevsky,2015,First Avenue Editions,5.00,Four brothers reunite in their hometown in Russia. The murder of their father forces the brothers to question their beliefs about each other\, religion\, and morality. -2713,Collected Stories of William Faulkner,William Faulkner,1995,Vintage,4.53,A collection of short stories focuses on the people of rural Mississippi -2464,Conversations with Kurt Vonnegut (Literary Conversations),Kurt Vonnegut,1988,Univ. Press of Mississippi,4.40,Gathers interviews with Vonnegut from each period of his career and offers a brief profile of his life and accomplishments -8534,Crime and Punishment (Oxford World's Classics),Fyodor Dostoevsky,2017,Oxford University Press,4.38,'One death\, in exchange for thousands of lives - it's simple arithmetic!' A new translation of Dostoevsky's epic masterpiece\, Crime and Punishment (1866). The impoverished student Raskolnikov decides to free himself from debt by killing an old moneylender\, an act he sees as elevating himself above conventional morality. Like Napoleon he will assert his will and his crime will be justified by its elimination of 'vermin' for the sake of the greater good. But Raskolnikov is torn apart by fear\, guilt\, and a growing conscience under the influence of his love for Sonya. Meanwhile the police detective Porfiry is on his trial. It is a powerfully psychological novel\, in which the St Petersburg setting\, Dostoevsky's own circumstances\, and contemporary social problems all play their part. -8605,Dead Souls,Nikolai Gogol,1997,Vintage,4.28,Chichikov\, an amusing and often confused schemer\, buys deceased serfs' names from landholders' poll tax lists hoping to mortgage them for profit -6970,Domestic Goddesses,Edith Vonnegut,1998,Pomegranate,4.67,In this immensely charming and insightful book\, artist Edith Vonnegut takes issue with traditional art imagery in which women are shown as weak and helpless. Through twenty-seven of her own paintings interspersed with her text\, she poignantly -- and humorously -- illustrates her maxim that the lives of mothers and homemakers are filled with endless challenges and vital decisions that should be portrayed with the dignity they deserve. In Vonnegut's paintings\, one woman bravely blocks the sun from harming a child (Sun Block) while another vacuums the stairs with angelic figures singing her praises (Electrolux). In contrasting her own Domestic Goddesses with the diaphanous women of classical art (seven paintings by masters such as Titian and Botticelli are included)\, she 'expresses the importance of traditional roles of women so cleverly and with such joy that her message and images will be forever emblazoned on our collective psyche. -4814,El Coronel No Tiene Quien Le Escriba / No One Writes to the Colonel (Spanish Edition),Gabriel Garcia Marquez,2005,Harper Collins,4.45,Written with compassionate realism and wit\, the stories in this mesmerizing collection depict the disparities of town and village life in South America\, of the frightfully poor and outrageously rich\, of memories and illusions\, and of lost opportunities and present joys. -4636,FINAL WITNESS,Simon Tolkien,2004,Random House Digital\, Inc.,3.94,The murder of Lady Anne Robinson by two intruders causes a schism in the victim's family when her son convinces police that his father's beautiful personal assistant hired the killers\, while his father\, the British minister of defense\, refuses to believe his son and marries the accused. A first novel. Reprint. -2936,Fellowship of the Ring 2ND Edition,John Ronald Reuel Tolkien,2008,HarperCollins UK,4.43,Sauron\, the Dark Lord\, has gathered to him all the Rings of Power - the means by which he intends to rule Middle-earth. All he lacks in his plans for dominion is the One Ring - the ring that rules them all - which has fallen into the hands of the hobbit\, Bilbo Baggins. In a sleepy village in the Shire\, young Frodo Baggins finds himself faced with an immense task\, as his elderly cousin Bilbo entrusts the Ring to his care. Frodo must leave his home and make a perilous journey across Middle-earth to the Cracks of Doom\, there to destroy the Ring and foil the Dark Lord in his evil purpose. JRR Tolkien's great work of imaginative fiction has been labelled both a heroic romance and a classic fantasy fiction. By turns comic and homely\, epic and diabolic\, the narrative moves through countless changes of scene and character in an imaginary world which is totally convincing in its detail. -8956,GOD BLESS YOU MR. ROSEWATER : Or Pearls Before Swine,Kurt Vonnegut,1970,New York : Dell,4.00,A lawyer schemes to gain control of a large fortune by having the present claimant declared insane. -6818,Hadji Murad,Leo Tolstoy,2022,Hachette UK,3.88,'How truth thickens and deepens when it migrates from didactic fable to the raw experience of a visceral awakening is one of the thrills of Tolstoy's stories' Sharon Cameron in her preface to Hadji Murad and Other Stories This\, the third volume of Tolstoy's shorter fiction concentrates on his later stories\, including one of his greatest\, 'Hadji Murad'. In the stark form of homily that shapes these later works\, life considered as one's own has no rational meaning. From the chain of events that follows in the wake of two schoolboys' deception in 'The Forged Coupon' to the disillusionment of the narrator in 'After the Ball' we see\, in Virginia Woolf's observation\, that Tolstoy puts at the centre of his writing one 'who gathers into himself all experience\, turns the world round between his fingers\, and never ceases to ask\, even as he enjoys it\, what is the meaning of it'. The riverrun edition reissues the translation of Louise and Aylmer Maude\, whose influential versions of Tolstoy first brought his work to a wide readership in English. -3950,Hocus,Kurt Vonnegut,1997,Penguin,4.67,Tarkington College\, a small\, exclusive college in upstate New York\, is turned upside down when ten thousand prisoners from the maximum security prison across Lake Mohiga break out and head for the college -5404,Intruder in the dust,William Faulkner,2011,Vintage,3.18,A classic Faulkner novel which explores the lives of a family of characters in the South. An aging black who has long refused to adopt the black's traditionally servile attitude is wrongfully accused of murdering a white man. -5578,Intruder in the dust: A novel,William Faulkner,1991,Vintage,3.18,Dramatizes the events that surround the murder of a white man in a volatile Southern community -6380,La hojarasca (Spanish Edition),Gabriel Garcia Marquez,1979,Harper Collins,3.75,Translated from the Spanish by Gregory Rabassa -5335,Letters of J R R Tolkien,J.R.R. Tolkien,2014,HarperCollins,4.70,This collection will entertain all who appreciate the art of masterful letter writing. The Letters of J.R.R Tolkien sheds much light on Tolkien's creative genius and grand design for the creation of a whole new world: Middle-earth. Featuring a radically expanded index\, this volume provides a valuable research tool for all fans wishing to trace the evolution of THE HOBBIT and THE LORD OF THE RINGS. -3870,My First 100 Words in Spanish/English (My First 100 Words Pull-Tab Book),Keith Faulkner,1998,Libros Para Ninos,4.50,Learning a foreign language has never been this much fun! Just pull the sturdy tabs and change the words under the pictures from English to Spanish and back again to English! -4502,O'Brian's Bride,Colleen Faulkner,1995,Zebra Books,5.00,Abandoning her pampered English life to marry a man in the American colonies\, Elizabeth finds her new world shattered when her husband is killed in an accident\, leaving her in charge of a business on the untamed frontier. Original. -7635,Oliphaunt (Beastly Verse),J. R. R. Tolkien,1989,Contemporary Books,2.50,A poem in which an elephant describes himself and his way of life. On board pages. -3254,Pearl and Sir Orfeo,[John Ronald Reuel Tolkien, Christopher Tolkien],1995,Harpercollins Pub Limited,5.00,Three epic poems from 14th century England speak of life during the age of chivalry. Translated from medieval English. -3677,Planet of Exile,Ursula K. Le Guin,1979,Orion,4.20,PLAYAWAY: An alliance between the powerful Tevars and the brown-skinned\, clairvoyant Farbons must take place if the two colonies are to withstand the fierce attack of the nomadic tribes from the north of the planet Eltanin. -4289,Poems from the Hobbit,J R R Tolkien,1999,HarperCollins Publishers,4.00,A collection of J.R.R. Tolkien's Hobbit poems in a miniature hardback volume complete with illustrations by Tolkien himself. Far over misty mountains cold To dungeons deep and caverns old We must away ere break of day To seek the pale enchanted gold. J.R.R. Tolkien's acclaimed The Hobbit contains 12 poems which are themselves masterpieces of writing. This miniature book\, illustrated with 30 of Tolkien's own paintings and drawings from the book -- some quite rare and all in full colour -- includes all the poems\, plus Gollum's eight riddles in verse\, and will be a perfect keepsake for lovers of The Hobbit and of accomplished poetry. -6151,Pop! Went Another Balloon: A Magical Counting Storybook (Magical Counting Storybooks),[Keith Faulkner, Rory Tyger],2003,Dutton Childrens Books,5.00,Toby the turtle goes from in-line skates to a motorcycle to a rocketship with a handful of balloons that pop\, one by one\, along the way. -3535,Rainbow's End: A Magical Story and Moneybox,[Keith Faulkner, Beverlie Manson],2003,Barrons Juveniles,4.00,In this combination picture storybook and coin bank\, the unusual front cover shows an illustration from the story that's embellished with five transparent plastic windows. Opening the book\, children will find a story about a poor little ballerina who is crying because her dancing shoes are worn and she has no money to replace them. Full color. Consumable. -8423,Raising Faithful Kids in a Fast-Paced World,Paul Faulkner,1995,Howard Publishing Company,5.00,To find help for struggling parents\, Dr. Paul Faulkner--renowned family counselor and popular speaker--interviewed 30 successful families who have managed to raise faithful kids while also maintaining demanding careers. The invaluable strategies and methods he gleaned are now available in this powerful book delivered in Dr. Faulkner's warm\, humorous style. -1463,Realms of Tolkien: Images of Middle-earth,J. R. R. Tolkien,1997,HarperCollins Publishers,4.00,Twenty new and familiar Tolkien artists are represented in this fabulous volume\, breathing an extraordinary variety of life into 58 different scenes\, each of which is accompanied by appropriate passage from The Hobbit and The Lord of the Rings and The Silmarillion -6323,Resurrection (The Penguin classics),Leo Tolstoy,2009,Penguin,3.25,Leo Tolstoy's last completed novel\, Resurrection is an intimate\, psychological tale of guilt\, anger and forgiveness Serving on the jury at a murder trial\, Prince Dmitri Nekhlyudov is devastated when he sees the prisoner - Katyusha\, a young maid he seduced and abandoned years before. As Dmitri faces the consequences of his actions\, he decides to give up his life of wealth and luxury to devote himself to rescuing Katyusha\, even if it means following her into exile in Siberia. But can a man truly find redemption by saving another person? Tolstoy's most controversial novel\, Resurrection (1899) is a scathing indictment of injustice\, corruption and hypocrisy at all levels of society. Creating a vast panorama of Russian life\, from peasants to aristocrats\, bureaucrats to convicts\, it reveals Tolstoy's magnificent storytelling powers. Anthony Briggs' superb new translation preserves Tolstoy's gripping realism and satirical humour. In his introduction\, Briggs discusses the true story behind Resurrection\, Tolstoy's political and religious reasons for writing the novel\, his gift for characterization and the compelling psychological portrait of Dmitri. This edition also includes a chronology\, notes and a summary of chapters. For more than seventy years\, Penguin has been the leading publisher of classic literature in the English-speaking world. With more than 1\,700 titles\, Penguin Classics represents a global bookshelf of the best works throughout history and across genres and disciplines. Readers trust the series to provide authoritative texts enhanced by introductions and notes by distinguished scholars and contemporary authors\, as well as up-to-date translations by award-winning translators. -2714,Return of the King Being the Third Part of The Lord of the Rings,J. R. R. Tolkien,2012,HarperCollins,4.60,Concluding the story begun in The Hobbit\, this is the final part of Tolkien s epic masterpiece\, The Lord of the Rings\, featuring an exclusive cover image from the film\, the definitive text\, and a detailed map of Middle-earth. The armies of the Dark Lord Sauron are massing as his evil shadow spreads ever wider. Men\, Dwarves\, Elves and Ents unite forces to do battle agains the Dark. Meanwhile\, Frodo and Sam struggle further into Mordor in their heroic quest to destroy the One Ring. The devastating conclusion of J.R.R. Tolkien s classic tale of magic and adventure\, begun in The Fellowship of the Ring and The Two Towers\, features the definitive edition of the text and includes the Appendices and a revised Index in full. To celebrate the release of the first of Peter Jackson s two-part film adaptation of The Hobbit\, THE HOBBIT: AN UNEXPECTED JOURNEY\, this third part of The Lord of the Rings is available for a limited time with an exclusive cover image from Peter Jackson s award-winning trilogy. -7350,Return of the Shadow,[John Ronald Reuel Tolkien, Christopher Tolkien],2000,Mariner Books,5.00,In this sixth volume of The History of Middle-earth the story reaches The Lord of the Rings. In The Return of the Shadow (an abandoned title for the first volume) Christopher Tolkien describes\, with full citation of the earliest notes\, outline plans\, and narrative drafts\, the intricate evolution of The Fellowship of the Ring and the gradual emergence of the conceptions that transformed what J.R.R. Tolkien for long believed would be a far shorter book\, 'a sequel to The Hobbit'. The enlargement of Bilbo's 'magic ring' into the supremely potent and dangerous Ruling Ring of the Dark Lord is traced and the precise moment is seen when\, in an astonishing and unforeseen leap in the earliest narrative\, a Black Rider first rode into the Shire\, his significance still unknown. The character of the hobbit called Trotter (afterwards Strider or Aragorn) is developed while his indentity remains an absolute puzzle\, and the suspicion only very slowly becomes certainty that he must after all be a Man. The hobbits\, Frodo's companions\, undergo intricate permutations of name and personality\, and other major figures appear in strange modes: a sinister Treebeard\, in league with the Enemy\, a ferocious and malevolent Farmer Maggot. The story in this book ends at the point where J.R.R. Tolkien halted in the story for a long time\, as the Company of the Ring\, still lacking Legolas and Gimli\, stood before the tomb of Balin in the Mines of Moria. The Return of the Shadow is illustrated with reproductions of the first maps and notable pages from the earliest manuscripts. -6760,Roverandom,J. R. R. Tolkien,1999,Mariner Books,4.38,Rover\, a dog who has been turned into a toy dog encounters rival wizards and experiences various adventures on the moon with giant spiders\, dragon moths\, and the Great White Dragon. By the author of The Hobbit. Reprint. -8873,Searoad: Chronicles of Klatsand,Ursula K. Le Guin,2004,Shambhala Publications,5.00,A series of interlinking tales and a novella by the author of the Earthsea trilogy portrays the triumphs and struggles of several generations of women who independently control Klatsand\, a small resort town on the Oregon coast. Reprint. -2378,Selected Letters of Lucretia Coffin Mott (Women in American History),[Lucretia Mott, Holly Byers Ochoa, Carol Faulkner],2002,University of Illinois Press,5.00,Dedicated to reform of almost every kind - temperance\, peace\, equal rights\, woman suffrage\, nonresistance\, and the abolition of slavery - Mott viewed women's rights as only one element of a broad-based reform agenda for American society. -1502,Selected Passages from Correspondence with Friends,Nikolai Vasilevich Gogol,2009,Vanderbilt University Press,4.00,Nikolai Gogol wrote some letters to his friends\, none of which were a nose of high rank. Many are reproduced here (the letters\, not noses). -5996,Smith of Wooten Manor & Farmer Giles of Ham,John Ronald Reuel Tolkien,1969,Del Rey,4.91,Two bewitching fantasies by J.R.R. Tolkien\, beloved author of THE HOBBIT. In SMITH OF WOOTTON MAJOR\, Tolkien explores the gift of fantasy\, and what it means to the life and character of the man who receives it. And FARMER GILES OF HAM tells a delightfully ribald mock-heroic tale\, where a dragon who invades a town refuses to fight\, and a farmer is chosen to slay him. -2301,Smith of Wootton Major & Farmer Giles of Ham,John Ronald Reuel Tolkien,1969,Del Rey,5.00,Two bewitching fantasies by J.R.R. Tolkien\, beloved author of THE HOBBIT. In SMITH OF WOOTTON MAJOR\, Tolkien explores the gift of fantasy\, and what it means to the life and character of the man who receives it. And FARMER GILES OF HAM tells a delightfully ribald mock-heroic tale\, where a dragon who invades a town refuses to fight\, and a farmer is chosen to slay him. -2236,Steering the Craft,Ursula K. Le Guin,2015,Houghton Mifflin Harcourt,4.73,A revised and updated guide to the essentials of a writer's craft\, presented by a brilliant practitioner of the art Completely revised and rewritten to address the challenges and opportunities of the modern era\, this handbook is a short\, deceptively simple guide to the craft of writing. Le Guin lays out ten chapters that address the most fundamental components of narrative\, from the sound of language to sentence construction to point of view. Each chapter combines illustrative examples from the global canon with Le Guin's own witty commentary and an exercise that the writer can do solo or in a group. She also offers a comprehensive guide to working in writing groups\, both actual and online. Masterly and concise\, Steering the Craft deserves a place on every writer's shelf. -4724,THE UNVANQUISHED,William Faulkner,2011,Vintage,3.50,Set in Mississippi during the Civil War and Reconstruction\, THE UNVANQUISHED focuses on the Sartoris family\, who\, with their code of personal responsibility and courage\, stand for the best of the Old South's traditions. -5948,That We Are Gentle Creatures,Fyodor Dostoevsky,2009,OUP Oxford,4.33,In the stories in this volume Dostoevsky explores both the figure of the dreamer divorced from reality and also his own ambiguous attitude to utopianism\, themes central to many of his great novels. In White Nights the apparent idyll of the dreamer's romantic fantasies disguises profound loneliness and estrangement from 'living life'. Despite his sentimental friendship with Nastenka\, his final withdrawal into the world of the imagination anticipates the retreat into the 'underground' of many of Dostoevsky's later intellectual heroes. A Gentle Creature and The Dream of a Ridiculous Man show how such withdrawal from reality can end in spiritual desolation and moral indifference and how\, in Dostoevsky's view\, the tragedy of the alienated individual can be resolved only by the rediscovery of a sense of compassion and responsibility towards fellow human beings. This new translation captures the power and lyricism of Dostoevsky's writing\, while the introduction examines the stories in relation to one another and to his novels. ABOUT THE SERIES: For over 100 years Oxford World's Classics has made available the widest range of literature from around the globe. Each affordable volume reflects Oxford's commitment to scholarship\, providing the most accurate text plus a wealth of other valuable features\, including expert introductions by leading authorities\, helpful notes to clarify the text\, up-to-date bibliographies for further study\, and much more. -1937,The Best Short Stories of Dostoevsky (Modern Library),Fyodor Dostoevsky,2012,Modern Library,4.33,This collection\, unique to the Modern Library\, gathers seven of Dostoevsky's key works and shows him to be equally adept at the short story as with the novel. Exploring many of the same themes as in his longer works\, these small masterpieces move from the tender and romantic White Nights\, an archetypal nineteenth-century morality tale of pathos and loss\, to the famous Notes from the Underground\, a story of guilt\, ineffectiveness\, and uncompromising cynicism\, and the first major work of existential literature. Among Dostoevsky's prototypical characters is Yemelyan in The Honest Thief\, whose tragedy turns on an inability to resist crime. Presented in chronological order\, in David Magarshack's celebrated translation\, this is the definitive edition of Dostoevsky's best stories. -2776,The Devil and Other Stories (Oxford World's Classics),Leo Tolstoy,2003,OUP Oxford,5.00,'It is impossible to explain why Yevgeny chose Liza Annenskaya\, as it is always impossible to explain why a man chooses this and not that woman.' This collection of eleven stories spans virtually the whole of Tolstoy's creative life. While each is unique in form\, as a group they are representative of his style\, and touch on the central themes that surface in War and Peace and Anna Karenina. Stories as different as 'The Snowstorm'\, 'Lucerne'\, 'The Diary of a Madman'\, and 'The Devil' are grounded in autobiographical experience. They deal with journeys of self-discovery and the moral and religious questioning that characterizes Tolstoy's works of criticism and philosophy. 'Strider' and 'Father Sergy'\, as well as reflecting Tolstoy's own experiences\, also reveal profound psychological insights. These stories range over much of the Russian world of the nineteenth century\, from the nobility to the peasantry\, the military to the clergy\, from merchants and cobblers to a horse and a tree. Together they present a fascinating picture of Tolstoy's skill and artistry. ABOUT THE SERIES: For over 100 years Oxford World's Classics has made available the widest range of literature from around the globe. Each affordable volume reflects Oxford's commitment to scholarship\, providing the most accurate text plus a wealth of other valuable features\, including expert introductions by leading authorities\, helpful notes to clarify the text\, up-to-date bibliographies for further study\, and much more. -4231,The Dispossessed,Ursula K. Le Guin,1974,Harpercollins,4.26,Frequently reissued with the same ISBN\, but with slightly differing bibliographical details. -7480,The Hobbit,J. R. R. Tolkien,2012,Mariner Books,4.64,Celebrating 75 years of one of the world's most treasured classics with an all new trade paperback edition. Repackaged with new cover art. 500\,000 first printing. -6405,The Hobbit or There and Back Again,J. R. R. Tolkien,2012,Mariner Books,4.63,Celebrating 75 years of one of the world's most treasured classics with an all new trade paperback edition. Repackaged with new cover art. 500\,000 first printing. -2540,The Inspector General (Language - Russian) (Russian Edition),[Nicolai Gogol, Thomas Seltzer],2014,CreateSpace,3.50,The Inspector-General is a national institution. To place a purely literary valuation upon it and call it the greatest of Russian comedies would not convey the significance of its position either in Russian literature or in Russian life itself. There is no other single work in the modern literature of any language that carries with it the wealth of associations which the Inspector-General does to the educated Russian. -2951,The Insulted and Injured,Fyodor Dostoevsky,2011,Wm. B. Eerdmans Publishing,4.00,The Insulted and Injured\, which came out in 1861\, was Fyodor Dostoevsky's first major work of fiction after his Siberian exile and the first of the long novels that made him famous. Set in nineteenth-century Petersburg\, this gripping novel features a vividly drawn set of characters - including Vanya (Dostoevsky's semi-autobiographical hero)\, Natasha (the woman he loves)\, and Alyosha (Natasha's aristocratic lover) - all suffering from the cruelly selfish machinations of Alyosha's father\, the dark and powerful Prince Valkovsky. Boris Jakim's fresh English-language rendering of this gem in the Doestoevsky canon is both more colorful and more accurate than any earlier translation. --from back cover. -2130,The J. R. R. Tolkien Audio Collection,[John Ronald Reuel Tolkien, Christopher Tolkien],2002,HarperCollins Publishers,4.89,For generations\, J R R Tolkien's words have brought to thrilling life a world of hobbits\, magic\, and historic myth\, woken from its foggy slumber within our minds. Here\, he tells the tales in his own voice. -9801,The Karamazov Brothers (Oxford World's Classics),Fyodor Dostoevsky,2008,Oxford University Press,4.40,A remarkable work showing the author's power to depict Russian character and his understanding of human nature. Driven by intense\, uncontrollable emotions of rage and revenge\, the four Karamazov brothers all become involved in the brutal murder of their despicable father. -5469,The Lays of Beleriand,[John Ronald Reuel Tolkien, Christopher Tolkien],2002,Harpercollins Pub Limited,4.42,The third volume that contains the early myths and legends which led to the writing of Tolkien's epic tale of war\, The Silmarillion. This\, the third volume of The History of Middle-earth\, gives us a priviledged insight into the creation of the mythology of Middle-earth\, through the alliterative verse tales of two of the most crucial stories in Tolkien's world -- those of Turien and Luthien. The first of the poems is the unpublished Lay of The Children of Hurin\, narrating on a grand scale the tragedy of Turin Turambar. The second is the moving Lay of Leithian\, the chief source of the tale of Beren and Luthien in The Silmarillion\, telling of the Quest of the Silmaril and the encounter with Morgoth in his subterranean fortress. Accompanying the poems are commentaries on the evolution of the history of the Elder Days. Also included is the notable criticism of The Lay of The Leithian by CS Lewis\, who read the poem in 1929. -2675,The Lord of the Rings - Boxed Set,J.R.R. Tolkien,2012,HarperCollins,4.56,This beautiful gift edition of The Hobbit\, J.R.R. Tolkien's classic prelude to his Lord of the Rings trilogy\, features cover art\, illustrations\, and watercolor paintings by the artist Alan Lee. Bilbo Baggins is a hobbit who enjoys a comfortable\, unambitious life\, rarely traveling any farther than his pantry or cellar. But his contentment is disturbed when the wizard Gandalf and a company of dwarves arrive on his doorstep one day to whisk him away on an adventure. They have launched a plot to raid the treasure hoard guarded by Smaug the Magnificent\, a large and very dangerous dragon. Bilbo reluctantly joins their quest\, unaware that on his journey to the Lonely Mountain he will encounter both a magic ring and a frightening creature known as Gollum. Written for J.R.R. Tolkien's own children\, The Hobbit has sold many millions of copies worldwide and established itself as a modern classic. -7140,The Lord of the Rings Poster Collection: Six Paintings by Alan Lee (No. 1),[J. R. R. Tolkien, Alan Lee],2002,HarperSport,4.75,A selection of stunning poster paintings from the celebrated Tolkien artist Alan Lee - the man behind many of the striking images from The Lord of The Rings movie. The 50 paintings contained within the centenary edition of The Lord of the Rings in 1992 have themselves become classics and Alan Lee's interpretations are hailed as the most faithful to Tolkien's own vision. This new poster collection\, a perfect complement to volume one\, reproduces six more of the most popular paintings from the book in a format suitable either for hanging as posters or mounting and framing. -5127,The Overcoat, Nikolai Gogol,1992,Courier Corporation,3.75,Four short stories include a satirical tale of Russian bureaucrats and a portrayal of an elderly couple living in the secluded countryside. -8875,The Two Towers,John Ronald Reuel Tolkien,2007,HarperCollins UK,4.64,The second volume in The Lord of the Rings\, This title is also available as a film. -4977,The Unvanquished,William Faulkner,2011,Vintage,3.50,Set in Mississippi during the Civil War and Reconstruction\, THE UNVANQUISHED focuses on the Sartoris family\, who\, with their code of personal responsibility and courage\, stand for the best of the Old South's traditions. -4382,The Wolves of Witchmaker,Carole Guinane,2001,iUniverse,5.00,Polly Lavender is mysteriously lured onto Witchmaker's grounds along with her best friends Tony Rico\, Gracie Reene\, and Zeus\, the wolf they rescued as a pup. The three must quickly learn to master the art of magic because they have been chosen to lead Witchmaker Prep against a threat that has grim consequences. -7912,The Word For World is Forest,Ursula K. Le Guin,2015,Gollancz,4.22,When the inhabitants of a peaceful world are conquered by the bloodthirsty yumens\, their existence is irrevocably altered. Forced into servitude\, the Athsheans find themselves at the mercy of their brutal masters. Desperation causes the Athsheans\, led by Selver\, to retaliate against their captors\, abandoning their strictures against violence. But in defending their lives\, they have endangered the very foundations of their society. For every blow against the invaders is a blow to the humanity of the Athsheans. And once the killing starts\, there is no turning back. -1211,The brothers Karamazov,Fyodor Dostoevsky,2003,Bantam Classics,1.00,In 1880 Dostoevsky completed The Brothers Karamazov\, the literary effort for which he had been preparing all his life. Compelling\, profound\, complex\, it is the story of a patricide and of the four sons who each had a motive for murder: Dmitry\, the sensualist\, Ivan\, the intellectual\, Alyosha\, the mystic\, and twisted\, cunning Smerdyakov\, the bastard child. Frequently lurid\, nightmarish\, always brilliant\, the novel plunges the reader into a sordid love triangle\, a pathological obsession\, and a gripping courtroom drama. But throughout the whole\, Dostoevsky searhes for the truth--about man\, about life\, about the existence of God. A terrifying answer to man's eternal questions\, this monumental work remains the crowning achievement of perhaps the finest novelist of all time. From the Paperback edition. -8086,The grand inquisitor (Milestones of thought),Fyodor Dostoevsky,1981,A&C Black,4.09,Dostoevsky's portrayal of the Catholic Church during the Inquisition is a plea for the power of pure faith\, and a critique of the tyrannies of institutionalized religion. This is an except from the Brothers Karamazov which stands alone as a statement of philiosophy and a warning about the surrender of freedom for the sake of comfort. -8077,The unvanquished,William Faulkner,2011,Vintage,4.00,Set in Mississippi during the Civil War and Reconstruction\, THE UNVANQUISHED focuses on the Sartoris family\, who\, with their code of personal responsibility and courage\, stand for the best of the Old South's traditions. -8480,The wind's twelve quarters: Short stories,Ursula K. Le Guin,2017,HarperCollins,5.00,The recipient of numerous literary prizes\, including the National Book Award\, the Kafka Award\, and the Pushcart Prize\, Ursula K. Le Guin is renowned for her lyrical writing\, rich characters\, and diverse worlds. The Wind's Twelve Quarters collects seventeen powerful stories\, each with an introduction by the author\, ranging from fantasy to intriguing scientific concepts\, from medieval settings to the future. Including an insightful foreword by Le Guin\, describing her experience\, her inspirations\, and her approach to writing\, this stunning collection explores human values\, relationships\, and survival\, and showcases the myriad talents of one of the most provocative writers of our time. -2847,To Love A Dark Stranger (Lovegram Historical Romance),Colleen Faulkner,1997,Zebra Books,5.00,Bestselling author Colleen Faulkner's tumultuous saga of royal intrigue and forbidden desire sweeps from the magnificent estates of the aristocracy to the shadowy streets of London to King Charles II's glittering Restoration court. -3293,Universe by Design,Danny Faulkner,2004,New Leaf Publishing Group,4.25,Views the stars and planets from a creationist standpoint\, addresses common misconceptions and difficulties about relativity and cosmology\, and discusses problems with the big bang theory with many analogies\, examples\, diagrams\, and illustrations. Original. -5327,War and Peace,Leo Tolstoy,2016,Lulu.com,3.84,Covering the period from the French invasion under Napoleon into Russia. Although not covering solely the war itself\, the serialized novel does cover the effects the war had on Russian society from the common person right up to the Tsar himself. The book starts to move more to a philosophical consideration on war and peace near the end making the book as a whole an important piece of literature. -4536,War and Peace (Signet Classics),[Leo Tolstoy, Pat Conroy, John Hockenberry],2012,Signet Classics,4.75,Presents the classical epic of the Napoleonic Wars and their effects on four Russian families. -9032,War and Peace: A Novel (6 Volumes),Tolstoy Leo,2013,Hardpress Publishing,3.81,Unlike some other reproductions of classic texts (1) We have not used OCR(Optical Character Recognition)\, as this leads to bad quality books with introduced typos. (2) In books where there are images such as portraits\, maps\, sketches etc We have endeavoured to keep the quality of these images\, so they represent accurately the original artefact. Although occasionally there may be certain imperfections with these old texts\, we feel they deserve to be made available for future generations to enjoy. -5119,William Faulkner,William Faulkner,2011,Vintage,4.00,This invaluable volume\, which has been republished to commemorate the one-hundredth anniversary of Faulkner's birth\, contains some of the greatest short fiction by a writer who defined the course of American literature. Its forty-five stories fall into three categories: those not included in Faulkner's earlier collections\, previously unpublished short fiction\, and stories that were later expanded into such novels as The Unvanquished\, The Hamlet\, and Go Down\, Moses. With its Introduction and extensive notes by the biographer Joseph Blotner\, Uncollected Stories of William Faulkner is an essential addition to its author's canon--as well as a book of some of the most haunting\, harrowing\, and atmospheric short fiction written in the twentieth century. -8615,Winter notes on summer impressions,Fyodor Dostoevsky,2018,Alma Books,4.75,In June 1862\, Dostoevsky left Petersburg on his first excursion to Western Europe. Ostensibly making the trip to consult Western specialists about his epilepsy\, he also wished to see first-hand the source of the Western ideas he believed were corrupting Russia. Over the course of his journey he visited a number of major cities\, including Berlin\, Paris\, London\, Florence\, Milan and Vienna.His record of the trip\, Winter Notes on Summer Impressions - first published in the February 1863 issue of Vremya\, the periodical he edited - is the chrysalis out of which many elements of his later masterpieces developed. -6478,Woman-The Full Story: A Dynamic Celebration of Freedoms,Michele Guinness,2003,Zondervan,5.00,What does it mean to be a woman today? What have women inherited from their radical\, risk-taking sisters of the past? And how does God view this half of humanity? Michele Guinness invites us on an adventure of discovery\, exploring the biblical texts\, the annals of history and the experiences of women today in search of the challenges and achievements\, failures and joys\, of women throughout the ages. -8678,Worlds of Exile and Illusion: Three Complete Novels of the Hainish Series in One Volume--Rocannon's World\, Planet of Exile\, City of Illusions,Ursula K. Le Guin,2016,Orb Books,4.41,Worlds of Exile and Illusion contains three novels in the Hainish Series from Ursula K. Le Guin\, one of the greatest science fiction writers and many times the winner of the Hugo and Nebula Awards. Her career as a novelist was launched by the three novels contained here. These books\, Rocannon's World\, Planet of Exile\, and City of Illusions\, are set in the same universe as Le Guin's groundbreaking classic\, The Left Hand of Darkness. At the Publisher's request\, this title is being sold without Digital Rights Management Software (DRM) applied. +_id:keyword,book_no:keyword,title:text,author:text,year:integer,publisher:text,ratings:float,description:text +0,2924,A Gentle Creature and Other Stories: White Nights\, A Gentle Creature\, and The Dream of a Ridiculous Man (The World's Classics),[Fyodor Dostoevsky, Alan Myers, W. J. Leatherbarrow],2009,Oxford Paperbacks,4.00,In these stories Dostoevsky explores both the figure of the dreamer divorced from reality and also his own ambiguous attitude to utopianism\, themes central to many of his great novels. This new translation captures the power and lyricism of Dostoevsky's writing\, while the introduction examines the stories in relation to one another and to his novels. +1,7670,A Middle English Reader and Vocabulary,[Kenneth Sisam, J. R. R. Tolkien],2011,Courier Corporation,4.33,This highly respected anthology of medieval English literature features poetry\, prose and popular tales from Arthurian legend and classical mythology. Includes notes on each extract\, appendices\, and an extensive glossary by J. R. R. Tolkien. +2,7381,A Psychic in the Heartland: The Extraordinary Experiences of a Small Town Doctor,Bettilu Stein Faulkner,2003,Red Wheel/Weiser,4.50,The true story of a small-town doctor destined to live his life along two paths: one as a successful physician\, the other as a psychic with ever more interesting adventures. Experiencing a wide range of spiritual phenomena\, Dr. Riblet Hout learned about the connection between the healer and the healed\, our individual missions on earth\, free will\, and our relationship with God. He also paints a vivid picture of life on the other side as well as the moment of transition from physical life to afterlife. +3,2883,A Summer of Faulkner: As I Lay Dying/The Sound and the Fury/Light in August (Oprah's Book Club),William Faulkner,2005,Vintage Books,3.89,Presents three novels\, including As I Lay Dying\, in which the Bundren family journeys across Mississippi to bury their mother\, The Sound and the Fury\, in which Caddy Compson's story is narrated by her three brothers\, and Light in August\, in which th +4,4023,A Tolkien Compass: Including J. R. R. Tolkien's Guide to the Names in The Lord of the Rings,[Walter Scheps, Agnes Perkins, Charles Adolph Huttar, John Ronald Reuel Tolkien],1975,Open Court Publishing,4.67,The structure\, content\, and character of Tolkien's The Hobbit and The Lord of the Rings are dealt with in ten critical essays. +5,2382,A Wizard of Earthsea (Earthsea Trilogy Ser.),Ursula K. Le Guin,1991,Atheneum Books for Young Readers,4.01,A boy grows to manhood while attempting to subdue the evil he unleashed on the world as an apprentice to the Master Wizard. +6,7541,A Writer's Diary (Volume 1: 1873-1876),Fyodor Dostoevsky,1997,Northwestern University Press,4.50,Winner of the AATSEEL Outstanding Translation Award This is the first paperback edition of the complete collection of writings that has been called Dostoevsky's boldest experiment with literary form\, it is a uniquely encyclopedic forum of fictional and nonfictional genres. The Diary's radical format was matched by the extreme range of its contents. In a single frame it incorporated an astonishing variety of material: short stories\, humorous sketches\, reports on sensational crimes\, historical predictions\, portraits of famous people\, autobiographical pieces\, and plans for stories\, some of which were never written while others appeared in the Diary itself. +7,7400,Anna Karenina: Television Tie-In Edition (Signet classics),[Leo Tolstoy, SBP Editors],2019,Samaira Book Publishers,4.45,The Russian novelist and moral philosopher Leo Tolstoy (1828-1910) ranks as one of the world s great writers\, and his 'War and Peace' has been called the greatest novel ever written. But during his long lifetime\, Tolstoy also wrote enough shorter works to fill many volumes. The message in all his stories is presented with such humour that the reader hardly realises that it is strongly didactic. These stories give a snapshot of Russia and its people in the late nineteenth century. +8,4917,Autumn of the Patriarch,Gabriel Garcia Marquez,2014,Penguin UK,4.33,Gabriel Garcia Marquez\, winner of the 1982 Nobel Prize for Literature and author of One Hundred Years of Solitude\, explores the loneliness of power in Autumn of the Patriarch. 'Over the weekend the vultures got into the presidential palace by pecking through the screens on the balcony windows and the flapping of their wings stirred up the stagnant time inside' As the citizens of an unnamed Caribbean nation creep through dusty corridors in search of their tyrannical leader\, they cannot comprehend that the frail and withered man lying dead on the floor can be the self-styled General of the Universe. Their arrogant\, manically violent leader\, known for serving up traitors to dinner guests and drowning young children at sea\, can surely not die the humiliating death of a mere mortal? Tracing the demands of a man whose egocentric excesses mask the loneliness of isolation and whose lies have become so ingrained that they are indistinguishable from truth\, Marquez has created a fantastical portrait of despotism that rings with an air of reality. 'Delights with its quirky humanity and black humour and impresses by its total originality' Vogue 'Captures perfectly the moral squalor and political paralysis that enshrouds a society awaiting the death of a long-term dictator' Guardian 'Marquez writes in this lyrical\, magical language that no-one else can do' Salman Rushdie +9,9896,Barn burning (A tale blazer book),William Faulkner,1979,Perfection Learning,3.50,Reprinted from Collected Stories of William Faulkner\, by permission of Random House\, Inc. +10,9607,Beowolf: The monsters and the critics,John Ronald Reuel Tolkien,1997,HarperCollins UK,4.12,A collection of seven essays by J.R.R. Tolkien arising out of Tolkien's work in medieval literature +11,1985,Brothers Karamazov,Fyodor Dostoevsky,2015,First Avenue Editions,5.00,Four brothers reunite in their hometown in Russia. The murder of their father forces the brothers to question their beliefs about each other\, religion\, and morality. +12,2713,Collected Stories of William Faulkner,William Faulkner,1995,Vintage,4.53,A collection of short stories focuses on the people of rural Mississippi +13,2464,Conversations with Kurt Vonnegut (Literary Conversations),Kurt Vonnegut,1988,Univ. Press of Mississippi,4.40,Gathers interviews with Vonnegut from each period of his career and offers a brief profile of his life and accomplishments +14,8534,Crime and Punishment (Oxford World's Classics),Fyodor Dostoevsky,2017,Oxford University Press,4.38,'One death\, in exchange for thousands of lives - it's simple arithmetic!' A new translation of Dostoevsky's epic masterpiece\, Crime and Punishment (1866). The impoverished student Raskolnikov decides to free himself from debt by killing an old moneylender\, an act he sees as elevating himself above conventional morality. Like Napoleon he will assert his will and his crime will be justified by its elimination of 'vermin' for the sake of the greater good. But Raskolnikov is torn apart by fear\, guilt\, and a growing conscience under the influence of his love for Sonya. Meanwhile the police detective Porfiry is on his trial. It is a powerfully psychological novel\, in which the St Petersburg setting\, Dostoevsky's own circumstances\, and contemporary social problems all play their part. +15,8605,Dead Souls,Nikolai Gogol,1997,Vintage,4.28,Chichikov\, an amusing and often confused schemer\, buys deceased serfs' names from landholders' poll tax lists hoping to mortgage them for profit +16,6970,Domestic Goddesses,Edith Vonnegut,1998,Pomegranate,4.67,In this immensely charming and insightful book\, artist Edith Vonnegut takes issue with traditional art imagery in which women are shown as weak and helpless. Through twenty-seven of her own paintings interspersed with her text\, she poignantly -- and humorously -- illustrates her maxim that the lives of mothers and homemakers are filled with endless challenges and vital decisions that should be portrayed with the dignity they deserve. In Vonnegut's paintings\, one woman bravely blocks the sun from harming a child (Sun Block) while another vacuums the stairs with angelic figures singing her praises (Electrolux). In contrasting her own Domestic Goddesses with the diaphanous women of classical art (seven paintings by masters such as Titian and Botticelli are included)\, she 'expresses the importance of traditional roles of women so cleverly and with such joy that her message and images will be forever emblazoned on our collective psyche. +17,4814,El Coronel No Tiene Quien Le Escriba / No One Writes to the Colonel (Spanish Edition),Gabriel Garcia Marquez,2005,Harper Collins,4.45,Written with compassionate realism and wit\, the stories in this mesmerizing collection depict the disparities of town and village life in South America\, of the frightfully poor and outrageously rich\, of memories and illusions\, and of lost opportunities and present joys. +18,4636,FINAL WITNESS,Simon Tolkien,2004,Random House Digital\, Inc.,3.94,The murder of Lady Anne Robinson by two intruders causes a schism in the victim's family when her son convinces police that his father's beautiful personal assistant hired the killers\, while his father\, the British minister of defense\, refuses to believe his son and marries the accused. A first novel. Reprint. +19,2936,Fellowship of the Ring 2ND Edition,John Ronald Reuel Tolkien,2008,HarperCollins UK,4.43,Sauron\, the Dark Lord\, has gathered to him all the Rings of Power - the means by which he intends to rule Middle-earth. All he lacks in his plans for dominion is the One Ring - the ring that rules them all - which has fallen into the hands of the hobbit\, Bilbo Baggins. In a sleepy village in the Shire\, young Frodo Baggins finds himself faced with an immense task\, as his elderly cousin Bilbo entrusts the Ring to his care. Frodo must leave his home and make a perilous journey across Middle-earth to the Cracks of Doom\, there to destroy the Ring and foil the Dark Lord in his evil purpose. JRR Tolkien's great work of imaginative fiction has been labelled both a heroic romance and a classic fantasy fiction. By turns comic and homely\, epic and diabolic\, the narrative moves through countless changes of scene and character in an imaginary world which is totally convincing in its detail. +20,8956,GOD BLESS YOU MR. ROSEWATER : Or Pearls Before Swine,Kurt Vonnegut,1970,New York : Dell,4.00,A lawyer schemes to gain control of a large fortune by having the present claimant declared insane. +21,6818,Hadji Murad,Leo Tolstoy,2022,Hachette UK,3.88,'How truth thickens and deepens when it migrates from didactic fable to the raw experience of a visceral awakening is one of the thrills of Tolstoy's stories' Sharon Cameron in her preface to Hadji Murad and Other Stories This\, the third volume of Tolstoy's shorter fiction concentrates on his later stories\, including one of his greatest\, 'Hadji Murad'. In the stark form of homily that shapes these later works\, life considered as one's own has no rational meaning. From the chain of events that follows in the wake of two schoolboys' deception in 'The Forged Coupon' to the disillusionment of the narrator in 'After the Ball' we see\, in Virginia Woolf's observation\, that Tolstoy puts at the centre of his writing one 'who gathers into himself all experience\, turns the world round between his fingers\, and never ceases to ask\, even as he enjoys it\, what is the meaning of it'. The riverrun edition reissues the translation of Louise and Aylmer Maude\, whose influential versions of Tolstoy first brought his work to a wide readership in English. +22,3950,Hocus,Kurt Vonnegut,1997,Penguin,4.67,Tarkington College\, a small\, exclusive college in upstate New York\, is turned upside down when ten thousand prisoners from the maximum security prison across Lake Mohiga break out and head for the college +23,5404,Intruder in the dust,William Faulkner,2011,Vintage,3.18,A classic Faulkner novel which explores the lives of a family of characters in the South. An aging black who has long refused to adopt the black's traditionally servile attitude is wrongfully accused of murdering a white man. +24,5578,Intruder in the dust: A novel,William Faulkner,1991,Vintage,3.18,Dramatizes the events that surround the murder of a white man in a volatile Southern community +25,6380,La hojarasca (Spanish Edition),Gabriel Garcia Marquez,1979,Harper Collins,3.75,Translated from the Spanish by Gregory Rabassa +26,5335,Letters of J R R Tolkien,J.R.R. Tolkien,2014,HarperCollins,4.70,This collection will entertain all who appreciate the art of masterful letter writing. The Letters of J.R.R Tolkien sheds much light on Tolkien's creative genius and grand design for the creation of a whole new world: Middle-earth. Featuring a radically expanded index\, this volume provides a valuable research tool for all fans wishing to trace the evolution of THE HOBBIT and THE LORD OF THE RINGS. +27,3870,My First 100 Words in Spanish/English (My First 100 Words Pull-Tab Book),Keith Faulkner,1998,Libros Para Ninos,4.50,Learning a foreign language has never been this much fun! Just pull the sturdy tabs and change the words under the pictures from English to Spanish and back again to English! +28,4502,O'Brian's Bride,Colleen Faulkner,1995,Zebra Books,5.00,Abandoning her pampered English life to marry a man in the American colonies\, Elizabeth finds her new world shattered when her husband is killed in an accident\, leaving her in charge of a business on the untamed frontier. Original. +29,7635,Oliphaunt (Beastly Verse),J. R. R. Tolkien,1989,Contemporary Books,2.50,A poem in which an elephant describes himself and his way of life. On board pages. +30,3254,Pearl and Sir Orfeo,[John Ronald Reuel Tolkien, Christopher Tolkien],1995,Harpercollins Pub Limited,5.00,Three epic poems from 14th century England speak of life during the age of chivalry. Translated from medieval English. +31,3677,Planet of Exile,Ursula K. Le Guin,1979,Orion,4.20,PLAYAWAY: An alliance between the powerful Tevars and the brown-skinned\, clairvoyant Farbons must take place if the two colonies are to withstand the fierce attack of the nomadic tribes from the north of the planet Eltanin. +32,4289,Poems from the Hobbit,J R R Tolkien,1999,HarperCollins Publishers,4.00,A collection of J.R.R. Tolkien's Hobbit poems in a miniature hardback volume complete with illustrations by Tolkien himself. Far over misty mountains cold To dungeons deep and caverns old We must away ere break of day To seek the pale enchanted gold. J.R.R. Tolkien's acclaimed The Hobbit contains 12 poems which are themselves masterpieces of writing. This miniature book\, illustrated with 30 of Tolkien's own paintings and drawings from the book -- some quite rare and all in full colour -- includes all the poems\, plus Gollum's eight riddles in verse\, and will be a perfect keepsake for lovers of The Hobbit and of accomplished poetry. +33,6151,Pop! Went Another Balloon: A Magical Counting Storybook (Magical Counting Storybooks),[Keith Faulkner, Rory Tyger],2003,Dutton Childrens Books,5.00,Toby the turtle goes from in-line skates to a motorcycle to a rocketship with a handful of balloons that pop\, one by one\, along the way. +34,3535,Rainbow's End: A Magical Story and Moneybox,[Keith Faulkner, Beverlie Manson],2003,Barrons Juveniles,4.00,In this combination picture storybook and coin bank\, the unusual front cover shows an illustration from the story that's embellished with five transparent plastic windows. Opening the book\, children will find a story about a poor little ballerina who is crying because her dancing shoes are worn and she has no money to replace them. Full color. Consumable. +35,8423,Raising Faithful Kids in a Fast-Paced World,Paul Faulkner,1995,Howard Publishing Company,5.00,To find help for struggling parents\, Dr. Paul Faulkner--renowned family counselor and popular speaker--interviewed 30 successful families who have managed to raise faithful kids while also maintaining demanding careers. The invaluable strategies and methods he gleaned are now available in this powerful book delivered in Dr. Faulkner's warm\, humorous style. +36,1463,Realms of Tolkien: Images of Middle-earth,J. R. R. Tolkien,1997,HarperCollins Publishers,4.00,Twenty new and familiar Tolkien artists are represented in this fabulous volume\, breathing an extraordinary variety of life into 58 different scenes\, each of which is accompanied by appropriate passage from The Hobbit and The Lord of the Rings and The Silmarillion +37,6323,Resurrection (The Penguin classics),Leo Tolstoy,2009,Penguin,3.25,Leo Tolstoy's last completed novel\, Resurrection is an intimate\, psychological tale of guilt\, anger and forgiveness Serving on the jury at a murder trial\, Prince Dmitri Nekhlyudov is devastated when he sees the prisoner - Katyusha\, a young maid he seduced and abandoned years before. As Dmitri faces the consequences of his actions\, he decides to give up his life of wealth and luxury to devote himself to rescuing Katyusha\, even if it means following her into exile in Siberia. But can a man truly find redemption by saving another person? Tolstoy's most controversial novel\, Resurrection (1899) is a scathing indictment of injustice\, corruption and hypocrisy at all levels of society. Creating a vast panorama of Russian life\, from peasants to aristocrats\, bureaucrats to convicts\, it reveals Tolstoy's magnificent storytelling powers. Anthony Briggs' superb new translation preserves Tolstoy's gripping realism and satirical humour. In his introduction\, Briggs discusses the true story behind Resurrection\, Tolstoy's political and religious reasons for writing the novel\, his gift for characterization and the compelling psychological portrait of Dmitri. This edition also includes a chronology\, notes and a summary of chapters. For more than seventy years\, Penguin has been the leading publisher of classic literature in the English-speaking world. With more than 1\,700 titles\, Penguin Classics represents a global bookshelf of the best works throughout history and across genres and disciplines. Readers trust the series to provide authoritative texts enhanced by introductions and notes by distinguished scholars and contemporary authors\, as well as up-to-date translations by award-winning translators. +38,2714,Return of the King Being the Third Part of The Lord of the Rings,J. R. R. Tolkien,2012,HarperCollins,4.60,Concluding the story begun in The Hobbit\, this is the final part of Tolkien s epic masterpiece\, The Lord of the Rings\, featuring an exclusive cover image from the film\, the definitive text\, and a detailed map of Middle-earth. The armies of the Dark Lord Sauron are massing as his evil shadow spreads ever wider. Men\, Dwarves\, Elves and Ents unite forces to do battle agains the Dark. Meanwhile\, Frodo and Sam struggle further into Mordor in their heroic quest to destroy the One Ring. The devastating conclusion of J.R.R. Tolkien s classic tale of magic and adventure\, begun in The Fellowship of the Ring and The Two Towers\, features the definitive edition of the text and includes the Appendices and a revised Index in full. To celebrate the release of the first of Peter Jackson s two-part film adaptation of The Hobbit\, THE HOBBIT: AN UNEXPECTED JOURNEY\, this third part of The Lord of the Rings is available for a limited time with an exclusive cover image from Peter Jackson s award-winning trilogy. +39,7350,Return of the Shadow,[John Ronald Reuel Tolkien, Christopher Tolkien],2000,Mariner Books,5.00,In this sixth volume of The History of Middle-earth the story reaches The Lord of the Rings. In The Return of the Shadow (an abandoned title for the first volume) Christopher Tolkien describes\, with full citation of the earliest notes\, outline plans\, and narrative drafts\, the intricate evolution of The Fellowship of the Ring and the gradual emergence of the conceptions that transformed what J.R.R. Tolkien for long believed would be a far shorter book\, 'a sequel to The Hobbit'. The enlargement of Bilbo's 'magic ring' into the supremely potent and dangerous Ruling Ring of the Dark Lord is traced and the precise moment is seen when\, in an astonishing and unforeseen leap in the earliest narrative\, a Black Rider first rode into the Shire\, his significance still unknown. The character of the hobbit called Trotter (afterwards Strider or Aragorn) is developed while his indentity remains an absolute puzzle\, and the suspicion only very slowly becomes certainty that he must after all be a Man. The hobbits\, Frodo's companions\, undergo intricate permutations of name and personality\, and other major figures appear in strange modes: a sinister Treebeard\, in league with the Enemy\, a ferocious and malevolent Farmer Maggot. The story in this book ends at the point where J.R.R. Tolkien halted in the story for a long time\, as the Company of the Ring\, still lacking Legolas and Gimli\, stood before the tomb of Balin in the Mines of Moria. The Return of the Shadow is illustrated with reproductions of the first maps and notable pages from the earliest manuscripts. +40,6760,Roverandom,J. R. R. Tolkien,1999,Mariner Books,4.38,Rover\, a dog who has been turned into a toy dog encounters rival wizards and experiences various adventures on the moon with giant spiders\, dragon moths\, and the Great White Dragon. By the author of The Hobbit. Reprint. +41,8873,Searoad: Chronicles of Klatsand,Ursula K. Le Guin,2004,Shambhala Publications,5.00,A series of interlinking tales and a novella by the author of the Earthsea trilogy portrays the triumphs and struggles of several generations of women who independently control Klatsand\, a small resort town on the Oregon coast. Reprint. +42,2378,Selected Letters of Lucretia Coffin Mott (Women in American History),[Lucretia Mott, Holly Byers Ochoa, Carol Faulkner],2002,University of Illinois Press,5.00,Dedicated to reform of almost every kind - temperance\, peace\, equal rights\, woman suffrage\, nonresistance\, and the abolition of slavery - Mott viewed women's rights as only one element of a broad-based reform agenda for American society. +43,1502,Selected Passages from Correspondence with Friends,Nikolai Vasilevich Gogol,2009,Vanderbilt University Press,4.00,Nikolai Gogol wrote some letters to his friends\, none of which were a nose of high rank. Many are reproduced here (the letters\, not noses). +44,5996,Smith of Wooten Manor & Farmer Giles of Ham,John Ronald Reuel Tolkien,1969,Del Rey,4.91,Two bewitching fantasies by J.R.R. Tolkien\, beloved author of THE HOBBIT. In SMITH OF WOOTTON MAJOR\, Tolkien explores the gift of fantasy\, and what it means to the life and character of the man who receives it. And FARMER GILES OF HAM tells a delightfully ribald mock-heroic tale\, where a dragon who invades a town refuses to fight\, and a farmer is chosen to slay him. +45,2301,Smith of Wootton Major & Farmer Giles of Ham,John Ronald Reuel Tolkien,1969,Del Rey,5.00,Two bewitching fantasies by J.R.R. Tolkien\, beloved author of THE HOBBIT. In SMITH OF WOOTTON MAJOR\, Tolkien explores the gift of fantasy\, and what it means to the life and character of the man who receives it. And FARMER GILES OF HAM tells a delightfully ribald mock-heroic tale\, where a dragon who invades a town refuses to fight\, and a farmer is chosen to slay him. +46,2236,Steering the Craft,Ursula K. Le Guin,2015,Houghton Mifflin Harcourt,4.73,A revised and updated guide to the essentials of a writer's craft\, presented by a brilliant practitioner of the art Completely revised and rewritten to address the challenges and opportunities of the modern era\, this handbook is a short\, deceptively simple guide to the craft of writing. Le Guin lays out ten chapters that address the most fundamental components of narrative\, from the sound of language to sentence construction to point of view. Each chapter combines illustrative examples from the global canon with Le Guin's own witty commentary and an exercise that the writer can do solo or in a group. She also offers a comprehensive guide to working in writing groups\, both actual and online. Masterly and concise\, Steering the Craft deserves a place on every writer's shelf. +47,4724,THE UNVANQUISHED,William Faulkner,2011,Vintage,3.50,Set in Mississippi during the Civil War and Reconstruction\, THE UNVANQUISHED focuses on the Sartoris family\, who\, with their code of personal responsibility and courage\, stand for the best of the Old South's traditions. +48,5948,That We Are Gentle Creatures,Fyodor Dostoevsky,2009,OUP Oxford,4.33,In the stories in this volume Dostoevsky explores both the figure of the dreamer divorced from reality and also his own ambiguous attitude to utopianism\, themes central to many of his great novels. In White Nights the apparent idyll of the dreamer's romantic fantasies disguises profound loneliness and estrangement from 'living life'. Despite his sentimental friendship with Nastenka\, his final withdrawal into the world of the imagination anticipates the retreat into the 'underground' of many of Dostoevsky's later intellectual heroes. A Gentle Creature and The Dream of a Ridiculous Man show how such withdrawal from reality can end in spiritual desolation and moral indifference and how\, in Dostoevsky's view\, the tragedy of the alienated individual can be resolved only by the rediscovery of a sense of compassion and responsibility towards fellow human beings. This new translation captures the power and lyricism of Dostoevsky's writing\, while the introduction examines the stories in relation to one another and to his novels. ABOUT THE SERIES: For over 100 years Oxford World's Classics has made available the widest range of literature from around the globe. Each affordable volume reflects Oxford's commitment to scholarship\, providing the most accurate text plus a wealth of other valuable features\, including expert introductions by leading authorities\, helpful notes to clarify the text\, up-to-date bibliographies for further study\, and much more. +49,1937,The Best Short Stories of Dostoevsky (Modern Library),Fyodor Dostoevsky,2012,Modern Library,4.33,This collection\, unique to the Modern Library\, gathers seven of Dostoevsky's key works and shows him to be equally adept at the short story as with the novel. Exploring many of the same themes as in his longer works\, these small masterpieces move from the tender and romantic White Nights\, an archetypal nineteenth-century morality tale of pathos and loss\, to the famous Notes from the Underground\, a story of guilt\, ineffectiveness\, and uncompromising cynicism\, and the first major work of existential literature. Among Dostoevsky's prototypical characters is Yemelyan in The Honest Thief\, whose tragedy turns on an inability to resist crime. Presented in chronological order\, in David Magarshack's celebrated translation\, this is the definitive edition of Dostoevsky's best stories. +50,2776,The Devil and Other Stories (Oxford World's Classics),Leo Tolstoy,2003,OUP Oxford,5.00,'It is impossible to explain why Yevgeny chose Liza Annenskaya\, as it is always impossible to explain why a man chooses this and not that woman.' This collection of eleven stories spans virtually the whole of Tolstoy's creative life. While each is unique in form\, as a group they are representative of his style\, and touch on the central themes that surface in War and Peace and Anna Karenina. Stories as different as 'The Snowstorm'\, 'Lucerne'\, 'The Diary of a Madman'\, and 'The Devil' are grounded in autobiographical experience. They deal with journeys of self-discovery and the moral and religious questioning that characterizes Tolstoy's works of criticism and philosophy. 'Strider' and 'Father Sergy'\, as well as reflecting Tolstoy's own experiences\, also reveal profound psychological insights. These stories range over much of the Russian world of the nineteenth century\, from the nobility to the peasantry\, the military to the clergy\, from merchants and cobblers to a horse and a tree. Together they present a fascinating picture of Tolstoy's skill and artistry. ABOUT THE SERIES: For over 100 years Oxford World's Classics has made available the widest range of literature from around the globe. Each affordable volume reflects Oxford's commitment to scholarship\, providing the most accurate text plus a wealth of other valuable features\, including expert introductions by leading authorities\, helpful notes to clarify the text\, up-to-date bibliographies for further study\, and much more. +51,4231,The Dispossessed,Ursula K. Le Guin,1974,Harpercollins,4.26,Frequently reissued with the same ISBN\, but with slightly differing bibliographical details. +52,7480,The Hobbit,J. R. R. Tolkien,2012,Mariner Books,4.64,Celebrating 75 years of one of the world's most treasured classics with an all new trade paperback edition. Repackaged with new cover art. 500\,000 first printing. +53,6405,The Hobbit or There and Back Again,J. R. R. Tolkien,2012,Mariner Books,4.63,Celebrating 75 years of one of the world's most treasured classics with an all new trade paperback edition. Repackaged with new cover art. 500\,000 first printing. +54,2540,The Inspector General (Language - Russian) (Russian Edition),[Nicolai Gogol, Thomas Seltzer],2014,CreateSpace,3.50,The Inspector-General is a national institution. To place a purely literary valuation upon it and call it the greatest of Russian comedies would not convey the significance of its position either in Russian literature or in Russian life itself. There is no other single work in the modern literature of any language that carries with it the wealth of associations which the Inspector-General does to the educated Russian. +55,2951,The Insulted and Injured,Fyodor Dostoevsky,2011,Wm. B. Eerdmans Publishing,4.00,The Insulted and Injured\, which came out in 1861\, was Fyodor Dostoevsky's first major work of fiction after his Siberian exile and the first of the long novels that made him famous. Set in nineteenth-century Petersburg\, this gripping novel features a vividly drawn set of characters - including Vanya (Dostoevsky's semi-autobiographical hero)\, Natasha (the woman he loves)\, and Alyosha (Natasha's aristocratic lover) - all suffering from the cruelly selfish machinations of Alyosha's father\, the dark and powerful Prince Valkovsky. Boris Jakim's fresh English-language rendering of this gem in the Doestoevsky canon is both more colorful and more accurate than any earlier translation. --from back cover. +56,2130,The J. R. R. Tolkien Audio Collection,[John Ronald Reuel Tolkien, Christopher Tolkien],2002,HarperCollins Publishers,4.89,For generations\, J R R Tolkien's words have brought to thrilling life a world of hobbits\, magic\, and historic myth\, woken from its foggy slumber within our minds. Here\, he tells the tales in his own voice. +57,9801,The Karamazov Brothers (Oxford World's Classics),Fyodor Dostoevsky,2008,Oxford University Press,4.40,A remarkable work showing the author's power to depict Russian character and his understanding of human nature. Driven by intense\, uncontrollable emotions of rage and revenge\, the four Karamazov brothers all become involved in the brutal murder of their despicable father. +58,5469,The Lays of Beleriand,[John Ronald Reuel Tolkien, Christopher Tolkien],2002,Harpercollins Pub Limited,4.42,The third volume that contains the early myths and legends which led to the writing of Tolkien's epic tale of war\, The Silmarillion. This\, the third volume of The History of Middle-earth\, gives us a priviledged insight into the creation of the mythology of Middle-earth\, through the alliterative verse tales of two of the most crucial stories in Tolkien's world -- those of Turien and Luthien. The first of the poems is the unpublished Lay of The Children of Hurin\, narrating on a grand scale the tragedy of Turin Turambar. The second is the moving Lay of Leithian\, the chief source of the tale of Beren and Luthien in The Silmarillion\, telling of the Quest of the Silmaril and the encounter with Morgoth in his subterranean fortress. Accompanying the poems are commentaries on the evolution of the history of the Elder Days. Also included is the notable criticism of The Lay of The Leithian by CS Lewis\, who read the poem in 1929. +59,2675,The Lord of the Rings - Boxed Set,J.R.R. Tolkien,2012,HarperCollins,4.56,This beautiful gift edition of The Hobbit\, J.R.R. Tolkien's classic prelude to his Lord of the Rings trilogy\, features cover art\, illustrations\, and watercolor paintings by the artist Alan Lee. Bilbo Baggins is a hobbit who enjoys a comfortable\, unambitious life\, rarely traveling any farther than his pantry or cellar. But his contentment is disturbed when the wizard Gandalf and a company of dwarves arrive on his doorstep one day to whisk him away on an adventure. They have launched a plot to raid the treasure hoard guarded by Smaug the Magnificent\, a large and very dangerous dragon. Bilbo reluctantly joins their quest\, unaware that on his journey to the Lonely Mountain he will encounter both a magic ring and a frightening creature known as Gollum. Written for J.R.R. Tolkien's own children\, The Hobbit has sold many millions of copies worldwide and established itself as a modern classic. +60,7140,The Lord of the Rings Poster Collection: Six Paintings by Alan Lee (No. 1),[J. R. R. Tolkien, Alan Lee],2002,HarperSport,4.75,A selection of stunning poster paintings from the celebrated Tolkien artist Alan Lee - the man behind many of the striking images from The Lord of The Rings movie. The 50 paintings contained within the centenary edition of The Lord of the Rings in 1992 have themselves become classics and Alan Lee's interpretations are hailed as the most faithful to Tolkien's own vision. This new poster collection\, a perfect complement to volume one\, reproduces six more of the most popular paintings from the book in a format suitable either for hanging as posters or mounting and framing. +61,5127,The Overcoat, Nikolai Gogol,1992,Courier Corporation,3.75,Four short stories include a satirical tale of Russian bureaucrats and a portrayal of an elderly couple living in the secluded countryside. +62,8875,The Two Towers,John Ronald Reuel Tolkien,2007,HarperCollins UK,4.64,The second volume in The Lord of the Rings\, This title is also available as a film. +63,4977,The Unvanquished,William Faulkner,2011,Vintage,3.50,Set in Mississippi during the Civil War and Reconstruction\, THE UNVANQUISHED focuses on the Sartoris family\, who\, with their code of personal responsibility and courage\, stand for the best of the Old South's traditions. +64,4382,The Wolves of Witchmaker,Carole Guinane,2001,iUniverse,5.00,Polly Lavender is mysteriously lured onto Witchmaker's grounds along with her best friends Tony Rico\, Gracie Reene\, and Zeus\, the wolf they rescued as a pup. The three must quickly learn to master the art of magic because they have been chosen to lead Witchmaker Prep against a threat that has grim consequences. +65,7912,The Word For World is Forest,Ursula K. Le Guin,2015,Gollancz,4.22,When the inhabitants of a peaceful world are conquered by the bloodthirsty yumens\, their existence is irrevocably altered. Forced into servitude\, the Athsheans find themselves at the mercy of their brutal masters. Desperation causes the Athsheans\, led by Selver\, to retaliate against their captors\, abandoning their strictures against violence. But in defending their lives\, they have endangered the very foundations of their society. For every blow against the invaders is a blow to the humanity of the Athsheans. And once the killing starts\, there is no turning back. +66,1211,The brothers Karamazov,Fyodor Dostoevsky,2003,Bantam Classics,1.00,In 1880 Dostoevsky completed The Brothers Karamazov\, the literary effort for which he had been preparing all his life. Compelling\, profound\, complex\, it is the story of a patricide and of the four sons who each had a motive for murder: Dmitry\, the sensualist\, Ivan\, the intellectual\, Alyosha\, the mystic\, and twisted\, cunning Smerdyakov\, the bastard child. Frequently lurid\, nightmarish\, always brilliant\, the novel plunges the reader into a sordid love triangle\, a pathological obsession\, and a gripping courtroom drama. But throughout the whole\, Dostoevsky searhes for the truth--about man\, about life\, about the existence of God. A terrifying answer to man's eternal questions\, this monumental work remains the crowning achievement of perhaps the finest novelist of all time. From the Paperback edition. +67,8086,The grand inquisitor (Milestones of thought),Fyodor Dostoevsky,1981,A&C Black,4.09,Dostoevsky's portrayal of the Catholic Church during the Inquisition is a plea for the power of pure faith\, and a critique of the tyrannies of institutionalized religion. This is an except from the Brothers Karamazov which stands alone as a statement of philiosophy and a warning about the surrender of freedom for the sake of comfort. +68,8077,The unvanquished,William Faulkner,2011,Vintage,4.00,Set in Mississippi during the Civil War and Reconstruction\, THE UNVANQUISHED focuses on the Sartoris family\, who\, with their code of personal responsibility and courage\, stand for the best of the Old South's traditions. +69,8480,The wind's twelve quarters: Short stories,Ursula K. Le Guin,2017,HarperCollins,5.00,The recipient of numerous literary prizes\, including the National Book Award\, the Kafka Award\, and the Pushcart Prize\, Ursula K. Le Guin is renowned for her lyrical writing\, rich characters\, and diverse worlds. The Wind's Twelve Quarters collects seventeen powerful stories\, each with an introduction by the author\, ranging from fantasy to intriguing scientific concepts\, from medieval settings to the future. Including an insightful foreword by Le Guin\, describing her experience\, her inspirations\, and her approach to writing\, this stunning collection explores human values\, relationships\, and survival\, and showcases the myriad talents of one of the most provocative writers of our time. +70,2847,To Love A Dark Stranger (Lovegram Historical Romance),Colleen Faulkner,1997,Zebra Books,5.00,Bestselling author Colleen Faulkner's tumultuous saga of royal intrigue and forbidden desire sweeps from the magnificent estates of the aristocracy to the shadowy streets of London to King Charles II's glittering Restoration court. +71,3293,Universe by Design,Danny Faulkner,2004,New Leaf Publishing Group,4.25,Views the stars and planets from a creationist standpoint\, addresses common misconceptions and difficulties about relativity and cosmology\, and discusses problems with the big bang theory with many analogies\, examples\, diagrams\, and illustrations. Original. +72,5327,War and Peace,Leo Tolstoy,2016,Lulu.com,3.84,Covering the period from the French invasion under Napoleon into Russia. Although not covering solely the war itself\, the serialized novel does cover the effects the war had on Russian society from the common person right up to the Tsar himself. The book starts to move more to a philosophical consideration on war and peace near the end making the book as a whole an important piece of literature. +73,4536,War and Peace (Signet Classics),[Leo Tolstoy, Pat Conroy, John Hockenberry],2012,Signet Classics,4.75,Presents the classical epic of the Napoleonic Wars and their effects on four Russian families. +74,9032,War and Peace: A Novel (6 Volumes),Tolstoy Leo,2013,Hardpress Publishing,3.81,Unlike some other reproductions of classic texts (1) We have not used OCR(Optical Character Recognition)\, as this leads to bad quality books with introduced typos. (2) In books where there are images such as portraits\, maps\, sketches etc We have endeavoured to keep the quality of these images\, so they represent accurately the original artefact. Although occasionally there may be certain imperfections with these old texts\, we feel they deserve to be made available for future generations to enjoy. +75,5119,William Faulkner,William Faulkner,2011,Vintage,4.00,This invaluable volume\, which has been republished to commemorate the one-hundredth anniversary of Faulkner's birth\, contains some of the greatest short fiction by a writer who defined the course of American literature. Its forty-five stories fall into three categories: those not included in Faulkner's earlier collections\, previously unpublished short fiction\, and stories that were later expanded into such novels as The Unvanquished\, The Hamlet\, and Go Down\, Moses. With its Introduction and extensive notes by the biographer Joseph Blotner\, Uncollected Stories of William Faulkner is an essential addition to its author's canon--as well as a book of some of the most haunting\, harrowing\, and atmospheric short fiction written in the twentieth century. +76,8615,Winter notes on summer impressions,Fyodor Dostoevsky,2018,Alma Books,4.75,In June 1862\, Dostoevsky left Petersburg on his first excursion to Western Europe. Ostensibly making the trip to consult Western specialists about his epilepsy\, he also wished to see first-hand the source of the Western ideas he believed were corrupting Russia. Over the course of his journey he visited a number of major cities\, including Berlin\, Paris\, London\, Florence\, Milan and Vienna.His record of the trip\, Winter Notes on Summer Impressions - first published in the February 1863 issue of Vremya\, the periodical he edited - is the chrysalis out of which many elements of his later masterpieces developed. +77,6478,Woman-The Full Story: A Dynamic Celebration of Freedoms,Michele Guinness,2003,Zondervan,5.00,What does it mean to be a woman today? What have women inherited from their radical\, risk-taking sisters of the past? And how does God view this half of humanity? Michele Guinness invites us on an adventure of discovery\, exploring the biblical texts\, the annals of history and the experiences of women today in search of the challenges and achievements\, failures and joys\, of women throughout the ages. +78,8678,Worlds of Exile and Illusion: Three Complete Novels of the Hainish Series in One Volume--Rocannon's World\, Planet of Exile\, City of Illusions,Ursula K. Le Guin,2016,Orb Books,4.41,Worlds of Exile and Illusion contains three novels in the Hainish Series from Ursula K. Le Guin\, one of the greatest science fiction writers and many times the winner of the Hugo and Nebula Awards. Her career as a novelist was launched by the three novels contained here. These books\, Rocannon's World\, Planet of Exile\, and City of Illusions\, are set in the same universe as Le Guin's groundbreaking classic\, The Left Hand of Darkness. At the Publisher's request\, this title is being sold without Digital Rights Management Software (DRM) applied. diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/scoring.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/scoring.csv-spec index cb38204a71ab0..72632c62603aa 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/scoring.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/scoring.csv-spec @@ -13,9 +13,9 @@ from books metadata _score | sort c_score desc, book_no asc | LIMIT 2; -book_no:keyword | title:text | c_score:double -2675 | The Lord of the Rings - Boxed Set | 6.0 -4023 | A Tolkien Compass: Including J. R. R. Tolkien's Guide to the Names in The Lord of the Rings | 6.0 +book_no:keyword | title:text | c_score:double +1463 | Realms of Tolkien: Images of Middle-earth | 6.0 +2675 | The Lord of the Rings - Boxed Set | 6.0 ; singleMatchWithKeywordFieldScoring @@ -28,15 +28,15 @@ from books metadata _score | sort book_no; book_no:keyword | author:text | _score:double -2713 | William Faulkner | 2.3142893314361572 -2883 | William Faulkner | 2.3142893314361572 -4724 | William Faulkner | 2.3142893314361572 -4977 | William Faulkner | 2.3142893314361572 -5119 | William Faulkner | 2.3142893314361572 -5404 | William Faulkner | 2.3142893314361572 -5578 | William Faulkner | 2.3142893314361572 -8077 | William Faulkner | 2.3142893314361572 -9896 | William Faulkner | 2.3142893314361572 +2713 | William Faulkner | 1.7589385509490967 +2883 | William Faulkner | 1.7589385509490967 +4724 | William Faulkner | 1.7589385509490967 +4977 | William Faulkner | 2.6145541667938232 +5119 | William Faulkner | 2.513157367706299 +5404 | William Faulkner | 1.7589385509490967 +5578 | William Faulkner | 2.513157367706299 +8077 | William Faulkner | 1.7589385509490967 +9896 | William Faulkner | 2.6145541667938232 ; qstrWithFieldAndScoringSortedEval @@ -51,9 +51,9 @@ from books metadata _score | limit 3; book_no:keyword | title:text | _score:double -2675 | The Lord of the Rings - Boxed Set | 2.7583377361297607 -7140 | The Lord of the Rings Poster Collection: Six Paintings by Alan Lee (No. 1) | 1.9239964485168457 -2714 | Return of the King Being the Third Part of The Lord of the Rings | 1.9239964485168457 +2675 | The Lord of the Rings - Boxed Set | 2.5619282722473145 +2714 | Return of the King Being the Third Part of The Lord of the Rings | 1.9245924949645996 +7140 | The Lord of the Rings Poster Collection: Six Paintings by Alan Lee (No. 1) | 1.746896743774414 ; qstrWithFieldAndScoringSorted @@ -67,9 +67,9 @@ from books metadata _score | limit 3; book_no:keyword | title:text | _score:double -2675 | The Lord of the Rings - Boxed Set | 2.7583377361297607 -7140 | The Lord of the Rings Poster Collection: Six Paintings by Alan Lee (No. 1) | 1.9239964485168457 -2714 | Return of the King Being the Third Part of The Lord of the Rings | 1.9239964485168457 +2675 | The Lord of the Rings - Boxed Set | 2.5619282722473145 +2714 | Return of the King Being the Third Part of The Lord of the Rings | 1.9245924949645996 +7140 | The Lord of the Rings Poster Collection: Six Paintings by Alan Lee (No. 1) | 1.746896743774414 ; singleQstrScoringManipulated @@ -84,8 +84,8 @@ from books metadata _score | LIMIT 2; book_no:keyword | author:text | add_score:double -2378 | [Carol Faulkner, Holly Byers Ochoa, Lucretia Mott] | 2.0 -2713 | William Faulkner | 7.0 +2378 | [Carol Faulkner, Holly Byers Ochoa, Lucretia Mott] | 3.0 +2713 | William Faulkner | 6.0 ; testMultiValuedFieldWithConjunctionWithScore @@ -125,7 +125,7 @@ from books metadata _score ignoreOrder:true book_no:keyword | title:text | author:text | _score:double -8480 | The wind's twelve quarters: Short stories | Ursula K. Le Guin | 14.489097595214844 +8480 | The wind's twelve quarters: Short stories | Ursula K. Le Guin | 11.193471908569336 ; multipleWhereWithMatchScoring @@ -139,7 +139,7 @@ from books metadata _score | sort book_no; book_no:keyword | title:text | author:text | _score:double -8480 | The wind's twelve quarters: Short stories | Ursula K. Le Guin | 14.489097595214844 +8480 | The wind's twelve quarters: Short stories | Ursula K. Le Guin | 11.193471908569336 ; combinedMatchWithFunctionsScoring @@ -153,7 +153,7 @@ from books metadata _score | sort book_no; book_no:keyword | title:text | author:text | year:integer | _score:double -5335 | Letters of J R R Tolkien | J.R.R. Tolkien | 2014 | 5.448054313659668 +5335 | Letters of J R R Tolkien | J.R.R. Tolkien | 2014 | 4.733664035797119 ; singleQstrScoring @@ -167,8 +167,8 @@ from books metadata _score | LIMIT 2; book_no:keyword | author:text | _score:double -2378 | [Carol Faulkner, Holly Byers Ochoa, Lucretia Mott] | 0.9976131916046143 -2713 | William Faulkner | 5.9556169509887695 +2378 | [Carol Faulkner, Holly Byers Ochoa, Lucretia Mott] | 1.3697924613952637 +2713 | William Faulkner | 4.631696701049805 ; singleQstrScoringGrok @@ -183,9 +183,9 @@ from books metadata _score | LIMIT 3; book_no:keyword | title:keyword | _score:double -8875 | The | 2.9505908489227295 -4023 | A | 2.8327860832214355 -2675 | The | 2.7583377361297607 +8875 | The | 2.769660472869873 +1463 | Realms | 2.6714818477630615 +2675 | The | 2.5619282722473145 ; combinedMatchWithScoringEvalNoSort @@ -200,7 +200,7 @@ from books metadata _score ignoreOrder:true book_no:keyword | title:text | author:text | year:integer | c_score:double -5335 | Letters of J R R Tolkien | J.R.R. Tolkien | 2014 | 6 +5335 | Letters of J R R Tolkien | J.R.R. Tolkien | 2014 | 5.0 ; singleQstrScoringRename @@ -215,9 +215,9 @@ from books metadata _score | LIMIT 3; book_no:keyword | rank:double -8875 | 2.9505908489227295 -4023 | 2.8327860832214355 -2675 | 2.7583377361297607 +8875 | 2.769660472869873 +1463 | 2.6714818477630615 +2675 | 2.5619282722473145 ; singleMatchWithTextFieldScoring @@ -231,11 +231,11 @@ from books metadata _score | limit 5; book_no:keyword | author:text | _score:double -2378 | [Carol Faulkner, Holly Byers Ochoa, Lucretia Mott] | 0.9976131916046143 -2713 | William Faulkner | 4.272439002990723 -2847 | Colleen Faulkner | 1.7401835918426514 -2883 | William Faulkner | 4.272439002990723 -3293 | Danny Faulkner | 1.7401835918426514 +2378 | [Carol Faulkner, Holly Byers Ochoa, Lucretia Mott] | 1.3697924613952637 +2713 | William Faulkner | 3.2750158309936523 +2847 | Colleen Faulkner | 1.593343734741211 +2883 | William Faulkner | 3.2750158309936523 +3293 | Danny Faulkner | 1.593343734741211 ; combinedMatchWithFunctionsScoringNoSort @@ -249,7 +249,7 @@ from books metadata _score ignoreOrder:true book_no:keyword | title:text | author:text | year:integer | _score:double -5335 | Letters of J R R Tolkien | J.R.R. Tolkien | 2014 | 5.448054313659668 +5335 | Letters of J R R Tolkien | J.R.R. Tolkien | 2014 | 4.733664035797119 ; combinedMatchWithScoringEval @@ -264,7 +264,7 @@ from books metadata _score | sort book_no; book_no:keyword | title:text | author:text | year:integer | c_score:double -5335 | Letters of J R R Tolkien | J.R.R. Tolkien | 2014 | 6 +5335 | Letters of J R R Tolkien | J.R.R. Tolkien | 2014 | 5.0 ; singleQstrScoringEval @@ -280,7 +280,7 @@ from books metadata _score book_no:keyword | c_score:double 8875 | 3.0 -7350 | 2.0 +7350 | 1.0 7140 | 3.0 ; @@ -289,14 +289,16 @@ required_capability: metadata_score required_capability: qstr_function from books metadata _score -| where qstr("title:rings") +| where qstr("title:gentle") | eval _score = _score + 1 | keep book_no, title, _score -| limit 2; +| limit 10 +; +ignoreOrder:true -book_no:keyword | title:text | _score:double -4023 | A Tolkien Compass: Including J. R. R. Tolkien's Guide to the Names in The Lord of the Rings | 2.6404519081115723 -2714 | Return of the King Being the Third Part of The Lord of the Rings | 2.9239964485168457 +book_no:keyword | title:text | _score:double +2924 | A Gentle Creature and Other Stories: White Nights, A Gentle Creature, and The Dream of a Ridiculous Man (The World's Classics) | 3.158426523208618 +5948 | That We Are Gentle Creatures | 3.727346897125244 ; QstrScoreOverride @@ -304,12 +306,14 @@ required_capability: metadata_score required_capability: qstr_function from books metadata _score -| where qstr("title:rings") +| where qstr("title:gentle") | eval _score = "foobar" | keep book_no, title, _score -| limit 2; +| limit 10 +; +ignoreOrder:true -book_no:keyword | title:text | _score:keyword -4023 | A Tolkien Compass: Including J. R. R. Tolkien's Guide to the Names in The Lord of the Rings | foobar -2714 | Return of the King Being the Third Part of The Lord of the Rings | foobar +book_no:keyword | title:text | _score:keyword +2924 | A Gentle Creature and Other Stories: White Nights, A Gentle Creature, and The Dream of a Ridiculous Man (The World's Classics) | foobar +5948 | That We Are Gentle Creatures | foobar ; From 7cf28a910e6aa8e5679a73eb54075b6778277b67 Mon Sep 17 00:00:00 2001 From: Ievgen Degtiarenko Date: Wed, 18 Dec 2024 09:56:42 +0100 Subject: [PATCH 30/60] ESQL Add esql hash function (#117989) This change introduces esql hash(alg, input) function that relies on the Java MessageDigest to compute the hash. --- docs/changelog/117989.yaml | 5 + .../esql/functions/description/hash.asciidoc | 5 + .../functions/kibana/definition/hash.json | 82 +++++++ .../esql/functions/kibana/docs/hash.md | 7 + .../esql/functions/layout/hash.asciidoc | 14 ++ .../esql/functions/parameters/hash.asciidoc | 9 + .../esql/functions/signature/hash.svg | 1 + .../esql/functions/string-functions.asciidoc | 2 + .../esql/functions/types/hash.asciidoc | 12 + .../src/main/resources/hash.csv-spec | 105 +++++++++ .../scalar/string/HashConstantEvaluator.java | 142 ++++++++++++ .../function/scalar/string/HashEvaluator.java | 174 ++++++++++++++ .../xpack/esql/action/EsqlCapabilities.java | 5 + .../function/EsqlFunctionRegistry.java | 2 + .../scalar/ScalarFunctionWritables.java | 2 + .../function/scalar/string/Hash.java | 217 ++++++++++++++++++ .../AbstractExpressionSerializationTests.java | 5 + .../scalar/string/HashSerializationTests.java | 27 +++ .../scalar/string/HashStaticTests.java | 66 ++++++ .../function/scalar/string/HashTests.java | 107 +++++++++ .../rest-api-spec/test/esql/60_usage.yml | 4 +- 21 files changed, 991 insertions(+), 2 deletions(-) create mode 100644 docs/changelog/117989.yaml create mode 100644 docs/reference/esql/functions/description/hash.asciidoc create mode 100644 docs/reference/esql/functions/kibana/definition/hash.json create mode 100644 docs/reference/esql/functions/kibana/docs/hash.md create mode 100644 docs/reference/esql/functions/layout/hash.asciidoc create mode 100644 docs/reference/esql/functions/parameters/hash.asciidoc create mode 100644 docs/reference/esql/functions/signature/hash.svg create mode 100644 docs/reference/esql/functions/types/hash.asciidoc create mode 100644 x-pack/plugin/esql/qa/testFixtures/src/main/resources/hash.csv-spec create mode 100644 x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashConstantEvaluator.java create mode 100644 x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashEvaluator.java create mode 100644 x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Hash.java create mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashSerializationTests.java create mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashStaticTests.java create mode 100644 x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashTests.java diff --git a/docs/changelog/117989.yaml b/docs/changelog/117989.yaml new file mode 100644 index 0000000000000..e4967141b3ebd --- /dev/null +++ b/docs/changelog/117989.yaml @@ -0,0 +1,5 @@ +pr: 117989 +summary: ESQL Add esql hash function +area: ES|QL +type: enhancement +issues: [] diff --git a/docs/reference/esql/functions/description/hash.asciidoc b/docs/reference/esql/functions/description/hash.asciidoc new file mode 100644 index 0000000000000..e074915c5132a --- /dev/null +++ b/docs/reference/esql/functions/description/hash.asciidoc @@ -0,0 +1,5 @@ +// This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +*Description* + +Computes the hash of the input using various algorithms such as MD5, SHA, SHA-224, SHA-256, SHA-384, SHA-512. diff --git a/docs/reference/esql/functions/kibana/definition/hash.json b/docs/reference/esql/functions/kibana/definition/hash.json new file mode 100644 index 0000000000000..17a60cf45acfe --- /dev/null +++ b/docs/reference/esql/functions/kibana/definition/hash.json @@ -0,0 +1,82 @@ +{ + "comment" : "This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.", + "type" : "eval", + "name" : "hash", + "description" : "Computes the hash of the input using various algorithms such as MD5, SHA, SHA-224, SHA-256, SHA-384, SHA-512.", + "signatures" : [ + { + "params" : [ + { + "name" : "algorithm", + "type" : "keyword", + "optional" : false, + "description" : "Hash algorithm to use." + }, + { + "name" : "input", + "type" : "keyword", + "optional" : false, + "description" : "Input to hash." + } + ], + "variadic" : false, + "returnType" : "keyword" + }, + { + "params" : [ + { + "name" : "algorithm", + "type" : "keyword", + "optional" : false, + "description" : "Hash algorithm to use." + }, + { + "name" : "input", + "type" : "text", + "optional" : false, + "description" : "Input to hash." + } + ], + "variadic" : false, + "returnType" : "keyword" + }, + { + "params" : [ + { + "name" : "algorithm", + "type" : "text", + "optional" : false, + "description" : "Hash algorithm to use." + }, + { + "name" : "input", + "type" : "keyword", + "optional" : false, + "description" : "Input to hash." + } + ], + "variadic" : false, + "returnType" : "keyword" + }, + { + "params" : [ + { + "name" : "algorithm", + "type" : "text", + "optional" : false, + "description" : "Hash algorithm to use." + }, + { + "name" : "input", + "type" : "text", + "optional" : false, + "description" : "Input to hash." + } + ], + "variadic" : false, + "returnType" : "keyword" + } + ], + "preview" : false, + "snapshot_only" : false +} diff --git a/docs/reference/esql/functions/kibana/docs/hash.md b/docs/reference/esql/functions/kibana/docs/hash.md new file mode 100644 index 0000000000000..9826e80ec5bec --- /dev/null +++ b/docs/reference/esql/functions/kibana/docs/hash.md @@ -0,0 +1,7 @@ + + +### HASH +Computes the hash of the input using various algorithms such as MD5, SHA, SHA-224, SHA-256, SHA-384, SHA-512. + diff --git a/docs/reference/esql/functions/layout/hash.asciidoc b/docs/reference/esql/functions/layout/hash.asciidoc new file mode 100644 index 0000000000000..27c55ada6319b --- /dev/null +++ b/docs/reference/esql/functions/layout/hash.asciidoc @@ -0,0 +1,14 @@ +// This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +[discrete] +[[esql-hash]] +=== `HASH` + +*Syntax* + +[.text-center] +image::esql/functions/signature/hash.svg[Embedded,opts=inline] + +include::../parameters/hash.asciidoc[] +include::../description/hash.asciidoc[] +include::../types/hash.asciidoc[] diff --git a/docs/reference/esql/functions/parameters/hash.asciidoc b/docs/reference/esql/functions/parameters/hash.asciidoc new file mode 100644 index 0000000000000..d47a82d4ab214 --- /dev/null +++ b/docs/reference/esql/functions/parameters/hash.asciidoc @@ -0,0 +1,9 @@ +// This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +*Parameters* + +`algorithm`:: +Hash algorithm to use. + +`input`:: +Input to hash. diff --git a/docs/reference/esql/functions/signature/hash.svg b/docs/reference/esql/functions/signature/hash.svg new file mode 100644 index 0000000000000..f819e14c9d1a4 --- /dev/null +++ b/docs/reference/esql/functions/signature/hash.svg @@ -0,0 +1 @@ +HASH(algorithm,input) \ No newline at end of file diff --git a/docs/reference/esql/functions/string-functions.asciidoc b/docs/reference/esql/functions/string-functions.asciidoc index ce9636f5c5a3a..da9580a55151a 100644 --- a/docs/reference/esql/functions/string-functions.asciidoc +++ b/docs/reference/esql/functions/string-functions.asciidoc @@ -13,6 +13,7 @@ * <> * <> * <> +* <> * <> * <> * <> @@ -37,6 +38,7 @@ include::layout/byte_length.asciidoc[] include::layout/concat.asciidoc[] include::layout/ends_with.asciidoc[] include::layout/from_base64.asciidoc[] +include::layout/hash.asciidoc[] include::layout/left.asciidoc[] include::layout/length.asciidoc[] include::layout/locate.asciidoc[] diff --git a/docs/reference/esql/functions/types/hash.asciidoc b/docs/reference/esql/functions/types/hash.asciidoc new file mode 100644 index 0000000000000..786ba03b2aa60 --- /dev/null +++ b/docs/reference/esql/functions/types/hash.asciidoc @@ -0,0 +1,12 @@ +// This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. + +*Supported types* + +[%header.monospaced.styled,format=dsv,separator=|] +|=== +algorithm | input | result +keyword | keyword | keyword +keyword | text | keyword +text | keyword | keyword +text | text | keyword +|=== diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/hash.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/hash.csv-spec new file mode 100644 index 0000000000000..fcac1e1859c6d --- /dev/null +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/hash.csv-spec @@ -0,0 +1,105 @@ +hash +required_capability: hash_function + +FROM sample_data +| WHERE message != "Connection error" +| EVAL md5 = hash("md5", message), sha256 = hash("sha256", message) +| KEEP message, md5, sha256; +ignoreOrder:true + +message:keyword | md5:keyword | sha256:keyword +Connected to 10.1.0.1 | abd7d1ce2bb636842a29246b3512dcae | 6d8372129ad78770f7185554dd39864749a62690216460752d6c075fa38ad85c +Connected to 10.1.0.2 | 8f8f1cb60832d153f5b9ec6dc828b93f | b0db24720f15857091b3c99f4c4833586d0ea3229911b8777efb8d917cf27e9a +Connected to 10.1.0.3 | 912b6dc13503165a15de43304bb77c78 | 75b0480188db8acc4d5cc666a51227eb2bc5b989cd8ca912609f33e0846eff57 +Disconnected | ef70e46fd3bbc21e3e1f0b6815e750c0 | 04dfac3671b494ad53fcd152f7a14511bfb35747278aad8ce254a0d6e4ba4718 +; + + +hashOfConvertedType +required_capability: hash_function + +FROM sample_data +| WHERE message != "Connection error" +| EVAL input = event_duration::STRING, md5 = hash("md5", input), sha256 = hash("sha256", input) +| KEEP message, input, md5, sha256; +ignoreOrder:true + +message:keyword | input:keyword | md5:keyword | sha256:keyword +Connected to 10.1.0.1 | 1756467 | c4fc1c57ee9b1d2b2023b70c8c167b54 | 8376a50a7ba7e6bd1bf9ad0c32d27d2f49fd0fa422573f98f239e21048b078f3 +Connected to 10.1.0.2 | 2764889 | 8e8cf005e11a7b5df1d9478a4715a444 | 1031f2bef8eaecbf47319505422300b27ea1f7c38b6717d41332325062f9a56a +Connected to 10.1.0.3 | 3450233 | 09f2c64f5a55e9edf8ffbad336b561d8 | f77d7545769c4ecc85092f4f0b7ec8c20f467e4beb15fe67ca29f9aa8e9a6900 +Disconnected | 1232382 | 6beac1485638d51e13c2c53990a2f611 | 9a03c1274a3ebb6c1cb85d170ce0a6fdb9d2232724e06b9f5e7cb9274af3cad6 +; + + +hashOfEmptyInput +required_capability: hash_function + +ROW input="" | EVAL md5 = hash("md5", input), sha256 = hash("sha256", input); + +input:keyword | md5:keyword | sha256:keyword + | d41d8cd98f00b204e9800998ecf8427e | e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +; + +hashOfNullInput +required_capability: hash_function + +ROW input=null::STRING | EVAL md5 = hash("md5", input), sha256 = hash("sha256", input); + +input:keyword | md5:keyword | sha256:keyword +null | null | null +; + + +hashWithNullAlgorithm +required_capability: hash_function + +ROW input="input" | EVAL hash = hash(null, input); + +input:keyword | hash:keyword +input | null +; + + +hashWithMv +required_capability: hash_function + +ROW input=["foo", "bar"] | mv_expand input | EVAL md5 = hash("md5", input), sha256 = hash("sha256", input); + +input:keyword | md5:keyword | sha256:keyword +foo | acbd18db4cc2f85cedef654fccc4a4d8 | 2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae +bar | 37b51d194a7513e45b56f6524f2d51f2 | fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9 +; + + +hashWithNestedFunctions +required_capability: hash_function + +ROW input=["foo", "bar"] | EVAL hash = concat(hash("md5", mv_concat(input, "-")), "-", hash("sha256", mv_concat(input, "-"))); + +input:keyword | hash:keyword +["foo", "bar"] | e5f9ec048d1dbe19c70f720e002f9cb1-7d89c4f517e3bd4b5e8e76687937005b602ea00c5cba3e25ef1fc6575a55103e +; + + +hashWithConvertedTypes +required_capability: hash_function + +ROW input=42 | EVAL md5 = hash("md5", input::STRING), sha256 = hash("sha256", to_string(input)); + +input:integer | md5:keyword | sha256:keyword +42 | a1d0c6e83f027327d8461063f4ac58a6 | 73475cb40a568e8da8a045ced110137e159f890ac4da883b6b17dc651b3a8049 +; + + +hashWithStats +required_capability: hash_function + +FROM sample_data +| EVAL md5="md5" +| STATS count = count(*) by hash(md5, message) +| WHERE count > 1; + +count:long | hash(md5, message):keyword +3 | 2e92ae79ff32b37fee4368a594792183 +; diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashConstantEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashConstantEvaluator.java new file mode 100644 index 0000000000000..34cff73018634 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashConstantEvaluator.java @@ -0,0 +1,142 @@ +// 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.esql.expression.function.scalar.string; + +import java.lang.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import java.util.function.Function; +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BytesRefBlock; +import org.elasticsearch.compute.data.BytesRefVector; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.BreakingBytesRefBuilder; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.compute.operator.Warnings; +import org.elasticsearch.core.Releasables; +import org.elasticsearch.xpack.esql.core.tree.Source; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link Hash}. + * This class is generated. Do not edit it. + */ +public final class HashConstantEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final BreakingBytesRefBuilder scratch; + + private final Hash.HashFunction algorithm; + + private final EvalOperator.ExpressionEvaluator input; + + private final DriverContext driverContext; + + private Warnings warnings; + + public HashConstantEvaluator(Source source, BreakingBytesRefBuilder scratch, + Hash.HashFunction algorithm, EvalOperator.ExpressionEvaluator input, + DriverContext driverContext) { + this.source = source; + this.scratch = scratch; + this.algorithm = algorithm; + this.input = input; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock inputBlock = (BytesRefBlock) input.eval(page)) { + BytesRefVector inputVector = inputBlock.asVector(); + if (inputVector == null) { + return eval(page.getPositionCount(), inputBlock); + } + return eval(page.getPositionCount(), inputVector).asBlock(); + } + } + + public BytesRefBlock eval(int positionCount, BytesRefBlock inputBlock) { + try(BytesRefBlock.Builder result = driverContext.blockFactory().newBytesRefBlockBuilder(positionCount)) { + BytesRef inputScratch = new BytesRef(); + position: for (int p = 0; p < positionCount; p++) { + if (inputBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (inputBlock.getValueCount(p) != 1) { + if (inputBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + result.appendBytesRef(Hash.processConstant(this.scratch, this.algorithm, inputBlock.getBytesRef(inputBlock.getFirstValueIndex(p), inputScratch))); + } + return result.build(); + } + } + + public BytesRefVector eval(int positionCount, BytesRefVector inputVector) { + try(BytesRefVector.Builder result = driverContext.blockFactory().newBytesRefVectorBuilder(positionCount)) { + BytesRef inputScratch = new BytesRef(); + position: for (int p = 0; p < positionCount; p++) { + result.appendBytesRef(Hash.processConstant(this.scratch, this.algorithm, inputVector.getBytesRef(p, inputScratch))); + } + return result.build(); + } + } + + @Override + public String toString() { + return "HashConstantEvaluator[" + "algorithm=" + algorithm + ", input=" + input + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(scratch, input); + } + + private Warnings warnings() { + if (warnings == null) { + this.warnings = Warnings.createWarnings( + driverContext.warningsMode(), + source.source().getLineNumber(), + source.source().getColumnNumber(), + source.text() + ); + } + return warnings; + } + + static class Factory implements EvalOperator.ExpressionEvaluator.Factory { + private final Source source; + + private final Function scratch; + + private final Function algorithm; + + private final EvalOperator.ExpressionEvaluator.Factory input; + + public Factory(Source source, Function scratch, + Function algorithm, + EvalOperator.ExpressionEvaluator.Factory input) { + this.source = source; + this.scratch = scratch; + this.algorithm = algorithm; + this.input = input; + } + + @Override + public HashConstantEvaluator get(DriverContext context) { + return new HashConstantEvaluator(source, scratch.apply(context), algorithm.apply(context), input.get(context), context); + } + + @Override + public String toString() { + return "HashConstantEvaluator[" + "algorithm=" + algorithm + ", input=" + input + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashEvaluator.java new file mode 100644 index 0000000000000..8b01cc0330142 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashEvaluator.java @@ -0,0 +1,174 @@ +// 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.esql.expression.function.scalar.string; + +import java.lang.IllegalArgumentException; +import java.lang.Override; +import java.lang.String; +import java.security.NoSuchAlgorithmException; +import java.util.function.Function; +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BytesRefBlock; +import org.elasticsearch.compute.data.BytesRefVector; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.BreakingBytesRefBuilder; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.compute.operator.Warnings; +import org.elasticsearch.core.Releasables; +import org.elasticsearch.xpack.esql.core.tree.Source; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link Hash}. + * This class is generated. Do not edit it. + */ +public final class HashEvaluator implements EvalOperator.ExpressionEvaluator { + private final Source source; + + private final BreakingBytesRefBuilder scratch; + + private final EvalOperator.ExpressionEvaluator algorithm; + + private final EvalOperator.ExpressionEvaluator input; + + private final DriverContext driverContext; + + private Warnings warnings; + + public HashEvaluator(Source source, BreakingBytesRefBuilder scratch, + EvalOperator.ExpressionEvaluator algorithm, EvalOperator.ExpressionEvaluator input, + DriverContext driverContext) { + this.source = source; + this.scratch = scratch; + this.algorithm = algorithm; + this.input = input; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock algorithmBlock = (BytesRefBlock) algorithm.eval(page)) { + try (BytesRefBlock inputBlock = (BytesRefBlock) input.eval(page)) { + BytesRefVector algorithmVector = algorithmBlock.asVector(); + if (algorithmVector == null) { + return eval(page.getPositionCount(), algorithmBlock, inputBlock); + } + BytesRefVector inputVector = inputBlock.asVector(); + if (inputVector == null) { + return eval(page.getPositionCount(), algorithmBlock, inputBlock); + } + return eval(page.getPositionCount(), algorithmVector, inputVector); + } + } + } + + public BytesRefBlock eval(int positionCount, BytesRefBlock algorithmBlock, + BytesRefBlock inputBlock) { + try(BytesRefBlock.Builder result = driverContext.blockFactory().newBytesRefBlockBuilder(positionCount)) { + BytesRef algorithmScratch = new BytesRef(); + BytesRef inputScratch = new BytesRef(); + position: for (int p = 0; p < positionCount; p++) { + if (algorithmBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (algorithmBlock.getValueCount(p) != 1) { + if (algorithmBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + if (inputBlock.isNull(p)) { + result.appendNull(); + continue position; + } + if (inputBlock.getValueCount(p) != 1) { + if (inputBlock.getValueCount(p) > 1) { + warnings().registerException(new IllegalArgumentException("single-value function encountered multi-value")); + } + result.appendNull(); + continue position; + } + try { + result.appendBytesRef(Hash.process(this.scratch, algorithmBlock.getBytesRef(algorithmBlock.getFirstValueIndex(p), algorithmScratch), inputBlock.getBytesRef(inputBlock.getFirstValueIndex(p), inputScratch))); + } catch (NoSuchAlgorithmException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + public BytesRefBlock eval(int positionCount, BytesRefVector algorithmVector, + BytesRefVector inputVector) { + try(BytesRefBlock.Builder result = driverContext.blockFactory().newBytesRefBlockBuilder(positionCount)) { + BytesRef algorithmScratch = new BytesRef(); + BytesRef inputScratch = new BytesRef(); + position: for (int p = 0; p < positionCount; p++) { + try { + result.appendBytesRef(Hash.process(this.scratch, algorithmVector.getBytesRef(p, algorithmScratch), inputVector.getBytesRef(p, inputScratch))); + } catch (NoSuchAlgorithmException e) { + warnings().registerException(e); + result.appendNull(); + } + } + return result.build(); + } + } + + @Override + public String toString() { + return "HashEvaluator[" + "algorithm=" + algorithm + ", input=" + input + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(scratch, algorithm, input); + } + + private Warnings warnings() { + if (warnings == null) { + this.warnings = Warnings.createWarnings( + driverContext.warningsMode(), + source.source().getLineNumber(), + source.source().getColumnNumber(), + source.text() + ); + } + return warnings; + } + + static class Factory implements EvalOperator.ExpressionEvaluator.Factory { + private final Source source; + + private final Function scratch; + + private final EvalOperator.ExpressionEvaluator.Factory algorithm; + + private final EvalOperator.ExpressionEvaluator.Factory input; + + public Factory(Source source, Function scratch, + EvalOperator.ExpressionEvaluator.Factory algorithm, + EvalOperator.ExpressionEvaluator.Factory input) { + this.source = source; + this.scratch = scratch; + this.algorithm = algorithm; + this.input = input; + } + + @Override + public HashEvaluator get(DriverContext context) { + return new HashEvaluator(source, scratch.apply(context), algorithm.get(context), input.get(context), context); + } + + @Override + public String toString() { + return "HashEvaluator[" + "algorithm=" + algorithm + ", input=" + input + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java index 8c7e381d33322..d6c1539088d47 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java @@ -449,6 +449,11 @@ public enum Cap { */ KQL_FUNCTION(Build.current().isSnapshot()), + /** + * Hash function + */ + HASH_FUNCTION, + /** * Don't optimize CASE IS NOT NULL function by not requiring the fields to be not null as well. * https://github.com/elastic/elasticsearch/issues/112704 diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java index a59ef5bb1575d..908c9c5f197a8 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/EsqlFunctionRegistry.java @@ -129,6 +129,7 @@ import org.elasticsearch.xpack.esql.expression.function.scalar.string.ByteLength; import org.elasticsearch.xpack.esql.expression.function.scalar.string.Concat; import org.elasticsearch.xpack.esql.expression.function.scalar.string.EndsWith; +import org.elasticsearch.xpack.esql.expression.function.scalar.string.Hash; import org.elasticsearch.xpack.esql.expression.function.scalar.string.LTrim; import org.elasticsearch.xpack.esql.expression.function.scalar.string.Left; import org.elasticsearch.xpack.esql.expression.function.scalar.string.Length; @@ -327,6 +328,7 @@ private static FunctionDefinition[][] functions() { def(ByteLength.class, ByteLength::new, "byte_length"), def(Concat.class, Concat::new, "concat"), def(EndsWith.class, EndsWith::new, "ends_with"), + def(Hash.class, Hash::new, "hash"), def(LTrim.class, LTrim::new, "ltrim"), def(Left.class, Left::new, "left"), def(Length.class, Length::new, "length"), diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/ScalarFunctionWritables.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/ScalarFunctionWritables.java index 192ca6c43e57d..3cf0eef9074ad 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/ScalarFunctionWritables.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/ScalarFunctionWritables.java @@ -34,6 +34,7 @@ import org.elasticsearch.xpack.esql.expression.function.scalar.string.BitLength; import org.elasticsearch.xpack.esql.expression.function.scalar.string.Concat; import org.elasticsearch.xpack.esql.expression.function.scalar.string.EndsWith; +import org.elasticsearch.xpack.esql.expression.function.scalar.string.Hash; import org.elasticsearch.xpack.esql.expression.function.scalar.string.Left; import org.elasticsearch.xpack.esql.expression.function.scalar.string.Locate; import org.elasticsearch.xpack.esql.expression.function.scalar.string.Repeat; @@ -64,6 +65,7 @@ public static List getNamedWriteables() { entries.add(E.ENTRY); entries.add(EndsWith.ENTRY); entries.add(Greatest.ENTRY); + entries.add(Hash.ENTRY); entries.add(Hypot.ENTRY); entries.add(In.ENTRY); entries.add(InsensitiveEquals.ENTRY); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Hash.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Hash.java new file mode 100644 index 0000000000000..99c5908699ec2 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/Hash.java @@ -0,0 +1,217 @@ +/* + * 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.esql.expression.function.scalar.string; + +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.io.stream.NamedWriteableRegistry; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.compute.ann.Evaluator; +import org.elasticsearch.compute.ann.Fixed; +import org.elasticsearch.compute.operator.BreakingBytesRefBuilder; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.xpack.esql.core.InvalidArgumentException; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.NodeInfo; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; +import org.elasticsearch.xpack.esql.expression.function.Param; +import org.elasticsearch.xpack.esql.expression.function.scalar.EsqlScalarFunction; +import org.elasticsearch.xpack.esql.io.stream.PlanStreamInput; + +import java.io.IOException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.List; +import java.util.function.Function; + +import static org.elasticsearch.compute.ann.Fixed.Scope.THREAD_LOCAL; +import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.FIRST; +import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.SECOND; +import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isString; + +public class Hash extends EsqlScalarFunction { + + public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Hash", Hash::new); + + private final Expression algorithm; + private final Expression input; + + @FunctionInfo( + returnType = "keyword", + description = "Computes the hash of the input using various algorithms such as MD5, SHA, SHA-224, SHA-256, SHA-384, SHA-512." + ) + public Hash( + Source source, + @Param(name = "algorithm", type = { "keyword", "text" }, description = "Hash algorithm to use.") Expression algorithm, + @Param(name = "input", type = { "keyword", "text" }, description = "Input to hash.") Expression input + ) { + super(source, List.of(algorithm, input)); + this.algorithm = algorithm; + this.input = input; + } + + private Hash(StreamInput in) throws IOException { + this(Source.readFrom((PlanStreamInput) in), in.readNamedWriteable(Expression.class), in.readNamedWriteable(Expression.class)); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + source().writeTo(out); + out.writeNamedWriteable(algorithm); + out.writeNamedWriteable(input); + } + + @Override + public String getWriteableName() { + return ENTRY.name; + } + + @Override + public DataType dataType() { + return DataType.KEYWORD; + } + + @Override + protected TypeResolution resolveType() { + if (childrenResolved() == false) { + return new TypeResolution("Unresolved children"); + } + + TypeResolution resolution = isString(algorithm, sourceText(), FIRST); + if (resolution.unresolved()) { + return resolution; + } + + return isString(input, sourceText(), SECOND); + } + + @Override + public boolean foldable() { + return algorithm.foldable() && input.foldable(); + } + + @Evaluator(warnExceptions = NoSuchAlgorithmException.class) + static BytesRef process( + @Fixed(includeInToString = false, scope = THREAD_LOCAL) BreakingBytesRefBuilder scratch, + BytesRef algorithm, + BytesRef input + ) throws NoSuchAlgorithmException { + return hash(scratch, MessageDigest.getInstance(algorithm.utf8ToString()), input); + } + + @Evaluator(extraName = "Constant") + static BytesRef processConstant( + @Fixed(includeInToString = false, scope = THREAD_LOCAL) BreakingBytesRefBuilder scratch, + @Fixed(scope = THREAD_LOCAL) HashFunction algorithm, + BytesRef input + ) { + return hash(scratch, algorithm.digest, input); + } + + private static BytesRef hash(BreakingBytesRefBuilder scratch, MessageDigest algorithm, BytesRef input) { + algorithm.reset(); + algorithm.update(input.bytes, input.offset, input.length); + var digest = algorithm.digest(); + scratch.clear(); + scratch.grow(digest.length * 2); + appendUtf8HexDigest(scratch, digest); + return scratch.bytesRefView(); + } + + private static final byte[] ASCII_HEX_BYTES = new byte[] { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102 }; + + /** + * This function allows to append hex bytes dirrectly to the {@link BreakingBytesRefBuilder} + * bypassing unnecessary array allocations and byte array copying. + */ + private static void appendUtf8HexDigest(BreakingBytesRefBuilder scratch, byte[] bytes) { + for (byte b : bytes) { + scratch.append(ASCII_HEX_BYTES[b >> 4 & 0xf]); + scratch.append(ASCII_HEX_BYTES[b & 0xf]); + } + } + + @Override + public EvalOperator.ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvaluator) { + if (algorithm.foldable()) { + try { + // hash function is created here in order to validate the algorithm is valid before evaluator is created + var hf = HashFunction.create((BytesRef) algorithm.fold()); + return new HashConstantEvaluator.Factory( + source(), + context -> new BreakingBytesRefBuilder(context.breaker(), "hash"), + new Function<>() { + @Override + public HashFunction apply(DriverContext context) { + return hf.copy(); + } + + @Override + public String toString() { + return hf.toString(); + } + }, + toEvaluator.apply(input) + ); + } catch (NoSuchAlgorithmException e) { + throw new InvalidArgumentException(e, "invalid algorithm for [{}]: {}", sourceText(), e.getMessage()); + } + } else { + return new HashEvaluator.Factory( + source(), + context -> new BreakingBytesRefBuilder(context.breaker(), "hash"), + toEvaluator.apply(algorithm), + toEvaluator.apply(input) + ); + } + } + + @Override + public Expression replaceChildren(List newChildren) { + return new Hash(source(), newChildren.get(0), newChildren.get(1)); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, Hash::new, children().get(0), children().get(1)); + } + + public record HashFunction(String algorithm, MessageDigest digest) { + + public static HashFunction create(BytesRef literal) throws NoSuchAlgorithmException { + var algorithm = literal.utf8ToString(); + var digest = MessageDigest.getInstance(algorithm); + return new HashFunction(algorithm, digest); + } + + public HashFunction copy() { + try { + return new HashFunction(algorithm, MessageDigest.getInstance(algorithm)); + } catch (NoSuchAlgorithmException e) { + assert false : "Algorithm should be valid at this point"; + throw new IllegalStateException(e); + } + } + + @Override + public String toString() { + return algorithm; + } + } + + Expression algorithm() { + return algorithm; + } + + Expression input() { + return input; + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/AbstractExpressionSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/AbstractExpressionSerializationTests.java index 6dd0c5fe88afd..050293e58c19d 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/AbstractExpressionSerializationTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/AbstractExpressionSerializationTests.java @@ -14,10 +14,15 @@ import org.elasticsearch.xpack.esql.plan.AbstractNodeSerializationTests; public abstract class AbstractExpressionSerializationTests extends AbstractNodeSerializationTests { + public static Expression randomChild() { return ReferenceAttributeTests.randomReferenceAttribute(false); } + public static Expression mutateExpression(Expression expression) { + return randomValueOtherThan(expression, AbstractExpressionSerializationTests::randomChild); + } + @Override protected final NamedWriteableRegistry getNamedWriteableRegistry() { return new NamedWriteableRegistry(ExpressionWritables.getNamedWriteables()); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashSerializationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashSerializationTests.java new file mode 100644 index 0000000000000..f21105c2c8bca --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashSerializationTests.java @@ -0,0 +1,27 @@ +/* + * 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.esql.expression.function.scalar.string; + +import org.elasticsearch.xpack.esql.expression.AbstractExpressionSerializationTests; + +import java.io.IOException; + +public class HashSerializationTests extends AbstractExpressionSerializationTests { + + @Override + protected Hash createTestInstance() { + return new Hash(randomSource(), randomChild(), randomChild()); + } + + @Override + protected Hash mutateInstance(Hash instance) throws IOException { + return randomBoolean() + ? new Hash(instance.source(), mutateExpression(instance.algorithm()), instance.input()) + : new Hash(instance.source(), instance.algorithm(), mutateExpression(instance.input())); + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashStaticTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashStaticTests.java new file mode 100644 index 0000000000000..871bec7c06804 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashStaticTests.java @@ -0,0 +1,66 @@ +/* + * 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.esql.expression.function.scalar.string; + +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.breaker.CircuitBreaker; +import org.elasticsearch.common.unit.ByteSizeValue; +import org.elasticsearch.common.util.BigArrays; +import org.elasticsearch.common.util.MockBigArrays; +import org.elasticsearch.common.util.PageCacheRecycler; +import org.elasticsearch.compute.data.BlockFactory; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.esql.core.InvalidArgumentException; +import org.elasticsearch.xpack.esql.core.expression.Literal; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.junit.After; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.elasticsearch.xpack.esql.expression.function.AbstractFunctionTestCase.evaluator; +import static org.elasticsearch.xpack.esql.expression.function.AbstractFunctionTestCase.field; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.startsWith; + +public class HashStaticTests extends ESTestCase { + + public void testInvalidAlgorithmLiteral() { + Source source = new Source(0, 0, "hast(\"invalid\", input)"); + DriverContext driverContext = driverContext(); + InvalidArgumentException e = expectThrows( + InvalidArgumentException.class, + () -> evaluator( + new Hash(source, new Literal(source, new BytesRef("invalid"), DataType.KEYWORD), field("input", DataType.KEYWORD)) + ).get(driverContext) + ); + assertThat(e.getMessage(), startsWith("invalid algorithm for [hast(\"invalid\", input)]: invalid MessageDigest not available")); + } + + /** + * The following fields and methods were borrowed from AbstractScalarFunctionTestCase + */ + private final List breakers = Collections.synchronizedList(new ArrayList<>()); + + private DriverContext driverContext() { + BigArrays bigArrays = new MockBigArrays(PageCacheRecycler.NON_RECYCLING_INSTANCE, ByteSizeValue.ofMb(256)).withCircuitBreaking(); + CircuitBreaker breaker = bigArrays.breakerService().getBreaker(CircuitBreaker.REQUEST); + breakers.add(breaker); + return new DriverContext(bigArrays, new BlockFactory(breaker, bigArrays)); + } + + @After + public void allMemoryReleased() { + for (CircuitBreaker breaker : breakers) { + assertThat(breaker.getUsed(), equalTo(0L)); + } + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashTests.java new file mode 100644 index 0000000000000..c5cdf97eccd17 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/HashTests.java @@ -0,0 +1,107 @@ +/* + * 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.esql.expression.function.scalar.string; + +import com.carrotsearch.randomizedtesting.annotations.Name; +import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; + +import org.apache.lucene.util.BytesRef; +import org.elasticsearch.common.lucene.BytesRefs; +import org.elasticsearch.xpack.esql.core.InvalidArgumentException; +import org.elasticsearch.xpack.esql.core.expression.Expression; +import org.elasticsearch.xpack.esql.core.tree.Source; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.expression.function.AbstractScalarFunctionTestCase; +import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.HexFormat; +import java.util.List; +import java.util.function.Supplier; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; + +public class HashTests extends AbstractScalarFunctionTestCase { + + public HashTests(@Name("TestCase") Supplier testCaseSupplier) { + this.testCase = testCaseSupplier.get(); + } + + @ParametersFactory + public static Iterable parameters() { + List cases = new ArrayList<>(); + for (String algorithm : List.of("MD5", "SHA", "SHA-224", "SHA-256", "SHA-384", "SHA-512")) { + cases.addAll(createTestCases(algorithm)); + } + cases.add(new TestCaseSupplier("Invalid algorithm", List.of(DataType.KEYWORD, DataType.KEYWORD), () -> { + var input = randomAlphaOfLength(10); + return new TestCaseSupplier.TestCase( + List.of( + new TestCaseSupplier.TypedData(new BytesRef("invalid"), DataType.KEYWORD, "algorithm"), + new TestCaseSupplier.TypedData(new BytesRef(input), DataType.KEYWORD, "input") + ), + "HashEvaluator[algorithm=Attribute[channel=0], input=Attribute[channel=1]]", + DataType.KEYWORD, + is(nullValue()) + ).withWarning("Line -1:-1: evaluation of [] failed, treating result as null. Only first 20 failures recorded.") + .withWarning("Line -1:-1: java.security.NoSuchAlgorithmException: invalid MessageDigest not available") + .withFoldingException(InvalidArgumentException.class, "invalid algorithm for []: invalid MessageDigest not available"); + })); + return parameterSuppliersFromTypedDataWithDefaultChecks(true, cases, (v, p) -> "string"); + } + + private static List createTestCases(String algorithm) { + return List.of( + createTestCase(algorithm, false, DataType.KEYWORD, DataType.KEYWORD), + createTestCase(algorithm, false, DataType.KEYWORD, DataType.TEXT), + createTestCase(algorithm, false, DataType.TEXT, DataType.KEYWORD), + createTestCase(algorithm, false, DataType.TEXT, DataType.TEXT), + createTestCase(algorithm, true, DataType.KEYWORD, DataType.KEYWORD), + createTestCase(algorithm, true, DataType.KEYWORD, DataType.TEXT), + createTestCase(algorithm, true, DataType.TEXT, DataType.KEYWORD), + createTestCase(algorithm, true, DataType.TEXT, DataType.TEXT) + ); + } + + private static TestCaseSupplier createTestCase(String algorithm, boolean forceLiteral, DataType algorithmType, DataType inputType) { + return new TestCaseSupplier(algorithm, List.of(algorithmType, inputType), () -> { + var input = randomFrom(TestCaseSupplier.stringCases(inputType)).get(); + return new TestCaseSupplier.TestCase( + List.of(createTypedData(algorithm, forceLiteral, algorithmType, "algorithm"), input), + forceLiteral + ? "HashConstantEvaluator[algorithm=" + algorithm + ", input=Attribute[channel=0]]" + : "HashEvaluator[algorithm=Attribute[channel=0], input=Attribute[channel=1]]", + DataType.KEYWORD, + equalTo(new BytesRef(hash(algorithm, BytesRefs.toString(input.data())))) + ); + }); + } + + private static TestCaseSupplier.TypedData createTypedData(String value, boolean forceLiteral, DataType type, String name) { + var data = new TestCaseSupplier.TypedData(new BytesRef(value), type, name); + return forceLiteral ? data.forceLiteral() : data; + } + + private static String hash(String algorithm, String input) { + try { + return HexFormat.of().formatHex(MessageDigest.getInstance(algorithm).digest(input.getBytes(StandardCharsets.UTF_8))); + } catch (NoSuchAlgorithmException e) { + throw new IllegalArgumentException("Unknown algorithm: " + algorithm); + } + } + + @Override + protected Expression build(Source source, List args) { + return new Hash(source, args.get(0), args.get(1)); + } +} diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml index 2a4cde9a680e9..b6d75048591e5 100644 --- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/60_usage.yml @@ -92,7 +92,7 @@ setup: - gt: {esql.functions.to_long: $functions_to_long} - match: {esql.functions.coalesce: $functions_coalesce} # Testing for the entire function set isn't feasbile, so we just check that we return the correct count as an approximation. - - length: {esql.functions: 129} # check the "sister" test below for a likely update to the same esql.functions length check + - length: {esql.functions: 130} # check the "sister" test below for a likely update to the same esql.functions length check --- "Basic ESQL usage output (telemetry) non-snapshot version": @@ -163,4 +163,4 @@ setup: - match: {esql.functions.cos: $functions_cos} - gt: {esql.functions.to_long: $functions_to_long} - match: {esql.functions.coalesce: $functions_coalesce} - - length: {esql.functions: 125} # check the "sister" test above for a likely update to the same esql.functions length check + - length: {esql.functions: 126} # check the "sister" test above for a likely update to the same esql.functions length check From c75e92a5e3d46cfae264fc54c0245be5a328c9c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Cea=20Fontenla?= Date: Wed, 18 Dec 2024 11:13:46 +0100 Subject: [PATCH 31/60] ESQL: Allow using the same index in FROM and LOOKUP (#118768) Changed the logic so that, instead of getting all the indices of the plan and then subtracting the lookup ones, it will now directly ignore the lookup part in the initial calculation. --- .../src/main/resources/lookup-join.csv-spec | 17 ++++++- .../xpack/esql/action/EsqlCapabilities.java | 5 ++ .../xpack/esql/planner/PlannerUtils.java | 24 ++++++++- .../xpack/esql/plugin/ComputeService.java | 49 ++----------------- 4 files changed, 47 insertions(+), 48 deletions(-) diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/lookup-join.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/lookup-join.csv-spec index 8bcc2c2ff3502..e75c68f4a379d 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/lookup-join.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/lookup-join.csv-spec @@ -182,6 +182,22 @@ language_code:integer | language_name:keyword | country:keyword 2 | [German, German, German] | [Austria, Germany, Switzerland] ; +repeatedIndexOnFrom +required_capability: join_lookup_v7 +required_capability: join_lookup_repeated_index_from + +FROM languages_lookup +| LOOKUP JOIN languages_lookup ON language_code +| SORT language_code +; + +language_code:integer | language_name:keyword +1 | English +2 | French +3 | Spanish +4 | German +; + ############################################### # Filtering tests with languages_lookup index ############################################### @@ -1061,4 +1077,3 @@ ignoreOrder:true 2023-10-23T12:27:28.948Z | 172.21.2.113 | 2764889 | QA | null 2023-10-23T12:15:03.360Z | 172.21.2.162 | 3450233 | QA | null ; - diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java index d6c1539088d47..bfc2675d59791 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java @@ -557,6 +557,11 @@ public enum Cap { */ JOIN_LOOKUP_V7(Build.current().isSnapshot()), + /** + * LOOKUP JOIN with the same index as the FROM + */ + JOIN_LOOKUP_REPEATED_INDEX_FROM(JOIN_LOOKUP_V7.isEnabled()), + /** * Fix for https://github.com/elastic/elasticsearch/issues/117054 */ diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/PlannerUtils.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/PlannerUtils.java index 37f89891860d8..a312d048db0ad 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/PlannerUtils.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/planner/PlannerUtils.java @@ -22,6 +22,7 @@ import org.elasticsearch.xpack.esql.core.expression.AttributeSet; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.predicate.Predicates; +import org.elasticsearch.xpack.esql.core.tree.Node; import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; import org.elasticsearch.xpack.esql.core.util.Holder; @@ -40,6 +41,7 @@ import org.elasticsearch.xpack.esql.plan.physical.ExchangeSinkExec; import org.elasticsearch.xpack.esql.plan.physical.ExchangeSourceExec; import org.elasticsearch.xpack.esql.plan.physical.FragmentExec; +import org.elasticsearch.xpack.esql.plan.physical.LookupJoinExec; import org.elasticsearch.xpack.esql.plan.physical.PhysicalPlan; import org.elasticsearch.xpack.esql.planner.mapper.LocalMapper; import org.elasticsearch.xpack.esql.planner.mapper.Mapper; @@ -48,9 +50,12 @@ import org.elasticsearch.xpack.esql.stats.SearchStats; import java.util.ArrayList; +import java.util.Collection; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Function; import static java.util.Arrays.asList; import static org.elasticsearch.index.mapper.MappedFieldType.FieldExtractPreference.DOC_VALUES; @@ -105,10 +110,27 @@ public static Set planConcreteIndices(PhysicalPlan plan) { return Set.of(); } var indices = new LinkedHashSet(); - plan.forEachUp(FragmentExec.class, f -> f.fragment().forEachUp(EsRelation.class, r -> indices.addAll(r.index().concreteIndices()))); + // TODO: This only works for LEFT join, we still need to support RIGHT join + forEachUpWithChildren(plan, node -> { + if (node instanceof FragmentExec f) { + f.fragment().forEachUp(EsRelation.class, r -> indices.addAll(r.index().concreteIndices())); + } + }, node -> node instanceof LookupJoinExec join ? List.of(join.left()) : node.children()); return indices; } + /** + * Similar to {@link Node#forEachUp(Consumer)}, but with a custom callback to get the node children. + */ + private static > void forEachUpWithChildren( + T node, + Consumer action, + Function> childrenGetter + ) { + childrenGetter.apply(node).forEach(c -> forEachUpWithChildren(c, action, childrenGetter)); + action.accept(node); + } + /** * Returns the original indices specified in the FROM command of the query. We need the original query to resolve alias filters. */ diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ComputeService.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ComputeService.java index 9b59b98a7cdc2..e77a2443df2dd 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ComputeService.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/ComputeService.java @@ -63,12 +63,8 @@ import org.elasticsearch.xpack.esql.core.expression.Attribute; import org.elasticsearch.xpack.esql.enrich.EnrichLookupService; import org.elasticsearch.xpack.esql.enrich.LookupFromIndexService; -import org.elasticsearch.xpack.esql.plan.logical.EsRelation; -import org.elasticsearch.xpack.esql.plan.logical.join.Join; import org.elasticsearch.xpack.esql.plan.physical.ExchangeSinkExec; import org.elasticsearch.xpack.esql.plan.physical.ExchangeSourceExec; -import org.elasticsearch.xpack.esql.plan.physical.FragmentExec; -import org.elasticsearch.xpack.esql.plan.physical.LookupJoinExec; import org.elasticsearch.xpack.esql.plan.physical.OutputExec; import org.elasticsearch.xpack.esql.plan.physical.PhysicalPlan; import org.elasticsearch.xpack.esql.planner.EsPhysicalOperationProviders; @@ -81,7 +77,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -167,11 +162,9 @@ public void execute( Map clusterToConcreteIndices = transportService.getRemoteClusterService() .groupIndices(SearchRequest.DEFAULT_INDICES_OPTIONS, PlannerUtils.planConcreteIndices(physicalPlan).toArray(String[]::new)); QueryPragmas queryPragmas = configuration.pragmas(); - Set lookupIndexNames = findLookupIndexNames(physicalPlan); - Set concreteIndexNames = selectConcreteIndices(clusterToConcreteIndices, lookupIndexNames); if (dataNodePlan == null) { - if (concreteIndexNames.isEmpty() == false) { - String error = "expected no concrete indices without data node plan; got " + concreteIndexNames; + if (clusterToConcreteIndices.values().stream().allMatch(v -> v.indices().length == 0) == false) { + String error = "expected no concrete indices without data node plan; got " + clusterToConcreteIndices; assert false : error; listener.onFailure(new IllegalStateException(error)); return; @@ -194,7 +187,7 @@ public void execute( return; } } else { - if (concreteIndexNames.isEmpty()) { + if (clusterToConcreteIndices.values().stream().allMatch(v -> v.indices().length == 0)) { var error = "expected concrete indices with data node plan but got empty; data node plan " + dataNodePlan; assert false : error; listener.onFailure(new IllegalStateException(error)); @@ -268,42 +261,6 @@ public void execute( } } - private Set selectConcreteIndices(Map clusterToConcreteIndices, Set indexesToIgnore) { - Set concreteIndexNames = new HashSet<>(); - clusterToConcreteIndices.forEach((clusterAlias, concreteIndices) -> { - for (String index : concreteIndices.indices()) { - if (indexesToIgnore.contains(index) == false) { - concreteIndexNames.add(index); - } - } - }); - return concreteIndexNames; - } - - private Set findLookupIndexNames(PhysicalPlan physicalPlan) { - Set lookupIndexNames = new HashSet<>(); - // When planning JOIN on the coordinator node: "LookupJoinExec.lookup()->FragmentExec.fragment()->EsRelation.index()" - physicalPlan.forEachDown( - LookupJoinExec.class, - lookupJoinExec -> lookupJoinExec.lookup() - .forEachDown( - FragmentExec.class, - frag -> frag.fragment().forEachDown(EsRelation.class, esRelation -> lookupIndexNames.add(esRelation.index().name())) - ) - ); - // When planning JOIN on the data node: "FragmentExec.fragment()->Join.right()->EsRelation.index()" - // TODO this only works for LEFT join, so we still need to support RIGHT join - physicalPlan.forEachDown( - FragmentExec.class, - fragmentExec -> fragmentExec.fragment() - .forEachDown( - Join.class, - join -> join.right().forEachDown(EsRelation.class, esRelation -> lookupIndexNames.add(esRelation.index().name())) - ) - ); - return lookupIndexNames; - } - // For queries like: FROM logs* | LIMIT 0 (including cross-cluster LIMIT 0 queries) private static void updateShardCountForCoordinatorOnlyQuery(EsqlExecutionInfo execInfo) { if (execInfo.isCrossClusterSearch()) { From 37807b83b7500cbe861817fa1e20aef07d72f6d9 Mon Sep 17 00:00:00 2001 From: Martijn van Groningen Date: Wed, 18 Dec 2024 11:45:41 +0100 Subject: [PATCH 32/60] Support flattened label field with downsampling. (#118816) If flattened field is configured as non-dimension and non-metric field, then downsampling fails to execute successfully. Downsampling doesn't know how to use the flattened field or how to serialize it. This change addresses this. Closes #116319 --- docs/changelog/118816.yaml | 6 + .../flattened/FlattenedFieldMapper.java | 9 +- .../FlattenedFieldSyntheticWriterHelper.java | 8 +- .../downsample/70_flattened_field_type.yml | 307 ++++++++++++++++++ .../xpack/downsample/FieldValueFetcher.java | 11 +- .../xpack/downsample/LabelFieldProducer.java | 42 ++- .../downsample/LabelFieldProducerTests.java | 54 +++ 7 files changed, 428 insertions(+), 9 deletions(-) create mode 100644 docs/changelog/118816.yaml create mode 100644 x-pack/plugin/downsample/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/downsample/70_flattened_field_type.yml diff --git a/docs/changelog/118816.yaml b/docs/changelog/118816.yaml new file mode 100644 index 0000000000000..f1c1eac90dbcf --- /dev/null +++ b/docs/changelog/118816.yaml @@ -0,0 +1,6 @@ +pr: 118816 +summary: Support flattened field with downsampling +area: Downsampling +type: bug +issues: + - 116319 diff --git a/server/src/main/java/org/elasticsearch/index/mapper/flattened/FlattenedFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/flattened/FlattenedFieldMapper.java index 93a2157b2338a..de2632165b0cc 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/flattened/FlattenedFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/flattened/FlattenedFieldMapper.java @@ -52,6 +52,7 @@ import org.elasticsearch.index.mapper.DocumentParserContext; import org.elasticsearch.index.mapper.DynamicFieldType; import org.elasticsearch.index.mapper.FieldMapper; +import org.elasticsearch.index.mapper.KeywordFieldMapper; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.Mapper; import org.elasticsearch.index.mapper.MapperBuilderContext; @@ -670,7 +671,7 @@ public static final class RootFlattenedFieldType extends StringFieldType impleme private final boolean isDimension; private final int ignoreAbove; - public RootFlattenedFieldType( + RootFlattenedFieldType( String name, boolean indexed, boolean hasDocValues, @@ -682,7 +683,7 @@ public RootFlattenedFieldType( this(name, indexed, hasDocValues, meta, splitQueriesOnWhitespace, eagerGlobalOrdinals, Collections.emptyList(), ignoreAbove); } - public RootFlattenedFieldType( + RootFlattenedFieldType( String name, boolean indexed, boolean hasDocValues, @@ -806,6 +807,10 @@ public MappedFieldType getChildFieldType(String childPath) { return new KeyedFlattenedFieldType(name(), childPath, this); } + public MappedFieldType getKeyedFieldType() { + return new KeywordFieldMapper.KeywordFieldType(name() + KEYED_FIELD_SUFFIX); + } + @Override public boolean isDimension() { return isDimension; diff --git a/server/src/main/java/org/elasticsearch/index/mapper/flattened/FlattenedFieldSyntheticWriterHelper.java b/server/src/main/java/org/elasticsearch/index/mapper/flattened/FlattenedFieldSyntheticWriterHelper.java index 950fef95772fb..53f68fb6edeef 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/flattened/FlattenedFieldSyntheticWriterHelper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/flattened/FlattenedFieldSyntheticWriterHelper.java @@ -55,7 +55,7 @@ * }` * */ -class FlattenedFieldSyntheticWriterHelper { +public class FlattenedFieldSyntheticWriterHelper { private record Prefix(List prefix) { @@ -225,17 +225,17 @@ public boolean equals(Object obj) { } } - interface SortedKeyedValues { + public interface SortedKeyedValues { BytesRef next() throws IOException; } private final SortedKeyedValues sortedKeyedValues; - FlattenedFieldSyntheticWriterHelper(final SortedKeyedValues sortedKeyedValues) { + public FlattenedFieldSyntheticWriterHelper(final SortedKeyedValues sortedKeyedValues) { this.sortedKeyedValues = sortedKeyedValues; } - void write(final XContentBuilder b) throws IOException { + public void write(final XContentBuilder b) throws IOException { KeyValue curr = new KeyValue(sortedKeyedValues.next()); KeyValue prev = KeyValue.EMPTY; final List values = new ArrayList<>(); diff --git a/x-pack/plugin/downsample/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/downsample/70_flattened_field_type.yml b/x-pack/plugin/downsample/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/downsample/70_flattened_field_type.yml new file mode 100644 index 0000000000000..0f586ec0ed669 --- /dev/null +++ b/x-pack/plugin/downsample/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/downsample/70_flattened_field_type.yml @@ -0,0 +1,307 @@ +--- +"A flattened label field": + - do: + indices.create: + index: source_index + body: + settings: + number_of_shards: 1 + index: + mode: time_series + routing_path: [ metricset, k8s.pod.uid ] + time_series: + start_time: 2021-04-28T00:00:00Z + end_time: 2021-04-29T00:00:00Z + mappings: + subobjects: false + properties: + "@timestamp": + type: date + metricset: + type: keyword + time_series_dimension: true + k8s: + properties: + pod: + properties: + uid: + type: keyword + time_series_dimension: true + name: + type: keyword + agent: + type: flattened + value: + type: long + time_series_metric: gauge + + - do: + bulk: + refresh: true + index: source_index + body: + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T18:50:04.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507"}, "agent": { "id": "first", "version": "2.0.4" }, "value": 10 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T18:50:24.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507"}, "agent": { "id": "first", "version": "2.0.5" }, "value": 20 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T20:50:44.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507"}, "agent": { "id": "first", "version": "2.0.6" }, "value": 12 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T20:51:04.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507"}, "agent": { "id": "first", "version": "2.0.7" }, "value": 15 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T18:50:03.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9"}, "agent": { "id": "second", "version": "2.1.7" }, "value": 9 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T18:50:23.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9"}, "agent": { "id": "second", "version": "2.1.8" }, "value": 16 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T19:50:53.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9"}, "agent": { "id": "second", "version": "2.1.9" }, "value": 25 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T19:51:03.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9"}, "agent": { "id": "second", "version": "2.1.10" }, "value": 17 }}' + + - do: + indices.put_settings: + index: source_index + body: + index.blocks.write: true + + - do: + indices.downsample: + index: source_index + target_index: target_index + body: > + { + "fixed_interval": "1h" + } + - is_true: acknowledged + + - do: + search: + index: target_index + body: + sort: [ "_tsid", "@timestamp" ] + + - length: { hits.hits: 4 } + - match: { hits.hits.0._source._doc_count: 2 } + - match: { hits.hits.0._source.k8s\.pod\.uid: df3145b3-0563-4d3b-a0f7-897eb2876ea9 } + - match: { hits.hits.0._source.@timestamp: 2021-04-28T18:00:00.000Z } + - match: { hits.hits.0._source.k8s\.agent: { "id": "second", "version": "2.1.8" } } + + - match: { hits.hits.1._source._doc_count: 2 } + - match: { hits.hits.1._source.k8s\.pod\.uid: df3145b3-0563-4d3b-a0f7-897eb2876ea9 } + - match: { hits.hits.1._source.@timestamp: 2021-04-28T19:00:00.000Z } + - match: { hits.hits.1._source.k8s\.agent: { "id": "second", "version": "2.1.10" } } + + - match: { hits.hits.2._source._doc_count: 2 } + - match: { hits.hits.2._source.k8s\.pod\.uid: 947e4ced-1786-4e53-9e0c-5c447e959507 } + - match: { hits.hits.2._source.@timestamp: 2021-04-28T18:00:00.000Z } + - match: { hits.hits.2._source.k8s\.agent: { "id": "first", "version": "2.0.5" } } + + - match: { hits.hits.3._source._doc_count: 2 } + - match: { hits.hits.3._source.k8s\.pod\.uid: 947e4ced-1786-4e53-9e0c-5c447e959507 } + - match: { hits.hits.3._source.@timestamp: 2021-04-28T20:00:00.000Z } + - match: { hits.hits.3._source.k8s\.agent: { "id": "first", "version": "2.0.7" } } + +--- +"A flattened label field with no doc values": + - do: + indices.create: + index: source_index + body: + settings: + number_of_shards: 1 + index: + mode: time_series + routing_path: [ metricset, k8s.pod.uid ] + time_series: + start_time: 2021-04-28T00:00:00Z + end_time: 2021-04-29T00:00:00Z + mappings: + subobjects: false + properties: + "@timestamp": + type: date + metricset: + type: keyword + time_series_dimension: true + k8s: + properties: + pod: + properties: + uid: + type: keyword + time_series_dimension: true + name: + type: keyword + agent: + type: flattened + doc_values: false + value: + type: long + time_series_metric: gauge + + - do: + bulk: + refresh: true + index: source_index + body: + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T18:50:04.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507"}, "agent": { "id": "first", "version": "2.0.4" }, "value": 10 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T18:50:24.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507"}, "agent": { "id": "first", "version": "2.0.5" }, "value": 20 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T20:50:44.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507"}, "agent": { "id": "first", "version": "2.0.6" }, "value": 12 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T20:51:04.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507"}, "agent": { "id": "first", "version": "2.0.7" }, "value": 15 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T18:50:03.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9"}, "agent": { "id": "second", "version": "2.1.7" }, "value": 9 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T18:50:23.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9"}, "agent": { "id": "second", "version": "2.1.8" }, "value": 16 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T19:50:53.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9"}, "agent": { "id": "second", "version": "2.1.9" }, "value": 25 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T19:51:03.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9"}, "agent": { "id": "second", "version": "2.1.10" }, "value": 17 }}' + + - do: + indices.put_settings: + index: source_index + body: + index.blocks.write: true + + - do: + indices.downsample: + index: source_index + target_index: target_index + body: > + { + "fixed_interval": "1h" + } + - is_true: acknowledged + + - do: + search: + index: target_index + body: + sort: [ "_tsid", "@timestamp" ] + + - length: { hits.hits: 4 } + - match: { hits.hits.0._source._doc_count: 2 } + - match: { hits.hits.0._source.k8s\.pod\.uid: df3145b3-0563-4d3b-a0f7-897eb2876ea9 } + - match: { hits.hits.0._source.@timestamp: 2021-04-28T18:00:00.000Z } + - is_false: hits.hits.0._source.k8s\.agent + + - match: { hits.hits.1._source._doc_count: 2 } + - match: { hits.hits.1._source.k8s\.pod\.uid: df3145b3-0563-4d3b-a0f7-897eb2876ea9 } + - match: { hits.hits.1._source.@timestamp: 2021-04-28T19:00:00.000Z } + - is_false: hits.hits.1._source.k8s\.agent + + - match: { hits.hits.2._source._doc_count: 2 } + - match: { hits.hits.2._source.k8s\.pod\.uid: 947e4ced-1786-4e53-9e0c-5c447e959507 } + - match: { hits.hits.2._source.@timestamp: 2021-04-28T18:00:00.000Z } + - is_false: hits.hits.2._source.k8s\.agent + + - match: { hits.hits.3._source._doc_count: 2 } + - match: { hits.hits.3._source.k8s\.pod\.uid: 947e4ced-1786-4e53-9e0c-5c447e959507 } + - match: { hits.hits.3._source.@timestamp: 2021-04-28T20:00:00.000Z } + - is_false: hits.hits.3._source.k8s\.agent + +--- +"A flattened label field with mixed content": + - do: + indices.create: + index: source_index + body: + settings: + number_of_shards: 1 + index: + mode: time_series + routing_path: [ metricset, k8s.pod.uid ] + time_series: + start_time: 2021-04-28T00:00:00Z + end_time: 2021-04-29T00:00:00Z + mappings: + subobjects: false + properties: + "@timestamp": + type: date + metricset: + type: keyword + time_series_dimension: true + k8s: + properties: + pod: + properties: + uid: + type: keyword + time_series_dimension: true + name: + type: keyword + agent: + type: flattened + null_value: my_null_value + value: + type: long + time_series_metric: gauge + + - do: + bulk: + refresh: true + index: source_index + body: + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T18:50:04.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507"}, "agent": { "id": "first", "version": "2.0.4", "versions": ["1", "2", "3"], "optional_version": null, "dotted.version": "1.1", "numeric_version": 11 }, "value": 10 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T18:50:24.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507"}, "agent": { "id": "first", "version": "2.0.5", "versions": ["1", "2", "3"], "optional_version": null, "dotted.version": "1.1", "numeric_version": 11}, "value": 20 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T20:50:44.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507"}, "agent": { "id": "first", "version": "2.0.6", "versions": ["1", "2", "3"], "optional_version": null, "dotted.version": "1.1", "numeric_version": 11}, "value": 12 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T20:51:04.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507"}, "agent": { "id": "first", "version": "2.0.7", "versions": ["1", "2", "3"], "optional_version": null, "dotted.version": "1.1", "numeric_version": 11}, "value": 15 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T18:50:03.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9"}, "agent": { "id": "second", "version": "2.1.7", "versions": ["1", "2", "3"], "optional_version": null, "dotted.version": "1.1", "numeric_version": 11}, "value": 9 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T18:50:23.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9"}, "agent": { "id": "second", "version": "2.1.8", "versions": ["1", "2", "3"], "optional_version": null, "dotted.version": "1.1", "numeric_version": 11}, "value": 16 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T19:50:53.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9"}, "agent": { "id": "second", "version": "2.1.9", "versions": ["1", "2", "3"], "optional_version": null, "dotted.version": "1.1", "numeric_version": 11}, "value": 25 }}' + - '{"index": {}}' + - '{"@timestamp": "2021-04-28T19:51:03.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9"}, "agent": { "id": "second", "version": "2.1.10", "versions": ["1", "2", "3"], "optional_version": null, "dotted.version": "1.1", "numeric_version": 11}, "value": 17 }}' + + - do: + indices.put_settings: + index: source_index + body: + index.blocks.write: true + + - do: + indices.downsample: + index: source_index + target_index: target_index + body: > + { + "fixed_interval": "1h" + } + - is_true: acknowledged + + - do: + search: + index: target_index + body: + sort: [ "_tsid", "@timestamp" ] + + - length: { hits.hits: 4 } + - match: { hits.hits.0._source._doc_count: 2 } + - match: { hits.hits.0._source.k8s\.pod\.uid: df3145b3-0563-4d3b-a0f7-897eb2876ea9 } + - match: { hits.hits.0._source.@timestamp: 2021-04-28T18:00:00.000Z } + - match: { hits.hits.0._source.k8s\.agent: { "id": "second", "version": "2.1.8", "versions": ["1", "2", "3"], "dotted": {"version": "1.1"}, "numeric_version": "11", optional_version: "my_null_value" } } + + - match: { hits.hits.1._source._doc_count: 2 } + - match: { hits.hits.1._source.k8s\.pod\.uid: df3145b3-0563-4d3b-a0f7-897eb2876ea9 } + - match: { hits.hits.1._source.@timestamp: 2021-04-28T19:00:00.000Z } + - match: { hits.hits.1._source.k8s\.agent: { "id": "second", "version": "2.1.10", "versions": ["1", "2", "3"], "dotted": {"version": "1.1"}, "numeric_version": "11", optional_version: "my_null_value" } } + + - match: { hits.hits.2._source._doc_count: 2 } + - match: { hits.hits.2._source.k8s\.pod\.uid: 947e4ced-1786-4e53-9e0c-5c447e959507 } + - match: { hits.hits.2._source.@timestamp: 2021-04-28T18:00:00.000Z } + - match: { hits.hits.2._source.k8s\.agent: { "id": "first", "version": "2.0.5", "versions": ["1", "2", "3"], "dotted": {"version": "1.1"}, "numeric_version": "11", optional_version: "my_null_value" } } + + - match: { hits.hits.3._source._doc_count: 2 } + - match: { hits.hits.3._source.k8s\.pod\.uid: 947e4ced-1786-4e53-9e0c-5c447e959507 } + - match: { hits.hits.3._source.@timestamp: 2021-04-28T20:00:00.000Z } + - match: { hits.hits.3._source.k8s\.agent: { "id": "first", "version": "2.0.7", "versions": ["1", "2", "3"], "dotted": {"version": "1.1"}, "numeric_version": "11", optional_version: "my_null_value" } } diff --git a/x-pack/plugin/downsample/src/main/java/org/elasticsearch/xpack/downsample/FieldValueFetcher.java b/x-pack/plugin/downsample/src/main/java/org/elasticsearch/xpack/downsample/FieldValueFetcher.java index 74375bbe27939..3657e4989ccbd 100644 --- a/x-pack/plugin/downsample/src/main/java/org/elasticsearch/xpack/downsample/FieldValueFetcher.java +++ b/x-pack/plugin/downsample/src/main/java/org/elasticsearch/xpack/downsample/FieldValueFetcher.java @@ -12,6 +12,7 @@ import org.elasticsearch.index.fielddata.IndexFieldData; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.NumberFieldMapper; +import org.elasticsearch.index.mapper.flattened.FlattenedFieldMapper; import org.elasticsearch.index.query.SearchExecutionContext; import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.xpack.aggregatemetric.mapper.AggregateDoubleMetricFieldMapper; @@ -65,6 +66,8 @@ private AbstractDownsampleFieldProducer createFieldProducer() { // If field is not a metric, we downsample it as a label if ("histogram".equals(fieldType.typeName())) { return new LabelFieldProducer.HistogramLastLabelFieldProducer(name()); + } else if ("flattened".equals(fieldType.typeName())) { + return new LabelFieldProducer.FlattenedLastValueFieldProducer(name()); } return new LabelFieldProducer.LabelLastValueFieldProducer(name()); } @@ -90,7 +93,13 @@ static List create(SearchExecutionContext context, String[] f } } else { if (context.fieldExistsInIndex(field)) { - final IndexFieldData fieldData = context.getForField(fieldType, MappedFieldType.FielddataOperation.SEARCH); + final IndexFieldData fieldData; + if (fieldType instanceof FlattenedFieldMapper.RootFlattenedFieldType flattenedFieldType) { + var keyedFieldType = flattenedFieldType.getKeyedFieldType(); + fieldData = context.getForField(keyedFieldType, MappedFieldType.FielddataOperation.SEARCH); + } else { + fieldData = context.getForField(fieldType, MappedFieldType.FielddataOperation.SEARCH); + } final String fieldName = context.isMultiField(field) ? fieldType.name().substring(0, fieldType.name().lastIndexOf('.')) : fieldType.name(); diff --git a/x-pack/plugin/downsample/src/main/java/org/elasticsearch/xpack/downsample/LabelFieldProducer.java b/x-pack/plugin/downsample/src/main/java/org/elasticsearch/xpack/downsample/LabelFieldProducer.java index 05b4852d0dfd3..b211c5bfb0d12 100644 --- a/x-pack/plugin/downsample/src/main/java/org/elasticsearch/xpack/downsample/LabelFieldProducer.java +++ b/x-pack/plugin/downsample/src/main/java/org/elasticsearch/xpack/downsample/LabelFieldProducer.java @@ -7,8 +7,10 @@ package org.elasticsearch.xpack.downsample; +import org.apache.lucene.util.BytesRef; import org.elasticsearch.index.fielddata.FormattedDocValues; import org.elasticsearch.index.fielddata.HistogramValue; +import org.elasticsearch.index.mapper.flattened.FlattenedFieldSyntheticWriterHelper; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xpack.aggregatemetric.mapper.AggregateDoubleMetricFieldMapper.Metric; @@ -141,14 +143,14 @@ public void reset() { } } - static class AggregateMetricFieldProducer extends LabelLastValueFieldProducer { + static final class AggregateMetricFieldProducer extends LabelLastValueFieldProducer { AggregateMetricFieldProducer(String name, Metric metric) { super(name, new LastValueLabel(metric.name())); } } - public static class HistogramLastLabelFieldProducer extends LabelLastValueFieldProducer { + static final class HistogramLastLabelFieldProducer extends LabelLastValueFieldProducer { HistogramLastLabelFieldProducer(String name) { super(name); } @@ -167,4 +169,40 @@ public void write(XContentBuilder builder) throws IOException { } } } + + static final class FlattenedLastValueFieldProducer extends LabelLastValueFieldProducer { + + FlattenedLastValueFieldProducer(String name) { + super(name); + } + + @Override + public void write(XContentBuilder builder) throws IOException { + if (isEmpty() == false) { + builder.startObject(name()); + + var value = label.get(); + List list; + if (value instanceof Object[] values) { + list = new ArrayList<>(values.length); + for (Object v : values) { + list.add(new BytesRef(v.toString())); + } + } else { + list = List.of(new BytesRef(value.toString())); + } + + var iterator = list.iterator(); + var helper = new FlattenedFieldSyntheticWriterHelper(() -> { + if (iterator.hasNext()) { + return iterator.next(); + } else { + return null; + } + }); + helper.write(builder); + builder.endObject(); + } + } + } } diff --git a/x-pack/plugin/downsample/src/test/java/org/elasticsearch/xpack/downsample/LabelFieldProducerTests.java b/x-pack/plugin/downsample/src/test/java/org/elasticsearch/xpack/downsample/LabelFieldProducerTests.java index 469e00f7af9af..844eb1b8e27d8 100644 --- a/x-pack/plugin/downsample/src/test/java/org/elasticsearch/xpack/downsample/LabelFieldProducerTests.java +++ b/x-pack/plugin/downsample/src/test/java/org/elasticsearch/xpack/downsample/LabelFieldProducerTests.java @@ -7,10 +7,18 @@ package org.elasticsearch.xpack.downsample; +import org.elasticsearch.common.Strings; import org.elasticsearch.index.fielddata.FormattedDocValues; import org.elasticsearch.search.aggregations.AggregatorTestCase; +import org.elasticsearch.xcontent.XContentBuilder; +import org.elasticsearch.xcontent.XContentType; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +import static org.hamcrest.Matchers.equalTo; public class LabelFieldProducerTests extends AggregatorTestCase { @@ -93,4 +101,50 @@ public Object nextValue() { assertTrue(producer.isEmpty()); assertNull(producer.label().get()); } + + public void testFlattenedLastValueFieldProducer() throws IOException { + var producer = new LabelFieldProducer.FlattenedLastValueFieldProducer("dummy"); + assertTrue(producer.isEmpty()); + assertEquals("dummy", producer.name()); + assertEquals("last_value", producer.label().name()); + + var bytes = List.of("a\0value_a", "b\0value_b", "c\0value_c", "d\0value_d"); + var docValues = new FormattedDocValues() { + + Iterator iterator = bytes.iterator(); + + @Override + public boolean advanceExact(int docId) { + return true; + } + + @Override + public int docValueCount() { + return bytes.size(); + } + + @Override + public Object nextValue() { + return iterator.next(); + } + }; + + producer.collect(docValues, 1); + assertFalse(producer.isEmpty()); + assertEquals("a\0value_a", (((Object[]) producer.label().get())[0]).toString()); + assertEquals("b\0value_b", (((Object[]) producer.label().get())[1]).toString()); + assertEquals("c\0value_c", (((Object[]) producer.label().get())[2]).toString()); + assertEquals("d\0value_d", (((Object[]) producer.label().get())[3]).toString()); + + var builder = new XContentBuilder(XContentType.JSON.xContent(), new ByteArrayOutputStream()); + builder.startObject(); + producer.write(builder); + builder.endObject(); + var content = Strings.toString(builder); + assertThat(content, equalTo("{\"dummy\":{\"a\":\"value_a\",\"b\":\"value_b\",\"c\":\"value_c\",\"d\":\"value_d\"}}")); + + producer.reset(); + assertTrue(producer.isEmpty()); + assertNull(producer.label().get()); + } } From b34867115cee9461f6aaf67aee05fb2c303b6f7d Mon Sep 17 00:00:00 2001 From: Andrei Stefan Date: Wed, 18 Dec 2024 13:09:33 +0200 Subject: [PATCH 33/60] Lookup join on multiple join fields not yet supported (#118858) --- docs/changelog/118858.yaml | 5 +++ .../xpack/esql/parser/LogicalPlanBuilder.java | 5 +++ .../xpack/esql/analysis/ParsingTests.java | 41 +++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 docs/changelog/118858.yaml diff --git a/docs/changelog/118858.yaml b/docs/changelog/118858.yaml new file mode 100644 index 0000000000000..a2161df1c84c7 --- /dev/null +++ b/docs/changelog/118858.yaml @@ -0,0 +1,5 @@ +pr: 118858 +summary: Lookup join on multiple join fields not yet supported +area: ES|QL +type: enhancement +issues: [] diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java index 24398afa18010..49d77bc36fb2e 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/parser/LogicalPlanBuilder.java @@ -564,6 +564,11 @@ public PlanFactory visitJoinCommand(EsqlBaseParser.JoinCommandContext ctx) { } } + var matchFieldsCount = joinFields.size(); + if (matchFieldsCount > 1) { + throw new ParsingException(source, "JOIN ON clause only supports one field at the moment, found [{}]", matchFieldsCount); + } + return p -> new LookupJoin(source, p, right, joinFields); } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java index 205c8943d4e3c..90a215653f251 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java @@ -12,6 +12,7 @@ import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.json.JsonXContent; import org.elasticsearch.xpack.esql.LoadMapping; +import org.elasticsearch.xpack.esql.action.EsqlCapabilities; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.type.DataType; import org.elasticsearch.xpack.esql.expression.function.EsqlFunctionRegistry; @@ -111,6 +112,46 @@ public void testTooBigQuery() { assertEquals("-1:-1: ESQL statement is too large [1000011 characters > 1000000]", error(query.toString())); } + public void testJoinOnConstant() { + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assertEquals( + "1:55: JOIN ON clause only supports fields at the moment, found [123]", + error("row languages = 1, gender = \"f\" | lookup join test on 123") + ); + assertEquals( + "1:55: JOIN ON clause only supports fields at the moment, found [\"abc\"]", + error("row languages = 1, gender = \"f\" | lookup join test on \"abc\"") + ); + assertEquals( + "1:55: JOIN ON clause only supports fields at the moment, found [false]", + error("row languages = 1, gender = \"f\" | lookup join test on false") + ); + } + + public void testJoinOnMultipleFields() { + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assertEquals( + "1:35: JOIN ON clause only supports one field at the moment, found [2]", + error("row languages = 1, gender = \"f\" | lookup join test on gender, languages") + ); + } + + public void testJoinTwiceOnTheSameField() { + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assertEquals( + "1:35: JOIN ON clause only supports one field at the moment, found [2]", + error("row languages = 1, gender = \"f\" | lookup join test on languages, languages") + ); + } + + public void testJoinTwiceOnTheSameField_TwoLookups() { + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assertEquals( + "1:80: JOIN ON clause only supports one field at the moment, found [2]", + error("row languages = 1, gender = \"f\" | lookup join test on languages | eval x = 1 | lookup join test on gender, gender") + ); + } + private String functionName(EsqlFunctionRegistry registry, Expression functionCall) { for (FunctionDefinition def : registry.listFunctions()) { if (functionCall.getClass().equals(def.clazz())) { From 4974336221f3b26678bc31ded4b34083e35523ae Mon Sep 17 00:00:00 2001 From: Martijn van Groningen Date: Wed, 18 Dec 2024 12:25:27 +0100 Subject: [PATCH 34/60] Fix synthetic recovery source version validation. (#118924) The validation didn't work as expected, because created version was always 0 (which is created version default value). Moving the validation to a place that does have access to the index version. --- .../indices.create/20_synthetic_source.yml | 39 ++++++++++++++ .../elasticsearch/index/IndexSettings.java | 38 ++++++------- .../index/mapper/MapperFeatures.java | 3 +- .../index/mapper/SourceFieldMapper.java | 1 + .../index/mapper/SourceFieldMapperTests.java | 54 ------------------- 5 files changed, 61 insertions(+), 74 deletions(-) diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.create/20_synthetic_source.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.create/20_synthetic_source.yml index af3d88fb35734..fc0bfa144bbc4 100644 --- a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.create/20_synthetic_source.yml +++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.create/20_synthetic_source.yml @@ -2012,3 +2012,42 @@ synthetic_source with copy_to pointing inside dynamic object: hits.hits.2.fields: c.copy.keyword: [ "hello", "zap" ] +--- +create index with use_synthetic_source: + - requires: + cluster_features: ["mapper.synthetic_recovery_source"] + reason: requires synthetic recovery source + + - do: + indices.create: + index: test + body: + settings: + index: + recovery: + use_synthetic_source: true + mapping: + source: + mode: synthetic + + - do: + indices.get_settings: {} + - match: { test.settings.index.mapping.source.mode: synthetic} + - is_true: test.settings.index.recovery.use_synthetic_source + + - do: + bulk: + index: test + refresh: true + body: + - '{ "create": { } }' + - '{ "field": "aaaa" }' + - '{ "create": { } }' + - '{ "field": "bbbb" }' + + - do: + indices.disk_usage: + index: test + run_expensive_tasks: true + - gt: { test.fields.field.total_in_bytes: 0 } + - is_false: test.fields.field._recovery_source diff --git a/server/src/main/java/org/elasticsearch/index/IndexSettings.java b/server/src/main/java/org/elasticsearch/index/IndexSettings.java index b15828c5594ae..9273888b9ec91 100644 --- a/server/src/main/java/org/elasticsearch/index/IndexSettings.java +++ b/server/src/main/java/org/elasticsearch/index/IndexSettings.java @@ -685,29 +685,11 @@ public void validate(Boolean enabled, Map, Object> settings) { ); } } - - // Verify that all nodes can handle this setting - var version = (IndexVersion) settings.get(SETTING_INDEX_VERSION_CREATED); - if (version.before(IndexVersions.USE_SYNTHETIC_SOURCE_FOR_RECOVERY) - && version.between( - IndexVersions.USE_SYNTHETIC_SOURCE_FOR_RECOVERY_BACKPORT, - IndexVersions.UPGRADE_TO_LUCENE_10_0_0 - ) == false) { - throw new IllegalArgumentException( - String.format( - Locale.ROOT, - "The setting [%s] is unavailable on this cluster because some nodes are running older " - + "versions that do not support it. Please upgrade all nodes to the latest version " - + "and try again.", - RECOVERY_USE_SYNTHETIC_SOURCE_SETTING.getKey() - ) - ); - } } @Override public Iterator> settings() { - List> res = List.of(INDEX_MAPPER_SOURCE_MODE_SETTING, SETTING_INDEX_VERSION_CREATED, MODE); + List> res = List.of(INDEX_MAPPER_SOURCE_MODE_SETTING, MODE); return res.iterator(); } }, @@ -1050,6 +1032,24 @@ public IndexSettings(final IndexMetadata indexMetadata, final Settings nodeSetti indexMappingSourceMode = scopedSettings.get(INDEX_MAPPER_SOURCE_MODE_SETTING); recoverySourceEnabled = RecoverySettings.INDICES_RECOVERY_SOURCE_ENABLED_SETTING.get(nodeSettings); recoverySourceSyntheticEnabled = scopedSettings.get(RECOVERY_USE_SYNTHETIC_SOURCE_SETTING); + if (recoverySourceSyntheticEnabled) { + // Verify that all nodes can handle this setting + if (version.before(IndexVersions.USE_SYNTHETIC_SOURCE_FOR_RECOVERY) + && version.between( + IndexVersions.USE_SYNTHETIC_SOURCE_FOR_RECOVERY_BACKPORT, + IndexVersions.UPGRADE_TO_LUCENE_10_0_0 + ) == false) { + throw new IllegalArgumentException( + String.format( + Locale.ROOT, + "The setting [%s] is unavailable on this cluster because some nodes are running older " + + "versions that do not support it. Please upgrade all nodes to the latest version " + + "and try again.", + RECOVERY_USE_SYNTHETIC_SOURCE_SETTING.getKey() + ) + ); + } + } scopedSettings.addSettingsUpdateConsumer( MergePolicyConfig.INDEX_COMPOUND_FORMAT_SETTING, diff --git a/server/src/main/java/org/elasticsearch/index/mapper/MapperFeatures.java b/server/src/main/java/org/elasticsearch/index/mapper/MapperFeatures.java index 276d3e151361c..5dbaf0e0f40ad 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/MapperFeatures.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/MapperFeatures.java @@ -77,7 +77,8 @@ public Set getTestFeatures() { DocumentParser.FIX_PARSING_SUBOBJECTS_FALSE_DYNAMIC_FALSE, CONSTANT_KEYWORD_SYNTHETIC_SOURCE_WRITE_FIX, META_FETCH_FIELDS_ERROR_CODE_CHANGED, - SPARSE_VECTOR_STORE_SUPPORT + SPARSE_VECTOR_STORE_SUPPORT, + SourceFieldMapper.SYNTHETIC_RECOVERY_SOURCE ); } } diff --git a/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java index 85f4217811a84..5f1ba6f0ab2a1 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/SourceFieldMapper.java @@ -56,6 +56,7 @@ public class SourceFieldMapper extends MetadataFieldMapper { "mapper.source.remove_synthetic_source_only_validation" ); public static final NodeFeature SOURCE_MODE_FROM_INDEX_SETTING = new NodeFeature("mapper.source.mode_from_index_setting"); + public static final NodeFeature SYNTHETIC_RECOVERY_SOURCE = new NodeFeature("mapper.synthetic_recovery_source"); public static final String NAME = "_source"; public static final String RECOVERY_SOURCE_NAME = "_recovery_source"; diff --git a/server/src/test/java/org/elasticsearch/index/mapper/SourceFieldMapperTests.java b/server/src/test/java/org/elasticsearch/index/mapper/SourceFieldMapperTests.java index 378920d0e6db5..b7693513a434d 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/SourceFieldMapperTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/SourceFieldMapperTests.java @@ -465,60 +465,6 @@ public void testRecoverySourceWitInvalidSettings() { ) ); } - { - Settings settings = Settings.builder() - .put(SourceFieldMapper.INDEX_MAPPER_SOURCE_MODE_SETTING.getKey(), SourceFieldMapper.Mode.SYNTHETIC.toString()) - .put(IndexSettings.RECOVERY_USE_SYNTHETIC_SOURCE_SETTING.getKey(), true) - .build(); - IllegalArgumentException exc = expectThrows( - IllegalArgumentException.class, - () -> createMapperService( - IndexVersionUtils.randomPreviousCompatibleVersion(random(), IndexVersions.USE_SYNTHETIC_SOURCE_FOR_RECOVERY_BACKPORT), - settings, - () -> false, - topMapping(b -> {}) - ) - ); - assertThat( - exc.getMessage(), - containsString( - String.format( - Locale.ROOT, - "The setting [%s] is unavailable on this cluster", - IndexSettings.RECOVERY_USE_SYNTHETIC_SOURCE_SETTING.getKey() - ) - ) - ); - } - { - Settings settings = Settings.builder() - .put(SourceFieldMapper.INDEX_MAPPER_SOURCE_MODE_SETTING.getKey(), SourceFieldMapper.Mode.SYNTHETIC.toString()) - .put(IndexSettings.RECOVERY_USE_SYNTHETIC_SOURCE_SETTING.getKey(), true) - .build(); - IllegalArgumentException exc = expectThrows( - IllegalArgumentException.class, - () -> createMapperService( - IndexVersionUtils.randomVersionBetween( - random(), - IndexVersions.UPGRADE_TO_LUCENE_10_0_0, - IndexVersions.DEPRECATE_SOURCE_MODE_MAPPER - ), - settings, - () -> false, - topMapping(b -> {}) - ) - ); - assertThat( - exc.getMessage(), - containsString( - String.format( - Locale.ROOT, - "The setting [%s] is unavailable on this cluster", - IndexSettings.RECOVERY_USE_SYNTHETIC_SOURCE_SETTING.getKey() - ) - ) - ); - } } public void testRecoverySourceWithSyntheticSource() throws IOException { From 4fbe306a1e0d137ae299dab44659a263a7f9dc46 Mon Sep 17 00:00:00 2001 From: Rene Groeschke Date: Wed, 18 Dec 2024 12:57:33 +0100 Subject: [PATCH 35/60] Revert "Support mTLS in Elastic Inference Service plugin (#116423)" (#118765) (#118902) --- docs/changelog/116423.yaml | 5 - .../xpack/core/ssl/SSLService.java | 2 - .../core/LocalStateCompositeXPackPlugin.java | 2 +- .../xpack/core/ssl/SSLServiceTests.java | 3 +- .../ShardBulkInferenceActionFilterIT.java | 3 +- .../integration/ModelRegistryIT.java | 4 +- .../inference/src/main/java/module-info.java | 1 - .../xpack/inference/InferencePlugin.java | 101 +++++------------- .../external/http/HttpClientManager.java | 44 -------- .../TextSimilarityRankRetrieverBuilder.java | 11 +- .../ElasticInferenceServiceSettings.java | 24 +---- .../SemanticTextClusterMetadataTests.java | 3 +- .../xpack/inference/InferencePluginTests.java | 65 ----------- .../inference/LocalStateInferencePlugin.java | 71 ------------ .../elasticsearch/xpack/inference/Utils.java | 15 +++ ...emanticTextNonDynamicFieldMapperTests.java | 3 +- .../TextSimilarityRankMultiNodeTests.java | 4 +- ...SimilarityRankRetrieverTelemetryTests.java | 5 +- .../TextSimilarityRankTests.java | 4 +- .../xpack/ml/LocalStateMachineLearning.java | 7 -- .../xpack/ml/support/BaseMlIntegTestCase.java | 4 +- .../security/CrossClusterShardTests.java | 2 + 22 files changed, 69 insertions(+), 314 deletions(-) delete mode 100644 docs/changelog/116423.yaml delete mode 100644 x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/InferencePluginTests.java delete mode 100644 x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/LocalStateInferencePlugin.java diff --git a/docs/changelog/116423.yaml b/docs/changelog/116423.yaml deleted file mode 100644 index d6d10eab410e4..0000000000000 --- a/docs/changelog/116423.yaml +++ /dev/null @@ -1,5 +0,0 @@ -pr: 116423 -summary: Support mTLS for the Elastic Inference Service integration inside the inference API -area: Machine Learning -type: feature -issues: [] diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ssl/SSLService.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ssl/SSLService.java index d0d5e463f9652..9704335776f11 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ssl/SSLService.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ssl/SSLService.java @@ -596,8 +596,6 @@ static Map getSSLSettingsMap(Settings settings) { sslSettingsMap.put(WatcherField.EMAIL_NOTIFICATION_SSL_PREFIX, settings.getByPrefix(WatcherField.EMAIL_NOTIFICATION_SSL_PREFIX)); sslSettingsMap.put(XPackSettings.TRANSPORT_SSL_PREFIX, settings.getByPrefix(XPackSettings.TRANSPORT_SSL_PREFIX)); sslSettingsMap.putAll(getTransportProfileSSLSettings(settings)); - // Mount Elastic Inference Service (part of the Inference plugin) configuration - sslSettingsMap.put("xpack.inference.elastic.http.ssl", settings.getByPrefix("xpack.inference.elastic.http.ssl.")); // Only build remote cluster server SSL if the port is enabled if (REMOTE_CLUSTER_SERVER_ENABLED.get(settings)) { sslSettingsMap.put(XPackSettings.REMOTE_CLUSTER_SERVER_SSL_PREFIX, getRemoteClusterServerSslSettings(settings)); diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/LocalStateCompositeXPackPlugin.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/LocalStateCompositeXPackPlugin.java index d50f7bb27a5df..1f2c89c473a62 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/LocalStateCompositeXPackPlugin.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/LocalStateCompositeXPackPlugin.java @@ -623,7 +623,7 @@ public Map getSnapshotCommitSup } @SuppressWarnings("unchecked") - protected List filterPlugins(Class type) { + private List filterPlugins(Class type) { return plugins.stream().filter(x -> type.isAssignableFrom(x.getClass())).map(p -> ((T) p)).collect(Collectors.toList()); } diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ssl/SSLServiceTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ssl/SSLServiceTests.java index bfac286bc3c35..9663e41a647a8 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ssl/SSLServiceTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ssl/SSLServiceTests.java @@ -614,8 +614,7 @@ public void testGetConfigurationByContextName() throws Exception { "xpack.security.authc.realms.ldap.realm1.ssl", "xpack.security.authc.realms.saml.realm2.ssl", "xpack.monitoring.exporters.mon1.ssl", - "xpack.monitoring.exporters.mon2.ssl", - "xpack.inference.elastic.http.ssl" }; + "xpack.monitoring.exporters.mon2.ssl" }; assumeTrue("Not enough cipher suites are available to support this test", getCipherSuites.length >= contextNames.length); diff --git a/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/action/filter/ShardBulkInferenceActionFilterIT.java b/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/action/filter/ShardBulkInferenceActionFilterIT.java index c7b3a9d42f579..3b0fc869c8124 100644 --- a/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/action/filter/ShardBulkInferenceActionFilterIT.java +++ b/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/action/filter/ShardBulkInferenceActionFilterIT.java @@ -22,7 +22,6 @@ import org.elasticsearch.plugins.Plugin; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.test.ESIntegTestCase; -import org.elasticsearch.xpack.inference.LocalStateInferencePlugin; import org.elasticsearch.xpack.inference.Utils; import org.elasticsearch.xpack.inference.mock.TestDenseInferenceServiceExtension; import org.elasticsearch.xpack.inference.mock.TestSparseInferenceServiceExtension; @@ -59,7 +58,7 @@ public void setup() throws Exception { @Override protected Collection> nodePlugins() { - return Arrays.asList(LocalStateInferencePlugin.class); + return Arrays.asList(Utils.TestInferencePlugin.class); } public void testBulkOperations() throws Exception { diff --git a/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/integration/ModelRegistryIT.java b/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/integration/ModelRegistryIT.java index d5c156d1d4f46..be6b3725b0f35 100644 --- a/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/integration/ModelRegistryIT.java +++ b/x-pack/plugin/inference/src/internalClusterTest/java/org/elasticsearch/xpack/inference/integration/ModelRegistryIT.java @@ -31,7 +31,7 @@ import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.xcontent.ToXContentObject; import org.elasticsearch.xcontent.XContentBuilder; -import org.elasticsearch.xpack.inference.LocalStateInferencePlugin; +import org.elasticsearch.xpack.inference.InferencePlugin; import org.elasticsearch.xpack.inference.chunking.ChunkingSettingsTests; import org.elasticsearch.xpack.inference.registry.ModelRegistry; import org.elasticsearch.xpack.inference.services.elasticsearch.ElasticsearchInternalModel; @@ -76,7 +76,7 @@ public void createComponents() { @Override protected Collection> getPlugins() { - return pluginList(ReindexPlugin.class, LocalStateInferencePlugin.class); + return pluginList(ReindexPlugin.class, InferencePlugin.class); } public void testStoreModel() throws Exception { diff --git a/x-pack/plugin/inference/src/main/java/module-info.java b/x-pack/plugin/inference/src/main/java/module-info.java index 1c2240e8c5217..53974657e4e23 100644 --- a/x-pack/plugin/inference/src/main/java/module-info.java +++ b/x-pack/plugin/inference/src/main/java/module-info.java @@ -34,7 +34,6 @@ requires software.amazon.awssdk.retries.api; requires org.reactivestreams; requires org.elasticsearch.logging; - requires org.elasticsearch.sslconfig; exports org.elasticsearch.xpack.inference.action; exports org.elasticsearch.xpack.inference.registry; diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java index 169c8f87043e8..72fa840ad19b0 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/InferencePlugin.java @@ -28,7 +28,6 @@ import org.elasticsearch.indices.SystemIndexDescriptor; import org.elasticsearch.inference.InferenceServiceExtension; import org.elasticsearch.inference.InferenceServiceRegistry; -import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.node.PluginComponentBinding; import org.elasticsearch.plugins.ActionPlugin; import org.elasticsearch.plugins.ExtensiblePlugin; @@ -46,7 +45,6 @@ import org.elasticsearch.threadpool.ScalingExecutorBuilder; import org.elasticsearch.xcontent.ParseField; import org.elasticsearch.xpack.core.ClientHelper; -import org.elasticsearch.xpack.core.XPackPlugin; import org.elasticsearch.xpack.core.action.XPackUsageFeatureAction; import org.elasticsearch.xpack.core.inference.action.DeleteInferenceEndpointAction; import org.elasticsearch.xpack.core.inference.action.GetInferenceDiagnosticsAction; @@ -56,7 +54,6 @@ import org.elasticsearch.xpack.core.inference.action.PutInferenceModelAction; import org.elasticsearch.xpack.core.inference.action.UnifiedCompletionAction; import org.elasticsearch.xpack.core.inference.action.UpdateInferenceModelAction; -import org.elasticsearch.xpack.core.ssl.SSLService; import org.elasticsearch.xpack.inference.action.TransportDeleteInferenceEndpointAction; import org.elasticsearch.xpack.inference.action.TransportGetInferenceDiagnosticsAction; import org.elasticsearch.xpack.inference.action.TransportGetInferenceModelAction; @@ -122,6 +119,7 @@ import java.util.Map; import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.stream.Collectors; import java.util.stream.Stream; import static java.util.Collections.singletonList; @@ -155,7 +153,6 @@ public class InferencePlugin extends Plugin implements ActionPlugin, ExtensibleP private final Settings settings; private final SetOnce httpFactory = new SetOnce<>(); private final SetOnce amazonBedrockFactory = new SetOnce<>(); - private final SetOnce elasicInferenceServiceFactory = new SetOnce<>(); private final SetOnce serviceComponents = new SetOnce<>(); private final SetOnce elasticInferenceServiceComponents = new SetOnce<>(); private final SetOnce inferenceServiceRegistry = new SetOnce<>(); @@ -238,31 +235,31 @@ public Collection createComponents(PluginServices services) { var inferenceServices = new ArrayList<>(inferenceServiceExtensions); inferenceServices.add(this::getInferenceServiceFactories); - if (isElasticInferenceServiceEnabled()) { - // Create a separate instance of HTTPClientManager with its own SSL configuration (`xpack.inference.elastic.http.ssl.*`). - var elasticInferenceServiceHttpClientManager = HttpClientManager.create( - settings, - services.threadPool(), - services.clusterService(), - throttlerManager, - getSslService() - ); + // Set elasticInferenceUrl based on feature flags to support transitioning to the new Elastic Inference Service URL without exposing + // internal names like "eis" or "gateway". + ElasticInferenceServiceSettings inferenceServiceSettings = new ElasticInferenceServiceSettings(settings); + + String elasticInferenceUrl = null; - var elasticInferenceServiceRequestSenderFactory = new HttpRequestSender.Factory( - serviceComponents.get(), - elasticInferenceServiceHttpClientManager, - services.clusterService() + if (ELASTIC_INFERENCE_SERVICE_FEATURE_FLAG.isEnabled()) { + elasticInferenceUrl = inferenceServiceSettings.getElasticInferenceServiceUrl(); + } else if (DEPRECATED_ELASTIC_INFERENCE_SERVICE_FEATURE_FLAG.isEnabled()) { + log.warn( + "Deprecated flag {} detected for enabling {}. Please use {}.", + ELASTIC_INFERENCE_SERVICE_IDENTIFIER, + DEPRECATED_ELASTIC_INFERENCE_SERVICE_FEATURE_FLAG, + ELASTIC_INFERENCE_SERVICE_FEATURE_FLAG ); - elasicInferenceServiceFactory.set(elasticInferenceServiceRequestSenderFactory); + elasticInferenceUrl = inferenceServiceSettings.getEisGatewayUrl(); + } - ElasticInferenceServiceSettings inferenceServiceSettings = new ElasticInferenceServiceSettings(settings); - String elasticInferenceUrl = this.getElasticInferenceServiceUrl(inferenceServiceSettings); + if (elasticInferenceUrl != null) { elasticInferenceServiceComponents.set(new ElasticInferenceServiceComponents(elasticInferenceUrl)); inferenceServices.add( () -> List.of( context -> new ElasticInferenceService( - elasicInferenceServiceFactory.get(), + httpFactory.get(), serviceComponents.get(), elasticInferenceServiceComponents.get() ) @@ -385,21 +382,16 @@ public static ExecutorBuilder inferenceUtilityExecutor(Settings settings) { @Override public List> getSettings() { - ArrayList> settings = new ArrayList<>(); - settings.addAll(HttpSettings.getSettingsDefinitions()); - settings.addAll(HttpClientManager.getSettingsDefinitions()); - settings.addAll(ThrottlerManager.getSettingsDefinitions()); - settings.addAll(RetrySettings.getSettingsDefinitions()); - settings.addAll(Truncator.getSettingsDefinitions()); - settings.addAll(RequestExecutorServiceSettings.getSettingsDefinitions()); - settings.add(SKIP_VALIDATE_AND_START); - - // Register Elastic Inference Service settings definitions if the corresponding feature flag is enabled. - if (isElasticInferenceServiceEnabled()) { - settings.addAll(ElasticInferenceServiceSettings.getSettingsDefinitions()); - } - - return settings; + return Stream.of( + HttpSettings.getSettingsDefinitions(), + HttpClientManager.getSettingsDefinitions(), + ThrottlerManager.getSettingsDefinitions(), + RetrySettings.getSettingsDefinitions(), + ElasticInferenceServiceSettings.getSettingsDefinitions(), + Truncator.getSettingsDefinitions(), + RequestExecutorServiceSettings.getSettingsDefinitions(), + List.of(SKIP_VALIDATE_AND_START) + ).flatMap(Collection::stream).collect(Collectors.toList()); } @Override @@ -447,10 +439,7 @@ public List getQueryRewriteInterceptors() { @Override public List> getRetrievers() { return List.of( - new RetrieverSpec<>( - new ParseField(TextSimilarityRankBuilder.NAME), - (parser, context) -> TextSimilarityRankRetrieverBuilder.fromXContent(parser, context, getLicenseState()) - ), + new RetrieverSpec<>(new ParseField(TextSimilarityRankBuilder.NAME), TextSimilarityRankRetrieverBuilder::fromXContent), new RetrieverSpec<>(new ParseField(RandomRankBuilder.NAME), RandomRankRetrieverBuilder::fromXContent) ); } @@ -459,36 +448,4 @@ public List> getRetrievers() { public Map getHighlighters() { return Map.of(SemanticTextHighlighter.NAME, new SemanticTextHighlighter()); } - - // Get Elastic Inference service URL based on feature flags to support transitioning - // to the new Elastic Inference Service URL. - private String getElasticInferenceServiceUrl(ElasticInferenceServiceSettings settings) { - String elasticInferenceUrl = null; - - if (ELASTIC_INFERENCE_SERVICE_FEATURE_FLAG.isEnabled()) { - elasticInferenceUrl = settings.getElasticInferenceServiceUrl(); - } else if (DEPRECATED_ELASTIC_INFERENCE_SERVICE_FEATURE_FLAG.isEnabled()) { - log.warn( - "Deprecated flag {} detected for enabling {}. Please use {}.", - ELASTIC_INFERENCE_SERVICE_IDENTIFIER, - DEPRECATED_ELASTIC_INFERENCE_SERVICE_FEATURE_FLAG, - ELASTIC_INFERENCE_SERVICE_FEATURE_FLAG - ); - elasticInferenceUrl = settings.getEisGatewayUrl(); - } - - return elasticInferenceUrl; - } - - protected Boolean isElasticInferenceServiceEnabled() { - return (ELASTIC_INFERENCE_SERVICE_FEATURE_FLAG.isEnabled() || DEPRECATED_ELASTIC_INFERENCE_SERVICE_FEATURE_FLAG.isEnabled()); - } - - protected SSLService getSslService() { - return XPackPlugin.getSharedSslService(); - } - - protected XPackLicenseState getLicenseState() { - return XPackPlugin.getSharedLicenseState(); - } } diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/http/HttpClientManager.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/http/HttpClientManager.java index 6d09c9e67b363..e5d76b9bb5570 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/http/HttpClientManager.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/external/http/HttpClientManager.java @@ -7,14 +7,9 @@ package org.elasticsearch.xpack.inference.external.http; -import org.apache.http.config.Registry; -import org.apache.http.config.RegistryBuilder; import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager; import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor; import org.apache.http.impl.nio.reactor.IOReactorConfig; -import org.apache.http.nio.conn.NoopIOSessionStrategy; -import org.apache.http.nio.conn.SchemeIOSessionStrategy; -import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy; import org.apache.http.nio.reactor.ConnectingIOReactor; import org.apache.http.nio.reactor.IOReactorException; import org.apache.http.pool.PoolStats; @@ -26,7 +21,6 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.core.TimeValue; import org.elasticsearch.threadpool.ThreadPool; -import org.elasticsearch.xpack.core.ssl.SSLService; import org.elasticsearch.xpack.inference.logging.ThrottlerManager; import java.io.Closeable; @@ -34,13 +28,11 @@ import java.util.List; import static org.elasticsearch.core.Strings.format; -import static org.elasticsearch.xpack.inference.services.elastic.ElasticInferenceServiceSettings.ELASTIC_INFERENCE_SERVICE_SSL_CONFIGURATION_PREFIX; public class HttpClientManager implements Closeable { private static final Logger logger = LogManager.getLogger(HttpClientManager.class); /** * The maximum number of total connections the connection pool can lease to all routes. - * The configuration applies to each instance of HTTPClientManager (max_total_connections=10 and instances=5 leads to 50 connections). * From googling around the connection pools maxTotal value should be close to the number of available threads. * * https://stackoverflow.com/questions/30989637/how-to-decide-optimal-settings-for-setmaxtotal-and-setdefaultmaxperroute @@ -55,7 +47,6 @@ public class HttpClientManager implements Closeable { /** * The max number of connections a single route can lease. - * This configuration applies to each instance of HttpClientManager. */ public static final Setting MAX_ROUTE_CONNECTIONS = Setting.intSetting( "xpack.inference.http.max_route_connections", @@ -107,22 +98,6 @@ public static HttpClientManager create( return new HttpClientManager(settings, connectionManager, threadPool, clusterService, throttlerManager); } - public static HttpClientManager create( - Settings settings, - ThreadPool threadPool, - ClusterService clusterService, - ThrottlerManager throttlerManager, - SSLService sslService - ) { - // Set the sslStrategy to ensure an encrypted connection, as Elastic Inference Service requires it. - SSLIOSessionStrategy sslioSessionStrategy = sslService.sslIOSessionStrategy( - sslService.getSSLConfiguration(ELASTIC_INFERENCE_SERVICE_SSL_CONFIGURATION_PREFIX) - ); - - PoolingNHttpClientConnectionManager connectionManager = createConnectionManager(sslioSessionStrategy); - return new HttpClientManager(settings, connectionManager, threadPool, clusterService, throttlerManager); - } - // Default for testing HttpClientManager( Settings settings, @@ -146,25 +121,6 @@ public static HttpClientManager create( this.addSettingsUpdateConsumers(clusterService); } - private static PoolingNHttpClientConnectionManager createConnectionManager(SSLIOSessionStrategy sslStrategy) { - ConnectingIOReactor ioReactor; - try { - var configBuilder = IOReactorConfig.custom().setSoKeepAlive(true); - ioReactor = new DefaultConnectingIOReactor(configBuilder.build()); - } catch (IOReactorException e) { - var message = "Failed to initialize HTTP client manager with SSL."; - logger.error(message, e); - throw new ElasticsearchException(message, e); - } - - Registry registry = RegistryBuilder.create() - .register("http", NoopIOSessionStrategy.INSTANCE) - .register("https", sslStrategy) - .build(); - - return new PoolingNHttpClientConnectionManager(ioReactor, registry); - } - private static PoolingNHttpClientConnectionManager createConnectionManager() { ConnectingIOReactor ioReactor; try { diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/rank/textsimilarity/TextSimilarityRankRetrieverBuilder.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/rank/textsimilarity/TextSimilarityRankRetrieverBuilder.java index f54696895a818..fd2427dc8ac6a 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/rank/textsimilarity/TextSimilarityRankRetrieverBuilder.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/rank/textsimilarity/TextSimilarityRankRetrieverBuilder.java @@ -12,7 +12,6 @@ import org.elasticsearch.features.NodeFeature; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.license.LicenseUtils; -import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.rank.RankDoc; import org.elasticsearch.search.retriever.CompoundRetrieverBuilder; @@ -22,6 +21,7 @@ import org.elasticsearch.xcontent.ParseField; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentParser; +import org.elasticsearch.xpack.core.XPackPlugin; import java.io.IOException; import java.util.List; @@ -73,11 +73,8 @@ public class TextSimilarityRankRetrieverBuilder extends CompoundRetrieverBuilder RetrieverBuilder.declareBaseParserFields(TextSimilarityRankBuilder.NAME, PARSER); } - public static TextSimilarityRankRetrieverBuilder fromXContent( - XContentParser parser, - RetrieverParserContext context, - XPackLicenseState licenceState - ) throws IOException { + public static TextSimilarityRankRetrieverBuilder fromXContent(XContentParser parser, RetrieverParserContext context) + throws IOException { if (context.clusterSupportsFeature(TEXT_SIMILARITY_RERANKER_RETRIEVER_SUPPORTED) == false) { throw new ParsingException(parser.getTokenLocation(), "unknown retriever [" + TextSimilarityRankBuilder.NAME + "]"); } @@ -86,7 +83,7 @@ public static TextSimilarityRankRetrieverBuilder fromXContent( "[text_similarity_reranker] retriever composition feature is not supported by all nodes in the cluster" ); } - if (TextSimilarityRankBuilder.TEXT_SIMILARITY_RERANKER_FEATURE.check(licenceState) == false) { + if (TextSimilarityRankBuilder.TEXT_SIMILARITY_RERANKER_FEATURE.check(XPackPlugin.getSharedLicenseState()) == false) { throw LicenseUtils.newComplianceException(TextSimilarityRankBuilder.NAME); } return PARSER.apply(parser, context); diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/elastic/ElasticInferenceServiceSettings.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/elastic/ElasticInferenceServiceSettings.java index 431a3647e2879..bc2daddc2a346 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/elastic/ElasticInferenceServiceSettings.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/services/elastic/ElasticInferenceServiceSettings.java @@ -9,9 +9,7 @@ import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.xpack.core.ssl.SSLConfigurationSettings; -import java.util.ArrayList; import java.util.List; public class ElasticInferenceServiceSettings { @@ -19,8 +17,6 @@ public class ElasticInferenceServiceSettings { @Deprecated static final Setting EIS_GATEWAY_URL = Setting.simpleString("xpack.inference.eis.gateway.url", Setting.Property.NodeScope); - public static final String ELASTIC_INFERENCE_SERVICE_SSL_CONFIGURATION_PREFIX = "xpack.inference.elastic.http.ssl."; - static final Setting ELASTIC_INFERENCE_SERVICE_URL = Setting.simpleString( "xpack.inference.elastic.url", Setting.Property.NodeScope @@ -35,27 +31,11 @@ public class ElasticInferenceServiceSettings { public ElasticInferenceServiceSettings(Settings settings) { eisGatewayUrl = EIS_GATEWAY_URL.get(settings); elasticInferenceServiceUrl = ELASTIC_INFERENCE_SERVICE_URL.get(settings); - } - - public static final SSLConfigurationSettings ELASTIC_INFERENCE_SERVICE_SSL_CONFIGURATION_SETTINGS = SSLConfigurationSettings.withPrefix( - ELASTIC_INFERENCE_SERVICE_SSL_CONFIGURATION_PREFIX, - false - ); - public static final Setting ELASTIC_INFERENCE_SERVICE_SSL_ENABLED = Setting.boolSetting( - ELASTIC_INFERENCE_SERVICE_SSL_CONFIGURATION_PREFIX + "enabled", - true, - Setting.Property.NodeScope - ); + } public static List> getSettingsDefinitions() { - ArrayList> settings = new ArrayList<>(); - settings.add(EIS_GATEWAY_URL); - settings.add(ELASTIC_INFERENCE_SERVICE_URL); - settings.add(ELASTIC_INFERENCE_SERVICE_SSL_ENABLED); - settings.addAll(ELASTIC_INFERENCE_SERVICE_SSL_CONFIGURATION_SETTINGS.getEnabledSettings()); - - return settings; + return List.of(EIS_GATEWAY_URL, ELASTIC_INFERENCE_SERVICE_URL); } @Deprecated diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/cluster/metadata/SemanticTextClusterMetadataTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/cluster/metadata/SemanticTextClusterMetadataTests.java index 61033a0211065..bfec2d5ac3484 100644 --- a/x-pack/plugin/inference/src/test/java/org/elasticsearch/cluster/metadata/SemanticTextClusterMetadataTests.java +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/cluster/metadata/SemanticTextClusterMetadataTests.java @@ -14,7 +14,6 @@ import org.elasticsearch.index.IndexService; import org.elasticsearch.plugins.Plugin; import org.elasticsearch.test.ESSingleNodeTestCase; -import org.elasticsearch.xpack.core.XPackPlugin; import org.elasticsearch.xpack.inference.InferencePlugin; import org.hamcrest.Matchers; @@ -29,7 +28,7 @@ public class SemanticTextClusterMetadataTests extends ESSingleNodeTestCase { @Override protected Collection> getPlugins() { - return List.of(XPackPlugin.class, InferencePlugin.class); + return List.of(InferencePlugin.class); } public void testCreateIndexWithSemanticTextField() { diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/InferencePluginTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/InferencePluginTests.java deleted file mode 100644 index d1db5b8b12cc6..0000000000000 --- a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/InferencePluginTests.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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.inference; - -import org.elasticsearch.common.settings.Setting; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.test.ESTestCase; -import org.elasticsearch.xpack.inference.services.elastic.ElasticInferenceServiceSettings; -import org.junit.After; -import org.junit.Before; - -import static org.hamcrest.Matchers.is; - -public class InferencePluginTests extends ESTestCase { - private InferencePlugin inferencePlugin; - - private Boolean elasticInferenceServiceEnabled = true; - - private void setElasticInferenceServiceEnabled(Boolean elasticInferenceServiceEnabled) { - this.elasticInferenceServiceEnabled = elasticInferenceServiceEnabled; - } - - @Before - public void setUp() throws Exception { - super.setUp(); - - Settings settings = Settings.builder().build(); - inferencePlugin = new InferencePlugin(settings) { - @Override - protected Boolean isElasticInferenceServiceEnabled() { - return elasticInferenceServiceEnabled; - } - }; - } - - @After - public void tearDown() throws Exception { - super.tearDown(); - } - - public void testElasticInferenceServiceSettingsPresent() throws Exception { - setElasticInferenceServiceEnabled(true); // enable elastic inference service - boolean anyMatch = inferencePlugin.getSettings() - .stream() - .map(Setting::getKey) - .anyMatch(key -> key.startsWith(ElasticInferenceServiceSettings.ELASTIC_INFERENCE_SERVICE_SSL_CONFIGURATION_PREFIX)); - - assertThat("xpack.inference.elastic settings are present", anyMatch, is(true)); - } - - public void testElasticInferenceServiceSettingsNotPresent() throws Exception { - setElasticInferenceServiceEnabled(false); // disable elastic inference service - boolean noneMatch = inferencePlugin.getSettings() - .stream() - .map(Setting::getKey) - .noneMatch(key -> key.startsWith(ElasticInferenceServiceSettings.ELASTIC_INFERENCE_SERVICE_SSL_CONFIGURATION_PREFIX)); - - assertThat("xpack.inference.elastic settings are not present", noneMatch, is(true)); - } -} diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/LocalStateInferencePlugin.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/LocalStateInferencePlugin.java deleted file mode 100644 index 68ea175bd9870..0000000000000 --- a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/LocalStateInferencePlugin.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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.inference; - -import org.elasticsearch.action.support.MappedActionFilter; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.index.mapper.Mapper; -import org.elasticsearch.inference.InferenceServiceExtension; -import org.elasticsearch.license.XPackLicenseState; -import org.elasticsearch.plugins.SearchPlugin; -import org.elasticsearch.xpack.core.LocalStateCompositeXPackPlugin; -import org.elasticsearch.xpack.core.ssl.SSLService; -import org.elasticsearch.xpack.inference.mock.TestDenseInferenceServiceExtension; -import org.elasticsearch.xpack.inference.mock.TestSparseInferenceServiceExtension; - -import java.nio.file.Path; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import static java.util.stream.Collectors.toList; - -public class LocalStateInferencePlugin extends LocalStateCompositeXPackPlugin { - private final InferencePlugin inferencePlugin; - - public LocalStateInferencePlugin(final Settings settings, final Path configPath) throws Exception { - super(settings, configPath); - LocalStateInferencePlugin thisVar = this; - this.inferencePlugin = new InferencePlugin(settings) { - @Override - protected SSLService getSslService() { - return thisVar.getSslService(); - } - - @Override - protected XPackLicenseState getLicenseState() { - return thisVar.getLicenseState(); - } - - @Override - public List getInferenceServiceFactories() { - return List.of( - TestSparseInferenceServiceExtension.TestInferenceService::new, - TestDenseInferenceServiceExtension.TestInferenceService::new - ); - } - }; - plugins.add(inferencePlugin); - } - - @Override - public List> getRetrievers() { - return this.filterPlugins(SearchPlugin.class).stream().flatMap(p -> p.getRetrievers().stream()).collect(toList()); - } - - @Override - public Map getMappers() { - return inferencePlugin.getMappers(); - } - - @Override - public Collection getMappedActionFilters() { - return inferencePlugin.getMappedActionFilters(); - } - -} diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/Utils.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/Utils.java index 0f322e64755be..9395ae222e9ba 100644 --- a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/Utils.java +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/Utils.java @@ -14,6 +14,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.core.TimeValue; import org.elasticsearch.index.mapper.vectors.DenseVectorFieldMapper; +import org.elasticsearch.inference.InferenceServiceExtension; import org.elasticsearch.inference.Model; import org.elasticsearch.inference.ModelConfigurations; import org.elasticsearch.inference.ModelSecrets; @@ -142,6 +143,20 @@ private static void blockingCall( latch.await(); } + public static class TestInferencePlugin extends InferencePlugin { + public TestInferencePlugin(Settings settings) { + super(settings); + } + + @Override + public List getInferenceServiceFactories() { + return List.of( + TestSparseInferenceServiceExtension.TestInferenceService::new, + TestDenseInferenceServiceExtension.TestInferenceService::new + ); + } + } + public static Model getInvalidModel(String inferenceEntityId, String serviceName) { var mockConfigs = mock(ModelConfigurations.class); when(mockConfigs.getInferenceEntityId()).thenReturn(inferenceEntityId); diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/mapper/SemanticTextNonDynamicFieldMapperTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/mapper/SemanticTextNonDynamicFieldMapperTests.java index 24183b21f73e7..1f58c4165056d 100644 --- a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/mapper/SemanticTextNonDynamicFieldMapperTests.java +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/mapper/SemanticTextNonDynamicFieldMapperTests.java @@ -9,7 +9,6 @@ import org.elasticsearch.index.mapper.NonDynamicFieldMapperTests; import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.xpack.inference.LocalStateInferencePlugin; import org.elasticsearch.xpack.inference.Utils; import org.elasticsearch.xpack.inference.mock.TestSparseInferenceServiceExtension; import org.junit.Before; @@ -27,7 +26,7 @@ public void setup() throws Exception { @Override protected Collection> getPlugins() { - return List.of(LocalStateInferencePlugin.class); + return List.of(Utils.TestInferencePlugin.class); } @Override diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/rank/textsimilarity/TextSimilarityRankMultiNodeTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/rank/textsimilarity/TextSimilarityRankMultiNodeTests.java index daed03c198e0d..6d6403b69ea11 100644 --- a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/rank/textsimilarity/TextSimilarityRankMultiNodeTests.java +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/rank/textsimilarity/TextSimilarityRankMultiNodeTests.java @@ -10,7 +10,7 @@ import org.elasticsearch.plugins.Plugin; import org.elasticsearch.search.rank.RankBuilder; import org.elasticsearch.search.rank.rerank.AbstractRerankerIT; -import org.elasticsearch.xpack.inference.LocalStateInferencePlugin; +import org.elasticsearch.xpack.inference.InferencePlugin; import java.util.Collection; import java.util.List; @@ -40,7 +40,7 @@ protected RankBuilder getThrowingRankBuilder(int rankWindowSize, String rankFeat @Override protected Collection> pluginsNeeded() { - return List.of(LocalStateInferencePlugin.class, TextSimilarityTestPlugin.class); + return List.of(InferencePlugin.class, TextSimilarityTestPlugin.class); } public void testQueryPhaseShardThrowingAllShardsFail() throws Exception { diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/rank/textsimilarity/TextSimilarityRankRetrieverTelemetryTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/rank/textsimilarity/TextSimilarityRankRetrieverTelemetryTests.java index ba6924ba0ff3b..084a7f3de4a53 100644 --- a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/rank/textsimilarity/TextSimilarityRankRetrieverTelemetryTests.java +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/rank/textsimilarity/TextSimilarityRankRetrieverTelemetryTests.java @@ -24,7 +24,8 @@ import org.elasticsearch.test.ESIntegTestCase; import org.elasticsearch.xcontent.XContentBuilder; import org.elasticsearch.xcontent.XContentFactory; -import org.elasticsearch.xpack.inference.LocalStateInferencePlugin; +import org.elasticsearch.xpack.core.XPackPlugin; +import org.elasticsearch.xpack.inference.InferencePlugin; import org.junit.Before; import java.io.IOException; @@ -46,7 +47,7 @@ protected boolean addMockHttpTransport() { @Override protected Collection> nodePlugins() { - return List.of(LocalStateInferencePlugin.class, TextSimilarityTestPlugin.class); + return List.of(InferencePlugin.class, XPackPlugin.class, TextSimilarityTestPlugin.class); } @Override diff --git a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/rank/textsimilarity/TextSimilarityRankTests.java b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/rank/textsimilarity/TextSimilarityRankTests.java index f81f2965c392e..a042fca44fdb5 100644 --- a/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/rank/textsimilarity/TextSimilarityRankTests.java +++ b/x-pack/plugin/inference/src/test/java/org/elasticsearch/xpack/inference/rank/textsimilarity/TextSimilarityRankTests.java @@ -20,7 +20,7 @@ import org.elasticsearch.test.ESSingleNodeTestCase; import org.elasticsearch.test.hamcrest.ElasticsearchAssertions; import org.elasticsearch.xpack.core.inference.action.InferenceAction; -import org.elasticsearch.xpack.inference.LocalStateInferencePlugin; +import org.elasticsearch.xpack.inference.InferencePlugin; import org.junit.Before; import java.util.Collection; @@ -108,7 +108,7 @@ protected InferenceAction.Request generateRequest(List docFeatures) { @Override protected Collection> getPlugins() { - return List.of(LocalStateInferencePlugin.class, TextSimilarityTestPlugin.class); + return List.of(InferencePlugin.class, TextSimilarityTestPlugin.class); } @Before diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/LocalStateMachineLearning.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/LocalStateMachineLearning.java index ff1a1d19779df..bab012afc3101 100644 --- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/LocalStateMachineLearning.java +++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/LocalStateMachineLearning.java @@ -27,7 +27,6 @@ import org.elasticsearch.xpack.core.LocalStateCompositeXPackPlugin; import org.elasticsearch.xpack.core.rollup.action.GetRollupIndexCapsAction; import org.elasticsearch.xpack.core.ssl.SSLService; -import org.elasticsearch.xpack.inference.InferencePlugin; import org.elasticsearch.xpack.monitoring.Monitoring; import org.elasticsearch.xpack.security.Security; @@ -87,12 +86,6 @@ protected XPackLicenseState getLicenseState() { } }); plugins.add(new MockedRollupPlugin()); - plugins.add(new InferencePlugin(settings) { - @Override - protected SSLService getSslService() { - return thisVar.getSslService(); - } - }); } @Override diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/support/BaseMlIntegTestCase.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/support/BaseMlIntegTestCase.java index 5cf15454e47f2..aeebfabdce704 100644 --- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/support/BaseMlIntegTestCase.java +++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/support/BaseMlIntegTestCase.java @@ -82,6 +82,7 @@ import org.elasticsearch.xpack.core.ml.job.process.autodetect.state.DataCounts; import org.elasticsearch.xpack.core.ml.utils.MlTaskState; import org.elasticsearch.xpack.ilm.IndexLifecycle; +import org.elasticsearch.xpack.inference.InferencePlugin; import org.elasticsearch.xpack.ml.LocalStateMachineLearning; import org.elasticsearch.xpack.ml.MachineLearning; import org.elasticsearch.xpack.ml.MlSingleNodeTestCase; @@ -160,7 +161,8 @@ protected Collection> nodePlugins() { DataStreamsPlugin.class, // To remove errors from parsing build in templates that contain scaled_float MapperExtrasPlugin.class, - Wildcard.class + Wildcard.class, + InferencePlugin.class ); } diff --git a/x-pack/plugin/security/qa/consistency-checks/src/test/java/org/elasticsearch/xpack/security/CrossClusterShardTests.java b/x-pack/plugin/security/qa/consistency-checks/src/test/java/org/elasticsearch/xpack/security/CrossClusterShardTests.java index 057ebdece5c61..ab5be0f48f5f3 100644 --- a/x-pack/plugin/security/qa/consistency-checks/src/test/java/org/elasticsearch/xpack/security/CrossClusterShardTests.java +++ b/x-pack/plugin/security/qa/consistency-checks/src/test/java/org/elasticsearch/xpack/security/CrossClusterShardTests.java @@ -35,6 +35,7 @@ import org.elasticsearch.xpack.frozen.FrozenIndices; import org.elasticsearch.xpack.graph.Graph; import org.elasticsearch.xpack.ilm.IndexLifecycle; +import org.elasticsearch.xpack.inference.InferencePlugin; import org.elasticsearch.xpack.profiling.ProfilingPlugin; import org.elasticsearch.xpack.rollup.Rollup; import org.elasticsearch.xpack.search.AsyncSearch; @@ -88,6 +89,7 @@ protected Collection> getPlugins() { FrozenIndices.class, Graph.class, IndexLifecycle.class, + InferencePlugin.class, IngestCommonPlugin.class, IngestTestPlugin.class, MustachePlugin.class, From 724e9bef3b923e64306db68999ffe02a226aa014 Mon Sep 17 00:00:00 2001 From: Jedr Blaszyk Date: Wed, 18 Dec 2024 13:05:16 +0100 Subject: [PATCH 36/60] [Connector APIs] Enforce index prefix for managed connectors (#117778) * [Connector APIs] Enforce manage connector index prefix * Update ConnectorIndexServiceTests to check for prefix * Update docs/changelog/117778.yaml * Fix accidental changes to muted tests * Review feedback * Review feedback --------- Co-authored-by: Elastic Machine --- docs/changelog/117778.yaml | 5 + .../entsearch/connector/10_connector_put.yml | 13 ++ .../130_connector_update_index_name.yml | 15 ++ .../connector/140_connector_update_native.yml | 40 +++++ .../entsearch/connector/15_connector_post.yml | 12 ++ .../connector/ConnectorIndexService.java | 137 +++++++++++++----- .../connector/ConnectorTemplateRegistry.java | 2 + .../action/ConnectorActionRequest.java | 27 ++++ .../connector/action/PostConnectorAction.java | 4 + .../connector/action/PutConnectorAction.java | 4 + .../connector/ConnectorIndexServiceTests.java | 80 +++++++++- .../connector/ConnectorTestUtils.java | 12 ++ .../action/PostConnectorActionTests.java | 20 ++- .../action/PutConnectorActionTests.java | 21 ++- 14 files changed, 351 insertions(+), 41 deletions(-) create mode 100644 docs/changelog/117778.yaml diff --git a/docs/changelog/117778.yaml b/docs/changelog/117778.yaml new file mode 100644 index 0000000000000..880d4f831e533 --- /dev/null +++ b/docs/changelog/117778.yaml @@ -0,0 +1,5 @@ +pr: 117778 +summary: "[Connector APIs] Enforce index prefix for managed connectors" +area: Extract&Transform +type: feature +issues: [] diff --git a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/connector/10_connector_put.yml b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/connector/10_connector_put.yml index 094d9cbf43089..4240467ea4ff3 100644 --- a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/connector/10_connector_put.yml +++ b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/connector/10_connector_put.yml @@ -152,6 +152,19 @@ setup: service_type: super-connector +--- +'Create Connector - Invalid Managed Connector Index Prefix': + - do: + catch: "bad_request" + connector.put: + connector_id: test-connector-test-managed + body: + index_name: wrong-prefix-index + name: my-connector + language: pl + is_native: true + service_type: super-connector + --- 'Create Connector - Id returned as part of response': - do: diff --git a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/connector/130_connector_update_index_name.yml b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/connector/130_connector_update_index_name.yml index f804dc02a9e01..b63bf595af5f4 100644 --- a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/connector/130_connector_update_index_name.yml +++ b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/connector/130_connector_update_index_name.yml @@ -151,3 +151,18 @@ setup: - match: { index_name: content-search-2-test } +--- +"Update Managed Connector Index Name - Bad Prefix": + - do: + connector.put: + connector_id: test-connector-2 + body: + is_native: true + service_type: super-connector + + - do: + catch: "bad_request" + connector.update_index_name: + connector_id: test-connector-2 + body: + index_name: wrong-prefix-search-2-test diff --git a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/connector/140_connector_update_native.yml b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/connector/140_connector_update_native.yml index f8cd24d175312..6811c3340ce42 100644 --- a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/connector/140_connector_update_native.yml +++ b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/connector/140_connector_update_native.yml @@ -73,3 +73,43 @@ setup: field_1: test field_2: something +--- +"Update Connector Native - changing connector to Elastic-managed wrong index name": + + - do: + connector.put: + connector_id: test-connector-1 + body: + is_native: false + index_name: super-connector + + - do: + catch: "bad_request" + connector.update_native: + connector_id: test-connector-1 + body: + is_native: true + +--- +"Update Connector Native - changing connector to Elastic-managed correct index name": + + - do: + connector.put: + connector_id: test-connector-1 + body: + is_native: false + index_name: content-super-connector + + - do: + connector.update_native: + connector_id: test-connector-1 + body: + is_native: true + + - match: { result: updated } + + - do: + connector.get: + connector_id: test-connector-1 + + - match: { is_native: true } diff --git a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/connector/15_connector_post.yml b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/connector/15_connector_post.yml index 634f99cd53fde..4acca493c42c8 100644 --- a/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/connector/15_connector_post.yml +++ b/x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/connector/15_connector_post.yml @@ -103,6 +103,18 @@ setup: service_type: super-connector +--- +'Create Connector - Invalid Managed Connector Index Prefix': + - do: + catch: "bad_request" + connector.post: + body: + index_name: wrong-prefix-index + name: my-connector + language: pl + is_native: true + service_type: super-connector + --- 'Create Connector - Index name used by another connector': - do: diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorIndexService.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorIndexService.java index 5e1fde0dfb942..d5d2159d8f373 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorIndexService.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorIndexService.java @@ -76,6 +76,7 @@ import static org.elasticsearch.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.xpack.application.connector.ConnectorFiltering.fromXContentBytesConnectorFiltering; import static org.elasticsearch.xpack.application.connector.ConnectorFiltering.sortFilteringRulesByOrder; +import static org.elasticsearch.xpack.application.connector.ConnectorTemplateRegistry.MANAGED_CONNECTOR_INDEX_PREFIX; /** * A service that manages persistent {@link Connector} configurations. @@ -807,8 +808,8 @@ public void updateConnectorLastSyncStats(UpdateConnectorLastSyncStatsAction.Requ } /** - * Updates the is_native property of a {@link Connector}. It always sets the {@link ConnectorStatus} to - * CONFIGURED. + * Updates the is_native property of a {@link Connector}. It sets the {@link ConnectorStatus} to + * CONFIGURED when connector is in CONNECTED state to indicate that connector needs to reconnect. * * @param request The request for updating the connector's is_native property. * @param listener The listener for handling responses, including successful updates or errors. @@ -816,29 +817,62 @@ public void updateConnectorLastSyncStats(UpdateConnectorLastSyncStatsAction.Requ public void updateConnectorNative(UpdateConnectorNativeAction.Request request, ActionListener listener) { try { String connectorId = request.getConnectorId(); + boolean isNative = request.isNative(); - final UpdateRequest updateRequest = new UpdateRequest(CONNECTOR_INDEX_NAME, connectorId).doc( - new IndexRequest(CONNECTOR_INDEX_NAME).opType(DocWriteRequest.OpType.INDEX) - .id(connectorId) - .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) - .source( - Map.of( - Connector.IS_NATIVE_FIELD.getPreferredName(), - request.isNative(), - Connector.STATUS_FIELD.getPreferredName(), - ConnectorStatus.CONFIGURED.toString() - ) - ) + getConnector(connectorId, listener.delegateFailure((l, connector) -> { - ); - client.update(updateRequest, new DelegatingIndexNotFoundActionListener<>(connectorId, listener, (l, updateResponse) -> { - if (updateResponse.getResult() == UpdateResponse.Result.NOT_FOUND) { - l.onFailure(new ResourceNotFoundException(connectorNotFoundErrorMsg(connectorId))); + String indexName = getConnectorIndexNameFromSearchResult(connector); + + boolean doesNotHaveContentPrefix = indexName != null && isValidManagedConnectorIndexName(indexName) == false; + // Ensure attached content index is prefixed correctly + if (isNative && doesNotHaveContentPrefix) { + l.onFailure( + new ElasticsearchStatusException( + "The index name [" + + indexName + + "] attached to the connector [" + + connectorId + + "] must start with the required prefix: [" + + MANAGED_CONNECTOR_INDEX_PREFIX + + "] to be Elastic-managed. Please update the attached index first to comply with this requirement.", + RestStatus.BAD_REQUEST + ) + ); return; } - l.onResponse(updateResponse); - })); + ConnectorStatus status = getConnectorStatusFromSearchResult(connector); + + // If connector was connected already, change its status to CONFIGURED as we need to re-connect + boolean isConnected = status == ConnectorStatus.CONNECTED; + boolean isValidTransitionToConfigured = ConnectorStateMachine.isValidTransition(status, ConnectorStatus.CONFIGURED); + if (isConnected && isValidTransitionToConfigured) { + status = ConnectorStatus.CONFIGURED; + } + + final UpdateRequest updateRequest = new UpdateRequest(CONNECTOR_INDEX_NAME, connectorId).setRefreshPolicy( + WriteRequest.RefreshPolicy.IMMEDIATE + ) + .doc( + new IndexRequest(CONNECTOR_INDEX_NAME).opType(DocWriteRequest.OpType.INDEX) + .id(connectorId) + .source( + Map.of( + Connector.IS_NATIVE_FIELD.getPreferredName(), + isNative, + Connector.STATUS_FIELD.getPreferredName(), + status.toString() + ) + ) + ); + client.update(updateRequest, new DelegatingIndexNotFoundActionListener<>(connectorId, listener, (ll, updateResponse) -> { + if (updateResponse.getResult() == UpdateResponse.Result.NOT_FOUND) { + ll.onFailure(new ResourceNotFoundException(connectorNotFoundErrorMsg(connectorId))); + return; + } + ll.onResponse(updateResponse); + })); + })); } catch (Exception e) { listener.onFailure(e); } @@ -896,22 +930,45 @@ public void updateConnectorIndexName(UpdateConnectorIndexNameAction.Request requ return; } - final UpdateRequest updateRequest = new UpdateRequest(CONNECTOR_INDEX_NAME, connectorId).doc( - new IndexRequest(CONNECTOR_INDEX_NAME).opType(DocWriteRequest.OpType.INDEX) - .id(connectorId) - .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) - .source(new HashMap<>() { - { - put(Connector.INDEX_NAME_FIELD.getPreferredName(), request.getIndexName()); - } - }) - ); - client.update(updateRequest, new DelegatingIndexNotFoundActionListener<>(connectorId, listener, (ll, updateResponse) -> { - if (updateResponse.getResult() == UpdateResponse.Result.NOT_FOUND) { - ll.onFailure(new ResourceNotFoundException(connectorNotFoundErrorMsg(connectorId))); + getConnector(connectorId, l.delegateFailure((ll, connector) -> { + + Boolean isNativeConnector = getConnectorIsNativeFlagFromSearchResult(connector); + Boolean doesNotHaveContentPrefix = indexName != null && isValidManagedConnectorIndexName(indexName) == false; + + if (isNativeConnector && doesNotHaveContentPrefix) { + ll.onFailure( + new ElasticsearchStatusException( + "Index attached to an Elastic-managed connector must start with the prefix: [" + + MANAGED_CONNECTOR_INDEX_PREFIX + + "]. The index name in the payload [" + + indexName + + "] doesn't comply with this requirement.", + RestStatus.BAD_REQUEST + ) + ); return; } - ll.onResponse(updateResponse); + + final UpdateRequest updateRequest = new UpdateRequest(CONNECTOR_INDEX_NAME, connectorId).doc( + new IndexRequest(CONNECTOR_INDEX_NAME).opType(DocWriteRequest.OpType.INDEX) + .id(connectorId) + .setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE) + .source(new HashMap<>() { + { + put(Connector.INDEX_NAME_FIELD.getPreferredName(), request.getIndexName()); + } + }) + ); + client.update( + updateRequest, + new DelegatingIndexNotFoundActionListener<>(connectorId, listener, (lll, updateResponse) -> { + if (updateResponse.getResult() == UpdateResponse.Result.NOT_FOUND) { + lll.onFailure(new ResourceNotFoundException(connectorNotFoundErrorMsg(connectorId))); + return; + } + lll.onResponse(updateResponse); + }) + ); })); })); @@ -1064,6 +1121,18 @@ private ConnectorStatus getConnectorStatusFromSearchResult(ConnectorSearchResult return ConnectorStatus.connectorStatus((String) searchResult.getResultMap().get(Connector.STATUS_FIELD.getPreferredName())); } + private Boolean getConnectorIsNativeFlagFromSearchResult(ConnectorSearchResult searchResult) { + return (Boolean) searchResult.getResultMap().get(Connector.IS_NATIVE_FIELD.getPreferredName()); + } + + private String getConnectorIndexNameFromSearchResult(ConnectorSearchResult searchResult) { + return (String) searchResult.getResultMap().get(Connector.INDEX_NAME_FIELD.getPreferredName()); + } + + private boolean isValidManagedConnectorIndexName(String indexName) { + return indexName.startsWith(MANAGED_CONNECTOR_INDEX_PREFIX); + } + @SuppressWarnings("unchecked") private Map getConnectorConfigurationFromSearchResult(ConnectorSearchResult searchResult) { return (Map) searchResult.getResultMap().get(Connector.CONFIGURATION_FIELD.getPreferredName()); diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistry.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistry.java index 9b8cc7cfdbe4f..e630f929bc09b 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistry.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistry.java @@ -45,6 +45,8 @@ public class ConnectorTemplateRegistry extends IndexTemplateRegistry { public static final String ACCESS_CONTROL_INDEX_NAME_PATTERN = ".search-acl-filter-*"; public static final String ACCESS_CONTROL_TEMPLATE_NAME = "search-acl-filter"; + public static final String MANAGED_CONNECTOR_INDEX_PREFIX = "content-"; + // Pipeline constants public static final String ENT_SEARCH_GENERIC_PIPELINE_NAME = "ent-search-generic-ingestion"; diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/ConnectorActionRequest.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/ConnectorActionRequest.java index 1799121505da5..66f347bc4dbb4 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/ConnectorActionRequest.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/ConnectorActionRequest.java @@ -19,6 +19,7 @@ import java.io.IOException; import static org.elasticsearch.action.ValidateActions.addValidationError; +import static org.elasticsearch.xpack.application.connector.ConnectorTemplateRegistry.MANAGED_CONNECTOR_INDEX_PREFIX; /** * Abstract base class for action requests targeting the connectors index. Implements {@link org.elasticsearch.action.IndicesRequest} @@ -52,6 +53,32 @@ public ActionRequestValidationException validateIndexName(String indexName, Acti return validationException; } + /** + * Validates that the given index name starts with the required prefix for Elastic-managed connectors. + * If the index name does not start with the required prefix, the validation exception is updated with an error message. + * + * @param indexName The index name to validate. If null, no validation is performed. + * @param validationException The exception to accumulate validation errors. + * @return The updated or original {@code validationException} with any new validation errors added, + * if the index name does not start with the required prefix. + */ + public ActionRequestValidationException validateManagedConnectorIndexPrefix( + String indexName, + ActionRequestValidationException validationException + ) { + if (indexName != null && indexName.startsWith(MANAGED_CONNECTOR_INDEX_PREFIX) == false) { + return addValidationError( + "Index [" + + indexName + + "] is invalid. Index attached to an Elastic-managed connector must start with the prefix: [" + + MANAGED_CONNECTOR_INDEX_PREFIX + + "]", + validationException + ); + } + return validationException; + } + @Override public String[] indices() { return new String[] { ConnectorTemplateRegistry.CONNECTOR_INDEX_NAME_PATTERN }; diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/PostConnectorAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/PostConnectorAction.java index fad349cd31877..b1c38637298c4 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/PostConnectorAction.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/PostConnectorAction.java @@ -127,6 +127,10 @@ public ActionRequestValidationException validate() { validationException = validateIndexName(indexName, validationException); + if (Boolean.TRUE.equals(isNative)) { + validationException = validateManagedConnectorIndexPrefix(indexName, validationException); + } + return validationException; } diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/PutConnectorAction.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/PutConnectorAction.java index 687a801ab8fd6..f3e8ed6b6e76d 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/PutConnectorAction.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/action/PutConnectorAction.java @@ -147,6 +147,10 @@ public ActionRequestValidationException validate() { validationException = validateIndexName(indexName, validationException); + if (Boolean.TRUE.equals(isNative)) { + validationException = validateManagedConnectorIndexPrefix(indexName, validationException); + } + return validationException; } diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIndexServiceTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIndexServiceTests.java index 12abca3a78591..28d4fe0956d03 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIndexServiceTests.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIndexServiceTests.java @@ -56,6 +56,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +import static org.elasticsearch.xpack.application.connector.ConnectorTemplateRegistry.MANAGED_CONNECTOR_INDEX_PREFIX; import static org.elasticsearch.xpack.application.connector.ConnectorTestUtils.getRandomConnectorFeatures; import static org.elasticsearch.xpack.application.connector.ConnectorTestUtils.getRandomCronExpression; import static org.elasticsearch.xpack.application.connector.ConnectorTestUtils.randomConnectorFeatureEnabled; @@ -648,8 +649,8 @@ public void testUpdateConnectorScheduling_OnlyFullSchedule() throws Exception { assertThat(initialScheduling.getIncremental(), equalTo(indexedConnector.getScheduling().getIncremental())); } - public void testUpdateConnectorIndexName() throws Exception { - Connector connector = ConnectorTestUtils.getRandomConnector(); + public void testUpdateConnectorIndexName_ForSelfManagedConnector() throws Exception { + Connector connector = ConnectorTestUtils.getRandomSelfManagedConnector(); String connectorId = randomUUID(); ConnectorCreateActionResponse resp = awaitCreateConnector(connectorId, connector); @@ -669,8 +670,8 @@ public void testUpdateConnectorIndexName() throws Exception { assertThat(newIndexName, equalTo(indexedConnector.getIndexName())); } - public void testUpdateConnectorIndexName_WithTheSameIndexName() throws Exception { - Connector connector = ConnectorTestUtils.getRandomConnector(); + public void testUpdateConnectorIndexName_ForSelfManagedConnector_WithTheSameIndexName() throws Exception { + Connector connector = ConnectorTestUtils.getRandomSelfManagedConnector(); String connectorId = randomUUID(); ConnectorCreateActionResponse resp = awaitCreateConnector(connectorId, connector); @@ -685,6 +686,42 @@ public void testUpdateConnectorIndexName_WithTheSameIndexName() throws Exception assertThat(updateResponse.getResult(), equalTo(DocWriteResponse.Result.NOOP)); } + public void testUpdateConnectorIndexName_ForManagedConnector_WithIllegalIndexName() throws Exception { + Connector connector = ConnectorTestUtils.getRandomElasticManagedConnector(); + String connectorId = randomUUID(); + + ConnectorCreateActionResponse resp = awaitCreateConnector(connectorId, connector); + assertThat(resp.status(), anyOf(equalTo(RestStatus.CREATED), equalTo(RestStatus.OK))); + + UpdateConnectorIndexNameAction.Request updateIndexNameRequest = new UpdateConnectorIndexNameAction.Request( + connectorId, + "wrong-prefix-" + randomAlphaOfLengthBetween(3, 10) + ); + + expectThrows(ElasticsearchStatusException.class, () -> awaitUpdateConnectorIndexName(updateIndexNameRequest)); + } + + public void testUpdateConnectorIndexName_ForManagedConnector_WithPrefixedIndexName() throws Exception { + Connector connector = ConnectorTestUtils.getRandomElasticManagedConnector(); + String connectorId = randomUUID(); + + ConnectorCreateActionResponse resp = awaitCreateConnector(connectorId, connector); + assertThat(resp.status(), anyOf(equalTo(RestStatus.CREATED), equalTo(RestStatus.OK))); + + String newIndexName = MANAGED_CONNECTOR_INDEX_PREFIX + randomAlphaOfLengthBetween(3, 10); + + UpdateConnectorIndexNameAction.Request updateIndexNameRequest = new UpdateConnectorIndexNameAction.Request( + connectorId, + newIndexName + ); + + DocWriteResponse updateResponse = awaitUpdateConnectorIndexName(updateIndexNameRequest); + assertThat(updateResponse.status(), equalTo(RestStatus.OK)); + + Connector indexedConnector = awaitGetConnector(connectorId); + assertThat(newIndexName, equalTo(indexedConnector.getIndexName())); + } + public void testUpdateConnectorServiceType() throws Exception { Connector connector = ConnectorTestUtils.getRandomConnector(); String connectorId = randomUUID(); @@ -756,7 +793,7 @@ public void testUpdateConnectorNameOrDescription() throws Exception { } public void testUpdateConnectorNative() throws Exception { - Connector connector = ConnectorTestUtils.getRandomConnector(); + Connector connector = ConnectorTestUtils.getRandomConnectorWithDetachedIndex(); String connectorId = randomUUID(); ConnectorCreateActionResponse resp = awaitCreateConnector(connectorId, connector); @@ -773,6 +810,39 @@ public void testUpdateConnectorNative() throws Exception { assertThat(isNative, equalTo(indexedConnector.isNative())); } + public void testUpdateConnectorNativeTrue_WhenIllegalIndexPrefix() throws Exception { + Connector connector = ConnectorTestUtils.getRandomConnectorWithAttachedIndex("wrong-prefix-" + randomAlphaOfLength(10)); + String connectorId = randomUUID(); + + ConnectorCreateActionResponse resp = awaitCreateConnector(connectorId, connector); + assertThat(resp.status(), anyOf(equalTo(RestStatus.CREATED), equalTo(RestStatus.OK))); + + boolean isNative = true; + + UpdateConnectorNativeAction.Request updateNativeRequest = new UpdateConnectorNativeAction.Request(connectorId, isNative); + + expectThrows(ElasticsearchStatusException.class, () -> awaitUpdateConnectorNative(updateNativeRequest)); + } + + public void testUpdateConnectorNativeTrue_WithCorrectIndexPrefix() throws Exception { + Connector connector = ConnectorTestUtils.getRandomConnectorWithAttachedIndex( + MANAGED_CONNECTOR_INDEX_PREFIX + randomAlphaOfLength(10) + ); + String connectorId = randomUUID(); + + ConnectorCreateActionResponse resp = awaitCreateConnector(connectorId, connector); + assertThat(resp.status(), anyOf(equalTo(RestStatus.CREATED), equalTo(RestStatus.OK))); + + boolean isNative = true; + + UpdateConnectorNativeAction.Request updateNativeRequest = new UpdateConnectorNativeAction.Request(connectorId, isNative); + DocWriteResponse updateResponse = awaitUpdateConnectorNative(updateNativeRequest); + assertThat(updateResponse.status(), equalTo(RestStatus.OK)); + + Connector indexedConnector = awaitGetConnector(connectorId); + assertThat(isNative, equalTo(indexedConnector.isNative())); + } + public void testUpdateConnectorStatus() throws Exception { Connector connector = ConnectorTestUtils.getRandomConnector(); String connectorId = randomUUID(); diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTestUtils.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTestUtils.java index f052ef79d82fb..c563bc0a14ee3 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTestUtils.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTestUtils.java @@ -343,6 +343,18 @@ public static Connector getRandomConnectorWithDetachedIndex() { return getRandomConnectorBuilder().setIndexName(null).build(); } + public static Connector getRandomConnectorWithAttachedIndex(String indexName) { + return getRandomConnectorBuilder().setIndexName(indexName).build(); + } + + public static Connector getRandomSelfManagedConnector() { + return getRandomConnectorBuilder().setIsNative(false).build(); + } + + public static Connector getRandomElasticManagedConnector() { + return getRandomConnectorBuilder().setIsNative(true).build(); + } + public static Connector getRandomConnectorWithServiceTypeNotDefined() { return getRandomConnectorBuilder().setServiceType(null).build(); } diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/PostConnectorActionTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/PostConnectorActionTests.java index 0f0e83f2b9c51..e482bf3f6bb74 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/PostConnectorActionTests.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/PostConnectorActionTests.java @@ -20,7 +20,7 @@ public void testValidate_WhenConnectorIdAndIndexNamePresent_ExpectNoValidationEr PostConnectorAction.Request request = new PostConnectorAction.Request( randomAlphaOfLength(10), randomAlphaOfLength(10), - randomBoolean(), + false, randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10) @@ -30,6 +30,24 @@ public void testValidate_WhenConnectorIdAndIndexNamePresent_ExpectNoValidationEr assertThat(exception, nullValue()); } + public void testValidate_WrongIndexNamePresentForManagedConnector_ExpectValidationError() { + PostConnectorAction.Request requestWithIllegalIndexName = new PostConnectorAction.Request( + randomAlphaOfLength(10), + "wrong-prefix-" + randomAlphaOfLength(10), + true, + randomAlphaOfLength(10), + randomAlphaOfLength(10), + randomAlphaOfLength(10) + ); + ActionRequestValidationException exception = requestWithIllegalIndexName.validate(); + + assertThat(exception, notNullValue()); + assertThat( + exception.getMessage(), + containsString("Index attached to an Elastic-managed connector must start with the prefix: [content-]") + ); + } + public void testValidate_WhenMalformedIndexName_ExpectValidationError() { PostConnectorAction.Request requestWithMissingConnectorId = new PostConnectorAction.Request( randomAlphaOfLength(10), diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/PutConnectorActionTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/PutConnectorActionTests.java index 873e102e40931..10ab049413565 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/PutConnectorActionTests.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/action/PutConnectorActionTests.java @@ -21,7 +21,7 @@ public void testValidate_WhenConnectorIdAndIndexNamePresent_ExpectNoValidationEr randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10), - randomBoolean(), + false, randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10) @@ -31,6 +31,25 @@ public void testValidate_WhenConnectorIdAndIndexNamePresent_ExpectNoValidationEr assertThat(exception, nullValue()); } + public void testValidate_WrongIndexNamePresentForManagedConnector_ExpectValidationError() { + PutConnectorAction.Request requestWithIllegalIndexName = new PutConnectorAction.Request( + randomAlphaOfLength(10), + randomAlphaOfLength(10), + "wrong-prefix-" + randomAlphaOfLength(10), + true, + randomAlphaOfLength(10), + randomAlphaOfLength(10), + randomAlphaOfLength(10) + ); + ActionRequestValidationException exception = requestWithIllegalIndexName.validate(); + + assertThat(exception, notNullValue()); + assertThat( + exception.getMessage(), + containsString("Index attached to an Elastic-managed connector must start with the prefix: [content-]") + ); + } + public void testValidate_WhenMalformedIndexName_ExpectValidationError() { PutConnectorAction.Request requestWithMissingConnectorId = new PutConnectorAction.Request( randomAlphaOfLength(10), From fb6d7db8bdd3db245004c36a608a1df4c5a92933 Mon Sep 17 00:00:00 2001 From: Ioana Tagirta Date: Wed, 18 Dec 2024 13:11:31 +0100 Subject: [PATCH 37/60] Semantic search with query builder rewrite (#118676) * Semantic search with query builder rewrite * Address review feedback * Add feature behind snapshot * Use after/before instead of afterClass/beforeClass * Call onFailure instead of throwing exception * Fix KqlFunctionIT by requiring KqlPlugin * Update scoring tests now that they are enabled * Drop the score column for now --- .../elasticsearch/action/ResolvedIndices.java | 20 +- .../esql/qa/multi_node/SemanticMatchIT.java | 26 +++ .../esql/qa/single_node/SemanticMatchIT.java | 26 +++ .../esql/qa/rest/SemanticMatchTestCase.java | 121 ++++++++++++ .../xpack/esql/EsqlTestUtils.java | 3 + .../xpack/esql/MockQueryBuilderResolver.java | 30 +++ .../main/resources/match-function.csv-spec | 71 +++++++ .../main/resources/match-operator.csv-spec | 70 +++++++ .../src/main/resources/scoring.csv-spec | 40 ++++ .../xpack/esql/plugin/KqlFunctionIT.java | 9 + .../xpack/esql/execution/PlanExecutor.java | 5 +- .../expression/function/fulltext/Match.java | 2 + .../esql/plugin/TransportEsqlQueryAction.java | 8 +- .../xpack/esql/session/EsqlSession.java | 16 +- .../esql/session/QueryBuilderResolver.java | 178 ++++++++++++++++++ .../elasticsearch/xpack/esql/CsvTests.java | 3 +- .../LocalPhysicalPlanOptimizerTests.java | 6 + .../esql/stats/PlanExecutorMetricsTests.java | 2 + 18 files changed, 629 insertions(+), 7 deletions(-) create mode 100644 x-pack/plugin/esql/qa/server/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/multi_node/SemanticMatchIT.java create mode 100644 x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/SemanticMatchIT.java create mode 100644 x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/SemanticMatchTestCase.java create mode 100644 x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/MockQueryBuilderResolver.java create mode 100644 x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/QueryBuilderResolver.java diff --git a/server/src/main/java/org/elasticsearch/action/ResolvedIndices.java b/server/src/main/java/org/elasticsearch/action/ResolvedIndices.java index f149603f12d8b..16f37c9573a8e 100644 --- a/server/src/main/java/org/elasticsearch/action/ResolvedIndices.java +++ b/server/src/main/java/org/elasticsearch/action/ResolvedIndices.java @@ -150,10 +150,26 @@ public static ResolvedIndices resolveWithIndicesRequest( RemoteClusterService remoteClusterService, long startTimeInMillis ) { - final Map remoteClusterIndices = remoteClusterService.groupIndices( + return resolveWithIndexNamesAndOptions( + request.indices(), request.indicesOptions(), - request.indices() + clusterState, + indexNameExpressionResolver, + remoteClusterService, + startTimeInMillis ); + } + + public static ResolvedIndices resolveWithIndexNamesAndOptions( + String[] indexNames, + IndicesOptions indicesOptions, + ClusterState clusterState, + IndexNameExpressionResolver indexNameExpressionResolver, + RemoteClusterService remoteClusterService, + long startTimeInMillis + ) { + final Map remoteClusterIndices = remoteClusterService.groupIndices(indicesOptions, indexNames); + final OriginalIndices localIndices = remoteClusterIndices.remove(RemoteClusterAware.LOCAL_CLUSTER_GROUP_KEY); Index[] concreteLocalIndices = localIndices == null diff --git a/x-pack/plugin/esql/qa/server/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/multi_node/SemanticMatchIT.java b/x-pack/plugin/esql/qa/server/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/multi_node/SemanticMatchIT.java new file mode 100644 index 0000000000000..0ce84330b0b01 --- /dev/null +++ b/x-pack/plugin/esql/qa/server/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/multi_node/SemanticMatchIT.java @@ -0,0 +1,26 @@ +/* + * 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.esql.qa.multi_node; + +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters; + +import org.elasticsearch.test.TestClustersThreadFilter; +import org.elasticsearch.test.cluster.ElasticsearchCluster; +import org.elasticsearch.xpack.esql.qa.rest.SemanticMatchTestCase; +import org.junit.ClassRule; + +@ThreadLeakFilters(filters = TestClustersThreadFilter.class) +public class SemanticMatchIT extends SemanticMatchTestCase { + @ClassRule + public static ElasticsearchCluster cluster = Clusters.testCluster(spec -> spec.plugin("inference-service-test")); + + @Override + protected String getTestRestCluster() { + return cluster.getHttpAddresses(); + } +} diff --git a/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/SemanticMatchIT.java b/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/SemanticMatchIT.java new file mode 100644 index 0000000000000..8edc2dbcf35a2 --- /dev/null +++ b/x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/SemanticMatchIT.java @@ -0,0 +1,26 @@ +/* + * 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.esql.qa.single_node; + +import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters; + +import org.elasticsearch.test.TestClustersThreadFilter; +import org.elasticsearch.test.cluster.ElasticsearchCluster; +import org.elasticsearch.xpack.esql.qa.rest.SemanticMatchTestCase; +import org.junit.ClassRule; + +@ThreadLeakFilters(filters = TestClustersThreadFilter.class) +public class SemanticMatchIT extends SemanticMatchTestCase { + @ClassRule + public static ElasticsearchCluster cluster = Clusters.testCluster(spec -> spec.plugin("inference-service-test")); + + @Override + protected String getTestRestCluster() { + return cluster.getHttpAddresses(); + } +} diff --git a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/SemanticMatchTestCase.java b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/SemanticMatchTestCase.java new file mode 100644 index 0000000000000..aafa57e764ae7 --- /dev/null +++ b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/SemanticMatchTestCase.java @@ -0,0 +1,121 @@ +/* + * 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.esql.qa.rest; + +import org.elasticsearch.client.Request; +import org.elasticsearch.client.ResponseException; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.test.rest.ESRestTestCase; +import org.elasticsearch.xpack.esql.action.EsqlCapabilities; +import org.junit.After; +import org.junit.Before; + +import java.io.IOException; +import java.util.Map; + +import static org.hamcrest.core.StringContains.containsString; + +public abstract class SemanticMatchTestCase extends ESRestTestCase { + public void testWithMultipleInferenceIds() throws IOException { + String query = """ + from test-semantic1,test-semantic2 + | where match(semantic_text_field, "something") + """; + ResponseException re = expectThrows(ResponseException.class, () -> runEsqlQuery(query)); + + assertThat(re.getMessage(), containsString("Field [semantic_text_field] has multiple inference IDs associated with it")); + + assertEquals(400, re.getResponse().getStatusLine().getStatusCode()); + } + + public void testWithInferenceNotConfigured() { + String query = """ + from test-semantic3 + | where match(semantic_text_field, "something") + """; + ResponseException re = expectThrows(ResponseException.class, () -> runEsqlQuery(query)); + + assertThat(re.getMessage(), containsString("Inference endpoint not found")); + assertEquals(404, re.getResponse().getStatusLine().getStatusCode()); + } + + @Before + public void setUpIndices() throws IOException { + assumeTrue("semantic text capability not available", EsqlCapabilities.Cap.SEMANTIC_TEXT_TYPE.isEnabled()); + + var settings = Settings.builder().build(); + + String mapping1 = """ + "properties": { + "semantic_text_field": { + "type": "semantic_text", + "inference_id": "test_sparse_inference" + } + } + """; + createIndex(adminClient(), "test-semantic1", settings, mapping1); + + String mapping2 = """ + "properties": { + "semantic_text_field": { + "type": "semantic_text", + "inference_id": "test_dense_inference" + } + } + """; + createIndex(adminClient(), "test-semantic2", settings, mapping2); + + String mapping3 = """ + "properties": { + "semantic_text_field": { + "type": "semantic_text", + "inference_id": "inexistent" + } + } + """; + createIndex(adminClient(), "test-semantic3", settings, mapping3); + } + + @Before + public void setUpTextEmbeddingInferenceEndpoint() throws IOException { + assumeTrue("semantic text capability not available", EsqlCapabilities.Cap.SEMANTIC_TEXT_TYPE.isEnabled()); + Request request = new Request("PUT", "_inference/text_embedding/test_dense_inference"); + request.setJsonEntity(""" + { + "service": "test_service", + "service_settings": { + "model": "my_model", + "api_key": "abc64" + }, + "task_settings": { + } + } + """); + adminClient().performRequest(request); + } + + @After + public void wipeData() throws IOException { + assumeTrue("semantic text capability not available", EsqlCapabilities.Cap.SEMANTIC_TEXT_TYPE.isEnabled()); + adminClient().performRequest(new Request("DELETE", "*")); + + try { + adminClient().performRequest(new Request("DELETE", "_inference/test_dense_inference")); + } catch (ResponseException e) { + // 404 here means the endpoint was not created + if (e.getResponse().getStatusLine().getStatusCode() != 404) { + throw e; + } + } + } + + private Map runEsqlQuery(String query) throws IOException { + RestEsqlTestCase.RequestObjectBuilder builder = RestEsqlTestCase.requestObjectBuilder().query(query); + return RestEsqlTestCase.runEsqlSync(builder); + } +} diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java index 18ce9d7e3e057..66fd7d3ee5eb5 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/EsqlTestUtils.java @@ -70,6 +70,7 @@ import org.elasticsearch.xpack.esql.plugin.EsqlPlugin; import org.elasticsearch.xpack.esql.plugin.QueryPragmas; import org.elasticsearch.xpack.esql.session.Configuration; +import org.elasticsearch.xpack.esql.session.QueryBuilderResolver; import org.elasticsearch.xpack.esql.stats.Metrics; import org.elasticsearch.xpack.esql.stats.SearchStats; import org.elasticsearch.xpack.versionfield.Version; @@ -351,6 +352,8 @@ public String toString() { public static final Verifier TEST_VERIFIER = new Verifier(new Metrics(new EsqlFunctionRegistry()), new XPackLicenseState(() -> 0L)); + public static final QueryBuilderResolver MOCK_QUERY_BUILDER_RESOLVER = new MockQueryBuilderResolver(); + private EsqlTestUtils() {} public static Configuration configuration(QueryPragmas pragmas, String query) { diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/MockQueryBuilderResolver.java b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/MockQueryBuilderResolver.java new file mode 100644 index 0000000000000..7af3a89108fc0 --- /dev/null +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/MockQueryBuilderResolver.java @@ -0,0 +1,30 @@ +/* + * 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.esql; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.session.QueryBuilderResolver; +import org.elasticsearch.xpack.esql.session.Result; + +import java.util.function.BiConsumer; + +public class MockQueryBuilderResolver extends QueryBuilderResolver { + public MockQueryBuilderResolver() { + super(null, null, null, null); + } + + @Override + public void resolveQueryBuilders( + LogicalPlan plan, + ActionListener listener, + BiConsumer> callback + ) { + callback.accept(plan, listener); + } +} diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-function.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-function.csv-spec index 5ea169e1b110d..6c9a6fed3853c 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-function.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-function.csv-spec @@ -597,3 +597,74 @@ from employees,employees_incompatible emp_no_bool:boolean ; + +testMatchWithSemanticText +required_capability: match_function +required_capability: semantic_text_type + +from semantic_text +| where match(semantic_text_field, "something") +| keep semantic_text_field +| sort semantic_text_field asc +; + +semantic_text_field:semantic_text +all we have to decide is what to do with the time that is given to us +be excellent to each other +live long and prosper +; + +testMatchWithSemanticTextAndKeyword +required_capability: match_function +required_capability: semantic_text_type + +from semantic_text +| where match(semantic_text_field, "something") AND match(host, "host1") +| keep semantic_text_field, host +; + +semantic_text_field:semantic_text | host:keyword +live long and prosper | host1 +; + +testMatchWithSemanticTextMultiValueField +required_capability: match_function +required_capability: semantic_text_type + +from semantic_text metadata _id +| where match(st_multi_value, "something") AND match(host, "host1") +| keep _id, st_multi_value +; + +_id: keyword | st_multi_value:semantic_text +1 | ["Hello there!", "This is a random value", "for testing purposes"] +; + +testMatchWithSemanticTextWithEvalsAndOtherFunctionsAndStats +required_capability: match_function +required_capability: semantic_text_type + +from semantic_text +| where qstr("description:some*") +| eval size = mv_count(st_multi_value) +| where match(semantic_text_field, "something") AND size > 1 AND match(host, "host1") +| STATS result = count(*) +; + +result:long +1 +; + +testMatchWithSemanticTextAndKql +required_capability: match_function +required_capability: semantic_text_type +required_capability: kql_function + +from semantic_text +| where kql("host:host1") AND match(semantic_text_field, "something") +| KEEP host, semantic_text_field +; + +host:keyword | semantic_text_field:semantic_text +"host1" | live long and prosper +; diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-operator.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-operator.csv-spec index 7906f8b69162b..721443a70fe20 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-operator.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/match-operator.csv-spec @@ -608,3 +608,73 @@ from employees,employees_incompatible emp_no_bool:boolean ; +testMatchWithSemanticText +required_capability: match_operator_colon +required_capability: semantic_text_type + +from semantic_text +| where semantic_text_field:"something" +| keep semantic_text_field +| sort semantic_text_field asc +; + +semantic_text_field:semantic_text +all we have to decide is what to do with the time that is given to us +be excellent to each other +live long and prosper +; + +testMatchWithSemanticTextAndKeyword +required_capability: match_operator_colon +required_capability: semantic_text_type + +from semantic_text +| where semantic_text_field:"something" AND host:"host1" +| keep semantic_text_field, host +; + +semantic_text_field:semantic_text | host:keyword +live long and prosper | host1 +; + +testMatchWithSemanticTextMultiValueField +required_capability: match_operator_colon +required_capability: semantic_text_type + +from semantic_text metadata _id +| where st_multi_value:"something" AND match(host, "host1") +| keep _id, st_multi_value +; + +_id: keyword | st_multi_value:semantic_text +1 | ["Hello there!", "This is a random value", "for testing purposes"] +; + +testMatchWithSemanticTextWithEvalsAndOtherFunctionsAndStats +required_capability: match_operator_colon +required_capability: semantic_text_type + +from semantic_text +| where qstr("description:some*") +| eval size = mv_count(st_multi_value) +| where semantic_text_field:"something" AND size > 1 AND match(host, "host1") +| STATS result = count(*) +; + +result:long +1 +; + +testMatchWithSemanticTextAndKql +required_capability: match_operator_colon +required_capability: semantic_text_type +required_capability: kql_function + +from semantic_text +| where kql("host:host1") AND semantic_text_field:"something" +| KEEP host, semantic_text_field +; + +host:keyword | semantic_text_field:semantic_text +"host1" | live long and prosper +; diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/scoring.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/scoring.csv-spec index 72632c62603aa..9d3526982f9ef 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/scoring.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/scoring.csv-spec @@ -317,3 +317,43 @@ book_no:keyword | title:text 2924 | A Gentle Creature and Other Stories: White Nights, A Gentle Creature, and The Dream of a Ridiculous Man (The World's Classics) | foobar 5948 | That We Are Gentle Creatures | foobar ; + + +semanticTextMatch +required_capability: metadata_score +required_capability: semantic_text_type +required_capability: match_function + +from semantic_text metadata _id, _score +| where match(semantic_text_field, "something") +| sort _score desc +| keep _id +; + +_id:keyword +2 +3 +1 +; + +semanticTextMatchWithAllTheTextFunctions + +required_capability: metadata_score +required_capability: semantic_text_type +required_capability: match_function +required_capability: kql_function +required_capability: qstr_function + +from semantic_text metadata _id, _score +| where match(semantic_text_field, "something") + AND match(description, "some") + AND kql("description:some*") + AND NOT qstr("host:host1") +| sort _score desc +| keep _id +; + +_id:keyword +2 +3 +; diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/KqlFunctionIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/KqlFunctionIT.java index d58637ab52c86..0e84ac7588ad6 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/KqlFunctionIT.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/KqlFunctionIT.java @@ -10,13 +10,17 @@ import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.support.WriteRequest; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.util.CollectionUtils; import org.elasticsearch.index.query.QueryShardException; +import org.elasticsearch.plugins.Plugin; import org.elasticsearch.xpack.esql.VerificationException; import org.elasticsearch.xpack.esql.action.AbstractEsqlIntegTestCase; import org.elasticsearch.xpack.esql.action.EsqlCapabilities; +import org.elasticsearch.xpack.kql.KqlPlugin; import org.junit.Before; import org.junit.BeforeClass; +import java.util.Collection; import java.util.List; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; @@ -141,4 +145,9 @@ private void createAndPopulateIndex() { .get(); ensureYellow(indexName); } + + @Override + protected Collection> nodePlugins() { + return CollectionUtils.appendToCopy(super.nodePlugins(), KqlPlugin.class); + } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/execution/PlanExecutor.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/execution/PlanExecutor.java index c1269009c6a41..dad63d25046d9 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/execution/PlanExecutor.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/execution/PlanExecutor.java @@ -23,6 +23,7 @@ import org.elasticsearch.xpack.esql.session.Configuration; import org.elasticsearch.xpack.esql.session.EsqlSession; import org.elasticsearch.xpack.esql.session.IndexResolver; +import org.elasticsearch.xpack.esql.session.QueryBuilderResolver; import org.elasticsearch.xpack.esql.session.Result; import org.elasticsearch.xpack.esql.stats.Metrics; import org.elasticsearch.xpack.esql.stats.PlanningMetrics; @@ -59,6 +60,7 @@ public void esql( EsqlExecutionInfo executionInfo, IndicesExpressionGrouper indicesExpressionGrouper, EsqlSession.PlanRunner planRunner, + QueryBuilderResolver queryBuilderResolver, ActionListener listener ) { final PlanningMetrics planningMetrics = new PlanningMetrics(); @@ -73,7 +75,8 @@ public void esql( mapper, verifier, planningMetrics, - indicesExpressionGrouper + indicesExpressionGrouper, + queryBuilderResolver ); QueryMetric clientId = QueryMetric.fromString("rest"); metrics.total(clientId); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/Match.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/Match.java index 0b2268fe1b022..e695a94198dab 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/Match.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/fulltext/Match.java @@ -51,6 +51,7 @@ import static org.elasticsearch.xpack.esql.core.type.DataType.IP; import static org.elasticsearch.xpack.esql.core.type.DataType.KEYWORD; import static org.elasticsearch.xpack.esql.core.type.DataType.LONG; +import static org.elasticsearch.xpack.esql.core.type.DataType.SEMANTIC_TEXT; import static org.elasticsearch.xpack.esql.core.type.DataType.TEXT; import static org.elasticsearch.xpack.esql.core.type.DataType.UNSIGNED_LONG; import static org.elasticsearch.xpack.esql.core.type.DataType.VERSION; @@ -70,6 +71,7 @@ public class Match extends FullTextFunction implements Validatable { public static final Set FIELD_DATA_TYPES = Set.of( KEYWORD, TEXT, + SEMANTIC_TEXT, BOOLEAN, DATETIME, DATE_NANOS, diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/TransportEsqlQueryAction.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/TransportEsqlQueryAction.java index 76bfb95d07926..50d5819688e46 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/TransportEsqlQueryAction.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/plugin/TransportEsqlQueryAction.java @@ -12,6 +12,7 @@ import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.HandledTransportAction; import org.elasticsearch.client.internal.Client; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; @@ -42,6 +43,7 @@ import org.elasticsearch.xpack.esql.execution.PlanExecutor; import org.elasticsearch.xpack.esql.session.Configuration; import org.elasticsearch.xpack.esql.session.EsqlSession.PlanRunner; +import org.elasticsearch.xpack.esql.session.QueryBuilderResolver; import org.elasticsearch.xpack.esql.session.Result; import java.io.IOException; @@ -68,6 +70,7 @@ public class TransportEsqlQueryAction extends HandledTransportAction asyncTaskManagementService; private final RemoteClusterService remoteClusterService; + private final QueryBuilderResolver queryBuilderResolver; @Inject @SuppressWarnings("this-escape") @@ -82,7 +85,8 @@ public TransportEsqlQueryAction( BigArrays bigArrays, BlockFactory blockFactory, Client client, - NamedWriteableRegistry registry + NamedWriteableRegistry registry, + IndexNameExpressionResolver indexNameExpressionResolver ) { // TODO replace SAME when removing workaround for https://github.com/elastic/elasticsearch/issues/97916 @@ -121,6 +125,7 @@ public TransportEsqlQueryAction( bigArrays ); this.remoteClusterService = transportService.getRemoteClusterService(); + this.queryBuilderResolver = new QueryBuilderResolver(searchService, clusterService, transportService, indexNameExpressionResolver); } @Override @@ -191,6 +196,7 @@ private void innerExecute(Task task, EsqlQueryRequest request, ActionListener toResponse(task, request, configuration, result)) ); } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java index c0290fa2b1d73..bd3b3bdb3483c 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/EsqlSession.java @@ -113,6 +113,7 @@ public interface PlanRunner { private final PhysicalPlanOptimizer physicalPlanOptimizer; private final PlanningMetrics planningMetrics; private final IndicesExpressionGrouper indicesExpressionGrouper; + private final QueryBuilderResolver queryBuilderResolver; public EsqlSession( String sessionId, @@ -125,7 +126,8 @@ public EsqlSession( Mapper mapper, Verifier verifier, PlanningMetrics planningMetrics, - IndicesExpressionGrouper indicesExpressionGrouper + IndicesExpressionGrouper indicesExpressionGrouper, + QueryBuilderResolver queryBuilderResolver ) { this.sessionId = sessionId; this.configuration = configuration; @@ -139,6 +141,7 @@ public EsqlSession( this.physicalPlanOptimizer = new PhysicalPlanOptimizer(new PhysicalOptimizerContext(configuration)); this.planningMetrics = planningMetrics; this.indicesExpressionGrouper = indicesExpressionGrouper; + this.queryBuilderResolver = queryBuilderResolver; } public String sessionId() { @@ -158,7 +161,16 @@ public void execute(EsqlQueryRequest request, EsqlExecutionInfo executionInfo, P new EsqlSessionCCSUtils.CssPartialErrorsActionListener(executionInfo, listener) { @Override public void onResponse(LogicalPlan analyzedPlan) { - executeOptimizedPlan(request, executionInfo, planRunner, optimizedPlan(analyzedPlan), listener); + try { + var optimizedPlan = optimizedPlan(analyzedPlan); + queryBuilderResolver.resolveQueryBuilders( + optimizedPlan, + listener, + (newPlan, next) -> executeOptimizedPlan(request, executionInfo, planRunner, newPlan, next) + ); + } catch (Exception e) { + listener.onFailure(e); + } } } ); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/QueryBuilderResolver.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/QueryBuilderResolver.java new file mode 100644 index 0000000000000..b6424c5f7fa56 --- /dev/null +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/session/QueryBuilderResolver.java @@ -0,0 +1,178 @@ +/* + * 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.esql.session; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.ResolvedIndices; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.index.query.QueryBuilder; +import org.elasticsearch.index.query.QueryRewriteContext; +import org.elasticsearch.index.query.Rewriteable; +import org.elasticsearch.search.SearchService; +import org.elasticsearch.transport.TransportService; +import org.elasticsearch.xpack.esql.action.EsqlCapabilities; +import org.elasticsearch.xpack.esql.core.util.Holder; +import org.elasticsearch.xpack.esql.expression.function.fulltext.FullTextFunction; +import org.elasticsearch.xpack.esql.plan.logical.EsRelation; +import org.elasticsearch.xpack.esql.plan.logical.LogicalPlan; +import org.elasticsearch.xpack.esql.planner.PlannerUtils; + +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.function.BiConsumer; + +/** + * Some {@link FullTextFunction} implementations such as {@link org.elasticsearch.xpack.esql.expression.function.fulltext.Match} + * will be translated to a {@link QueryBuilder} that require a rewrite phase on the coordinator. + * {@link QueryBuilderResolver#resolveQueryBuilders(LogicalPlan, ActionListener, BiConsumer)} will rewrite the plan by replacing + * {@link FullTextFunction} expression with new ones that hold rewritten {@link QueryBuilder}s. + */ +public class QueryBuilderResolver { + private final SearchService searchService; + private final ClusterService clusterService; + private final TransportService transportService; + private final IndexNameExpressionResolver indexNameExpressionResolver; + + public QueryBuilderResolver( + SearchService searchService, + ClusterService clusterService, + TransportService transportService, + IndexNameExpressionResolver indexNameExpressionResolver + ) { + this.searchService = searchService; + this.clusterService = clusterService; + this.transportService = transportService; + this.indexNameExpressionResolver = indexNameExpressionResolver; + } + + public void resolveQueryBuilders( + LogicalPlan plan, + ActionListener listener, + BiConsumer> callback + ) { + // TODO: remove once SEMANTIC_TEXT_TYPE is enabled outside of snapshots + if (false == EsqlCapabilities.Cap.SEMANTIC_TEXT_TYPE.isEnabled()) { + callback.accept(plan, listener); + return; + } + + if (plan.optimized() == false) { + listener.onFailure(new IllegalStateException("Expected optimized plan before query builder rewrite.")); + return; + } + + Set unresolved = fullTextFunctions(plan); + Set indexNames = indexNames(plan); + + if (indexNames == null || indexNames.isEmpty() || unresolved.isEmpty()) { + callback.accept(plan, listener); + return; + } + QueryRewriteContext ctx = queryRewriteContext(indexNames); + FullTextFunctionsRewritable rewritable = new FullTextFunctionsRewritable(unresolved); + Rewriteable.rewriteAndFetch(rewritable, ctx, new ActionListener() { + @Override + public void onResponse(FullTextFunctionsRewritable fullTextFunctionsRewritable) { + try { + LogicalPlan newPlan = planWithResolvedQueryBuilders(plan, fullTextFunctionsRewritable.results()); + callback.accept(newPlan, listener); + } catch (Exception e) { + onFailure(e); + } + } + + @Override + public void onFailure(Exception e) { + listener.onFailure(e); + } + }); + } + + private Set fullTextFunctions(LogicalPlan plan) { + Set functions = new HashSet<>(); + plan.forEachExpressionDown(FullTextFunction.class, func -> functions.add(func)); + return functions; + } + + public Set indexNames(LogicalPlan plan) { + Holder> indexNames = new Holder<>(); + + plan.forEachDown(EsRelation.class, esRelation -> { indexNames.set(esRelation.index().concreteIndices()); }); + + return indexNames.get(); + } + + public LogicalPlan planWithResolvedQueryBuilders(LogicalPlan plan, Map newQueryBuilders) { + LogicalPlan newPlan = plan.transformExpressionsDown(FullTextFunction.class, m -> { + if (newQueryBuilders.keySet().contains(m)) { + return m.replaceQueryBuilder(newQueryBuilders.get(m)); + } + return m; + }); + // The given plan was already analyzed and optimized, so we set the resulted plan to optimized as well. + newPlan.setOptimized(); + return newPlan; + } + + private QueryRewriteContext queryRewriteContext(Set indexNames) { + ResolvedIndices resolvedIndices = ResolvedIndices.resolveWithIndexNamesAndOptions( + indexNames.toArray(String[]::new), + IndexResolver.FIELD_CAPS_INDICES_OPTIONS, + clusterService.state(), + indexNameExpressionResolver, + transportService.getRemoteClusterService(), + System.currentTimeMillis() + ); + + return searchService.getRewriteContext(() -> System.currentTimeMillis(), resolvedIndices, null); + } + + private class FullTextFunctionsRewritable implements Rewriteable { + + private final Map queryBuilderMap; + + FullTextFunctionsRewritable(Map queryBuilderMap) { + this.queryBuilderMap = queryBuilderMap; + } + + FullTextFunctionsRewritable(Set functions) { + this.queryBuilderMap = new HashMap<>(); + + for (FullTextFunction func : functions) { + queryBuilderMap.put(func, func.asQuery(PlannerUtils.TRANSLATOR_HANDLER).asBuilder()); + } + } + + @Override + public FullTextFunctionsRewritable rewrite(QueryRewriteContext ctx) throws IOException { + Map results = new HashMap<>(); + + boolean hasChanged = false; + for (FullTextFunction func : queryBuilderMap.keySet()) { + var initial = queryBuilderMap.get(func); + var rewritten = Rewriteable.rewrite(initial, ctx, false); + + if (rewritten.equals(initial) == false) { + hasChanged = true; + } + + results.put(func, rewritten); + } + + return hasChanged ? new FullTextFunctionsRewritable(results) : this; + } + + public Map results() { + return queryBuilderMap; + } + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java index 717ac7b5a62a7..70794e4a82130 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java @@ -445,7 +445,8 @@ private ActualResults executePlan(BigArrays bigArrays) throws Exception { mapper, TEST_VERIFIER, new PlanningMetrics(), - null + null, + EsqlTestUtils.MOCK_QUERY_BUILDER_RESOLVER ); TestPhysicalOperationProviders physicalOperationProviders = testOperationProviders(testDataset); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalPhysicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalPhysicalPlanOptimizerTests.java index 406e27c1517e5..928c849b847d5 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalPhysicalPlanOptimizerTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LocalPhysicalPlanOptimizerTests.java @@ -1450,6 +1450,11 @@ private void checkMatchFunctionPushDown( var analyzer = makeAnalyzer("mapping-all-types.json"); // Check for every possible query data type for (DataType fieldDataType : fieldDataTypes) { + // TODO: semantic_text is not present in mapping-all-types.json so we skip it for now + if (fieldDataType == DataType.SEMANTIC_TEXT) { + continue; + } + var queryValue = randomQueryValue(fieldDataType); String fieldName = fieldDataType == DataType.DATETIME ? "date" : fieldDataType.name().toLowerCase(Locale.ROOT); @@ -1483,6 +1488,7 @@ private static Object randomQueryValue(DataType dataType) { case KEYWORD -> randomAlphaOfLength(5); case IP -> NetworkAddress.format(randomIp(randomBoolean())); case TEXT -> randomAlphaOfLength(50); + case SEMANTIC_TEXT -> randomAlphaOfLength(5); case VERSION -> VersionUtils.randomVersion(random()).toString(); default -> throw new IllegalArgumentException("Unexpected type: " + dataType); }; diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/stats/PlanExecutorMetricsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/stats/PlanExecutorMetricsTests.java index b323efad2b4c3..539cd0314a4d1 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/stats/PlanExecutorMetricsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/stats/PlanExecutorMetricsTests.java @@ -123,6 +123,7 @@ public void testFailedMetric() { new EsqlExecutionInfo(randomBoolean()), groupIndicesByCluster, runPhase, + EsqlTestUtils.MOCK_QUERY_BUILDER_RESOLVER, new ActionListener<>() { @Override public void onResponse(Result result) { @@ -152,6 +153,7 @@ public void onFailure(Exception e) { new EsqlExecutionInfo(randomBoolean()), groupIndicesByCluster, runPhase, + EsqlTestUtils.MOCK_QUERY_BUILDER_RESOLVER, new ActionListener<>() { @Override public void onResponse(Result result) {} From 47d5e87d21dd682539c9da24a4cd321b68a97f05 Mon Sep 17 00:00:00 2001 From: Nikolaj Volgushev Date: Wed, 18 Dec 2024 13:18:14 +0100 Subject: [PATCH 38/60] Prevent boot if bind DN is set without password (#118366) LDAP/AD authentication realms can be configured to authenticate through LDAP via a bind user. For this it's necessary to set a bind DN (via `bind_dn`) together with a bind password (via `bind_password` or `secure_bind_password`). Setting a bind DN without a bind password will cause all LDAP/AD realm authentication to fail, leaving the node non-operational. This PR adds a bootstrap check to prevent a misconfigured node from starting. This behavior was deprecated in https://github.com/elastic/elasticsearch/pull/85326. Closes: ES-9749 --- docs/changelog/118366.yaml | 22 +++++++++++ .../authc/ldap/PoolingSessionFactory.java | 37 +++++-------------- .../LdapUserSearchSessionFactoryTests.java | 29 +++++++-------- 3 files changed, 46 insertions(+), 42 deletions(-) create mode 100644 docs/changelog/118366.yaml diff --git a/docs/changelog/118366.yaml b/docs/changelog/118366.yaml new file mode 100644 index 0000000000000..cfeab1937738b --- /dev/null +++ b/docs/changelog/118366.yaml @@ -0,0 +1,22 @@ +pr: 118366 +summary: |- + Configuring a bind DN in an LDAP or Active Directory (AD) realm without a corresponding bind password + will prevent node from starting +area: Authentication +type: breaking +issues: [] +breaking: + title: -| + Configuring a bind DN in an LDAP or Active Directory (AD) realm without + a corresponding bind password will prevent node from starting + area: Cluster and node setting + details: -| + For LDAP or AD authentication realms, setting a bind DN (via the + `xpack.security.authc.realms.ldap.*.bind_dn` or `xpack.security.authc.realms.active_directory.*.bind_dn` + realm settings) without a bind password is a misconfiguration that may prevent successful authentication + to the node. Nodes will fail to start if a bind DN is specified without a password. + impact: -| + If you have a bind DN configured for an LDAP or AD authentication + realm, set a bind password for {ref}/ldap-realm.html#ldap-realm-configuration[LDAP] + or {ref}/active-directory-realm.html#ad-realm-configuration[Active Directory]. + Configuring a bind DN without a password prevents the misconfigured node from starting. diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ldap/PoolingSessionFactory.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ldap/PoolingSessionFactory.java index 4f87ac27be141..f31d5647b4cc5 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ldap/PoolingSessionFactory.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ldap/PoolingSessionFactory.java @@ -16,7 +16,6 @@ import org.apache.logging.log4j.Logger; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.common.logging.DeprecationCategory; import org.elasticsearch.common.settings.SecureString; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; @@ -74,7 +73,7 @@ abstract class PoolingSessionFactory extends SessionFactory implements Releasabl super(config, sslService, threadPool); this.groupResolver = groupResolver; this.bindDn = bindDn; - this.bindRequest = new AtomicReference<>(buildBindRequest(config.settings(), false)); + this.bindRequest = new AtomicReference<>(buildBindRequest(config.settings())); this.useConnectionPool = config.getSetting(poolingEnabled); if (useConnectionPool) { this.connectionPool = createConnectionPool(config, serverSet, timeout, logger, bindRequest.get(), healthCheckDNSupplier); @@ -93,11 +92,9 @@ abstract class PoolingSessionFactory extends SessionFactory implements Releasabl * will perform a setting consistency validation and throw {@link SettingsException} in case of violation. * Due to legacy reasons and BWC, when {@code reloadRequest} is se to {@code false}, this method will only log a warning message. * - * @param reloadRequest {@code true} if this method is called during reloading of secure settings, - * {@code false} if it is called during bootstrapping. * @return A new {@link SimpleBindRequest} that contains configured bind DN and password. */ - private SimpleBindRequest buildBindRequest(Settings settings, boolean reloadRequest) { + private SimpleBindRequest buildBindRequest(Settings settings) { final byte[] bindPassword; final Setting legacyPasswordSetting = config.getConcreteSetting(LEGACY_BIND_PASSWORD); final Setting securePasswordSetting = config.getConcreteSetting(SECURE_BIND_PASSWORD); @@ -119,27 +116,13 @@ private SimpleBindRequest buildBindRequest(Settings settings, boolean reloadRequ return new SimpleBindRequest(); } else { if (bindPassword == null) { - if (reloadRequest) { - throw new SettingsException( - "[{}] is set but no bind password is specified. Without a corresponding bind password, " - + "all {} realm authentication will fail. Specify a bind password via [{}].", - RealmSettings.getFullSettingKey(config, PoolingSessionFactorySettings.BIND_DN), - config.type(), - RealmSettings.getFullSettingKey(config, SECURE_BIND_PASSWORD) - ); - } else { - deprecationLogger.critical( - DeprecationCategory.SECURITY, - "bind_dn_set_without_password", - "[{}] is set but no bind password is specified. Without a corresponding bind password, " - + "all {} realm authentication will fail. Specify a bind password via [{}] or [{}]. " - + "In the next major release, nodes with incomplete bind credentials will fail to start.", - RealmSettings.getFullSettingKey(config, PoolingSessionFactorySettings.BIND_DN), - config.type(), - RealmSettings.getFullSettingKey(config, SECURE_BIND_PASSWORD), - RealmSettings.getFullSettingKey(config, LEGACY_BIND_PASSWORD) - ); - } + throw new SettingsException( + "[{}] is set but no bind password is specified. Without a corresponding bind password, " + + "all {} realm authentication will fail. Specify a bind password via [{}].", + RealmSettings.getFullSettingKey(config, PoolingSessionFactorySettings.BIND_DN), + config.type(), + RealmSettings.getFullSettingKey(config, SECURE_BIND_PASSWORD) + ); } return new SimpleBindRequest(this.bindDn, bindPassword); } @@ -148,7 +131,7 @@ private SimpleBindRequest buildBindRequest(Settings settings, boolean reloadRequ @Override public void reload(Settings settings) { final SimpleBindRequest oldRequest = bindRequest.get(); - final SimpleBindRequest newRequest = buildBindRequest(settings, true); + final SimpleBindRequest newRequest = buildBindRequest(settings); if (bindRequestEquals(newRequest, oldRequest) == false) { if (bindRequest.compareAndSet(oldRequest, newRequest)) { if (connectionPool != null) { diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapUserSearchSessionFactoryTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapUserSearchSessionFactoryTests.java index acb4359b37323..5482d7711031e 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapUserSearchSessionFactoryTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapUserSearchSessionFactoryTests.java @@ -21,6 +21,7 @@ import org.elasticsearch.common.settings.SecureString; import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.core.TimeValue; import org.elasticsearch.env.TestEnvironment; @@ -45,7 +46,6 @@ import java.util.Locale; import static org.elasticsearch.xpack.core.security.authc.RealmSettings.getFullSettingKey; -import static org.elasticsearch.xpack.core.security.authc.ldap.PoolingSessionFactorySettings.BIND_DN; import static org.elasticsearch.xpack.core.security.authc.ldap.PoolingSessionFactorySettings.LEGACY_BIND_PASSWORD; import static org.elasticsearch.xpack.core.security.authc.ldap.PoolingSessionFactorySettings.SECURE_BIND_PASSWORD; import static org.hamcrest.Matchers.containsString; @@ -199,7 +199,7 @@ public void testUserSearchBaseScopeFailsWithWrongBaseDN() throws Exception { assertDeprecationWarnings(config.identifier(), useAttribute, useLegacyBindPassword); } - public void testConstructorLogsErrorIfBindDnSetWithoutPassword() throws Exception { + public void testConstructorThrowsIfBindDnSetWithoutPassword() throws Exception { String groupSearchBase = "o=sevenSeas"; String userSearchBase = "cn=William Bush,ou=people,o=sevenSeas"; @@ -216,19 +216,18 @@ public void testConstructorLogsErrorIfBindDnSetWithoutPassword() throws Exceptio new ThreadContext(globalSettings) ); - try (LdapUserSearchSessionFactory ignored = getLdapUserSearchSessionFactory(config, sslService, threadPool)) { - assertCriticalWarnings( - String.format( - Locale.ROOT, - "[%s] is set but no bind password is specified. Without a corresponding bind password, " - + "all ldap realm authentication will fail. Specify a bind password via [%s] or [%s]. " - + "In the next major release, nodes with incomplete bind credentials will fail to start.", - RealmSettings.getFullSettingKey(config, BIND_DN), - RealmSettings.getFullSettingKey(config, SECURE_BIND_PASSWORD), - RealmSettings.getFullSettingKey(config, LEGACY_BIND_PASSWORD) - ) - ); - } + Exception ex = expectThrows(SettingsException.class, () -> getLdapUserSearchSessionFactory(config, sslService, threadPool)); + assertEquals( + String.format( + Locale.ROOT, + "[%s] is set but no bind password is specified. Without a corresponding bind password, " + + "all %s realm authentication will fail. Specify a bind password via [%s].", + RealmSettings.getFullSettingKey(config, PoolingSessionFactorySettings.BIND_DN), + config.type(), + RealmSettings.getFullSettingKey(config, SECURE_BIND_PASSWORD) + ), + ex.getMessage() + ); } public void testConstructorThrowsIfBothLegacyAndSecureBindPasswordSet() throws Exception { From ede1a7ab2af7156edd0e3cb6626cb9cbf8e858c4 Mon Sep 17 00:00:00 2001 From: Luca Cavanna Date: Wed, 18 Dec 2024 13:46:21 +0100 Subject: [PATCH 39/60] Include v7 in IndexVersionUtils#ALL_VERSIONS (#118793) We are going to retain read-only compatibility with v7 index versions upon upgrade to v9. This means that all the v7 index versions and corresponding version conditionals will stay around for another major series. This PR reflects this decision in the codebase. No need to filter index versions when retrieving ALL_VERSIONS, and we can remove corresponding @UpdateForV9 annotations from the IndexVersions class. At the same time, there are tests that need to randomize version but need to write to an index, hence 7x versions should be filtered out. The overall goal is to extend testing to v7 index versions when possible, and making randomization across writeable versions an exception that certain tests can rely on as needed. These are the mechanical steps I made in this PR: - Rename `getFirstVersion` to `getLowestReadCompatibleVersion`, which returns the lowest supported index version ( which can not be written to) - Introduce `getLowestWriteCompatibleVersion` to identify the lowest writeable version. This is used by tests that used to call `getFirstVersion` and need to write to the index. - Remove `randomVersion(Random random)` in favour of `randomVersion()` . It was always called providing `random()` which is equivalent to what `randomVersion()` already does. - Introduce `randomWriteVersion` for tests that need a random writeable version. Moved tests that need it to use it (from `randomVersion` to `randomWriteVersion`) There is still work to do in `IndexVersionUtils` to extend testing, especially as some randomized tests have a lower bound of `MINIMUM_COMPATIBLE_VERSION` hence don't include v7 index versions yet. We will address that as a follow-up. --- .../common/NGramTokenizerFactoryTests.java | 2 +- .../common/PersianAnalyzerProviderTests.java | 2 +- .../common/RomanianAnalyzerTests.java | 2 +- .../StemmerTokenFilterFactoryTests.java | 10 +++++----- .../admin/indices/create/ShrinkIndexIT.java | 2 +- .../cluster/ClusterStateDiffIT.java | 7 ++++--- .../PreBuiltAnalyzerIntegrationIT.java | 2 +- .../indices/recovery/IndexRecoveryIT.java | 2 +- .../elasticsearch/index/IndexVersions.java | 11 +++++----- .../HumanReadableIndexSettingsTests.java | 2 +- .../MetadataCreateIndexServiceTests.java | 6 +----- .../MetadataDeleteIndexServiceTests.java | 6 +++--- .../MetadataIndexAliasesServiceTests.java | 2 +- .../MetadataIndexStateServiceTests.java | 2 +- .../elasticsearch/env/NodeMetadataTests.java | 2 +- .../index/IndexVersionTests.java | 9 ++------- .../index/analysis/AnalysisRegistryTests.java | 12 +++++------ .../index/analysis/PreBuiltAnalyzerTests.java | 6 +++--- .../PreConfiguredTokenFilterTests.java | 6 +++--- .../index/engine/InternalEngineTests.java | 2 +- .../vectors/DenseVectorFieldMapperTests.java | 8 ++++---- .../indices/analysis/AnalysisModuleTests.java | 6 +++--- .../IncorrectSetupStablePluginsTests.java | 6 +++--- .../StableAnalysisPluginsNoSettingsTests.java | 2 +- ...tableAnalysisPluginsWithSettingsTests.java | 8 ++++---- .../recovery/RecoverySourceHandlerTests.java | 2 +- .../nodesinfo/NodeInfoStreamingTests.java | 2 +- .../PersistentTasksClusterServiceTests.java | 4 ++-- ...SnapshotsInProgressSerializationTests.java | 2 +- .../index/KnownIndexVersions.java | 6 +++++- .../test/index/IndexVersionUtils.java | 20 ++++++++++++------- ...eprecationRoleDescriptorConsumerTests.java | 2 +- 32 files changed, 83 insertions(+), 80 deletions(-) diff --git a/modules/analysis-common/src/test/java/org/elasticsearch/analysis/common/NGramTokenizerFactoryTests.java b/modules/analysis-common/src/test/java/org/elasticsearch/analysis/common/NGramTokenizerFactoryTests.java index 8c365a1362f85..35c01b5b9296f 100644 --- a/modules/analysis-common/src/test/java/org/elasticsearch/analysis/common/NGramTokenizerFactoryTests.java +++ b/modules/analysis-common/src/test/java/org/elasticsearch/analysis/common/NGramTokenizerFactoryTests.java @@ -161,7 +161,7 @@ public void testBackwardsCompatibilityEdgeNgramTokenFilter() throws Exception { for (int i = 0; i < iters; i++) { final Index index = new Index("test", "_na_"); final String name = "ngr"; - IndexVersion v = IndexVersionUtils.randomVersion(random()); + IndexVersion v = IndexVersionUtils.randomVersion(); Builder builder = newAnalysisSettingsBuilder().put("min_gram", 2).put("max_gram", 3); boolean reverse = random().nextBoolean(); if (reverse) { diff --git a/modules/analysis-common/src/test/java/org/elasticsearch/analysis/common/PersianAnalyzerProviderTests.java b/modules/analysis-common/src/test/java/org/elasticsearch/analysis/common/PersianAnalyzerProviderTests.java index 7b962538c2a10..153c3e9549285 100644 --- a/modules/analysis-common/src/test/java/org/elasticsearch/analysis/common/PersianAnalyzerProviderTests.java +++ b/modules/analysis-common/src/test/java/org/elasticsearch/analysis/common/PersianAnalyzerProviderTests.java @@ -56,7 +56,7 @@ public void testPersianAnalyzerPostLucene10() throws IOException { public void testPersianAnalyzerPreLucene10() throws IOException { IndexVersion preLucene10Version = IndexVersionUtils.randomVersionBetween( random(), - IndexVersionUtils.getFirstVersion(), + IndexVersionUtils.getLowestReadCompatibleVersion(), IndexVersionUtils.getPreviousVersion(IndexVersions.UPGRADE_TO_LUCENE_10_0_0) ); Settings settings = ESTestCase.indexSettings(1, 1) diff --git a/modules/analysis-common/src/test/java/org/elasticsearch/analysis/common/RomanianAnalyzerTests.java b/modules/analysis-common/src/test/java/org/elasticsearch/analysis/common/RomanianAnalyzerTests.java index 1af44bc71f35d..29e27e62e3164 100644 --- a/modules/analysis-common/src/test/java/org/elasticsearch/analysis/common/RomanianAnalyzerTests.java +++ b/modules/analysis-common/src/test/java/org/elasticsearch/analysis/common/RomanianAnalyzerTests.java @@ -57,7 +57,7 @@ public void testRomanianAnalyzerPostLucene10() throws IOException { public void testRomanianAnalyzerPreLucene10() throws IOException { IndexVersion preLucene10Version = IndexVersionUtils.randomVersionBetween( random(), - IndexVersionUtils.getFirstVersion(), + IndexVersionUtils.getLowestReadCompatibleVersion(), IndexVersionUtils.getPreviousVersion(IndexVersions.UPGRADE_TO_LUCENE_10_0_0) ); Settings settings = ESTestCase.indexSettings(1, 1) diff --git a/modules/analysis-common/src/test/java/org/elasticsearch/analysis/common/StemmerTokenFilterFactoryTests.java b/modules/analysis-common/src/test/java/org/elasticsearch/analysis/common/StemmerTokenFilterFactoryTests.java index bb06c221873b5..4e774d92e3d62 100644 --- a/modules/analysis-common/src/test/java/org/elasticsearch/analysis/common/StemmerTokenFilterFactoryTests.java +++ b/modules/analysis-common/src/test/java/org/elasticsearch/analysis/common/StemmerTokenFilterFactoryTests.java @@ -39,7 +39,7 @@ public class StemmerTokenFilterFactoryTests extends ESTokenStreamTestCase { public void testEnglishFilterFactory() throws IOException { int iters = scaledRandomIntBetween(20, 100); for (int i = 0; i < iters; i++) { - IndexVersion v = IndexVersionUtils.randomVersion(random()); + IndexVersion v = IndexVersionUtils.randomVersion(); Settings settings = Settings.builder() .put("index.analysis.filter.my_english.type", "stemmer") .put("index.analysis.filter.my_english.language", "english") @@ -66,7 +66,7 @@ public void testPorter2FilterFactory() throws IOException { int iters = scaledRandomIntBetween(20, 100); for (int i = 0; i < iters; i++) { - IndexVersion v = IndexVersionUtils.randomVersion(random()); + IndexVersion v = IndexVersionUtils.randomVersion(); Settings settings = Settings.builder() .put("index.analysis.filter.my_porter2.type", "stemmer") .put("index.analysis.filter.my_porter2.language", "porter2") @@ -90,7 +90,7 @@ public void testPorter2FilterFactory() throws IOException { } public void testMultipleLanguagesThrowsException() throws IOException { - IndexVersion v = IndexVersionUtils.randomVersion(random()); + IndexVersion v = IndexVersionUtils.randomVersion(); Settings settings = Settings.builder() .put("index.analysis.filter.my_english.type", "stemmer") .putList("index.analysis.filter.my_english.language", "english", "light_english") @@ -142,7 +142,7 @@ private static Analyzer createGermanStemmer(String variant, IndexVersion v) thro } public void testKpDeprecation() throws IOException { - IndexVersion v = IndexVersionUtils.randomVersion(random()); + IndexVersion v = IndexVersionUtils.randomVersion(); Settings settings = Settings.builder() .put("index.analysis.filter.my_kp.type", "stemmer") .put("index.analysis.filter.my_kp.language", "kp") @@ -155,7 +155,7 @@ public void testKpDeprecation() throws IOException { } public void testLovinsDeprecation() throws IOException { - IndexVersion v = IndexVersionUtils.randomVersion(random()); + IndexVersion v = IndexVersionUtils.randomVersion(); Settings settings = Settings.builder() .put("index.analysis.filter.my_lovins.type", "stemmer") .put("index.analysis.filter.my_lovins.language", "lovins") diff --git a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/create/ShrinkIndexIT.java b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/create/ShrinkIndexIT.java index 4f6d24b419595..ca9fdb27ac389 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/create/ShrinkIndexIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/create/ShrinkIndexIT.java @@ -236,7 +236,7 @@ private static IndexMetadata indexMetadata(final Client client, final String ind public void testCreateShrinkIndex() { internalCluster().ensureAtLeastNumDataNodes(2); - IndexVersion version = IndexVersionUtils.randomVersion(random()); + IndexVersion version = IndexVersionUtils.randomWriteVersion(); prepareCreate("source").setSettings( Settings.builder().put(indexSettings()).put("number_of_shards", randomIntBetween(2, 7)).put("index.version.created", version) ).get(); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/cluster/ClusterStateDiffIT.java b/server/src/internalClusterTest/java/org/elasticsearch/cluster/ClusterStateDiffIT.java index 58b9af7724aaa..e8e4eb7562462 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/cluster/ClusterStateDiffIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/cluster/ClusterStateDiffIT.java @@ -71,6 +71,7 @@ import static org.elasticsearch.test.XContentTestUtils.convertToMap; import static org.elasticsearch.test.XContentTestUtils.differenceBetweenMapsIgnoringArrayOrder; import static org.elasticsearch.test.index.IndexVersionUtils.randomVersion; +import static org.elasticsearch.test.index.IndexVersionUtils.randomWriteVersion; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; @@ -218,7 +219,7 @@ private ClusterState.Builder randomCoordinationMetadata(ClusterState clusterStat private DiscoveryNode randomNode(String nodeId) { Version nodeVersion = VersionUtils.randomVersion(random()); - IndexVersion indexVersion = randomVersion(random()); + IndexVersion indexVersion = randomVersion(); return DiscoveryNodeUtils.builder(nodeId) .roles(emptySet()) .version(nodeVersion, IndexVersion.fromId(indexVersion.id() - 1_000_000), indexVersion) @@ -561,7 +562,7 @@ public IndexMetadata randomCreate(String name) { IndexMetadata.Builder builder = IndexMetadata.builder(name); Settings.Builder settingsBuilder = Settings.builder(); setRandomIndexSettings(random(), settingsBuilder); - settingsBuilder.put(randomSettings(Settings.EMPTY)).put(IndexMetadata.SETTING_VERSION_CREATED, randomVersion(random())); + settingsBuilder.put(randomSettings(Settings.EMPTY)).put(IndexMetadata.SETTING_VERSION_CREATED, randomWriteVersion()); builder.settings(settingsBuilder); builder.numberOfShards(randomIntBetween(1, 10)).numberOfReplicas(randomInt(10)); builder.eventIngestedRange(IndexLongFieldRange.UNKNOWN, TransportVersion.current()); @@ -736,7 +737,7 @@ public ClusterState.Custom randomCreate(String name) { ImmutableOpenMap.of(), null, SnapshotInfoTestUtils.randomUserMetadata(), - randomVersion(random()) + randomVersion() ) ); case 1 -> new RestoreInProgress.Builder().add( diff --git a/server/src/internalClusterTest/java/org/elasticsearch/indices/analysis/PreBuiltAnalyzerIntegrationIT.java b/server/src/internalClusterTest/java/org/elasticsearch/indices/analysis/PreBuiltAnalyzerIntegrationIT.java index 48aef0d348045..891b0319f880d 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/indices/analysis/PreBuiltAnalyzerIntegrationIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/indices/analysis/PreBuiltAnalyzerIntegrationIT.java @@ -47,7 +47,7 @@ public void testThatPreBuiltAnalyzersAreNotClosedOnIndexClose() throws Exception PreBuiltAnalyzers preBuiltAnalyzer = PreBuiltAnalyzers.values()[randomInt]; String name = preBuiltAnalyzer.name().toLowerCase(Locale.ROOT); - IndexVersion randomVersion = IndexVersionUtils.randomVersion(random()); + IndexVersion randomVersion = IndexVersionUtils.randomWriteVersion(); if (loadedAnalyzers.containsKey(preBuiltAnalyzer) == false) { loadedAnalyzers.put(preBuiltAnalyzer, new ArrayList<>()); } diff --git a/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java b/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java index 7d4269550bb88..fa1348c82d71a 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java @@ -2050,7 +2050,7 @@ public void testPostRecoveryMergeDisabledOnOlderIndices() throws Exception { IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersionBetween( random(), - IndexVersionUtils.getFirstVersion(), + IndexVersionUtils.getLowestWriteCompatibleVersion(), IndexVersionUtils.getPreviousVersion(IndexVersions.MERGE_ON_RECOVERY_VERSION) ) ) diff --git a/server/src/main/java/org/elasticsearch/index/IndexVersions.java b/server/src/main/java/org/elasticsearch/index/IndexVersions.java index fd321f6256194..8af10524813cc 100644 --- a/server/src/main/java/org/elasticsearch/index/IndexVersions.java +++ b/server/src/main/java/org/elasticsearch/index/IndexVersions.java @@ -12,7 +12,6 @@ import org.apache.lucene.util.Version; import org.elasticsearch.ReleaseVersions; import org.elasticsearch.core.Assertions; -import org.elasticsearch.core.UpdateForV9; import java.lang.reflect.Field; import java.text.ParseException; @@ -25,6 +24,7 @@ import java.util.TreeMap; import java.util.TreeSet; import java.util.function.IntFunction; +import java.util.stream.Collectors; @SuppressWarnings("deprecation") public class IndexVersions { @@ -58,7 +58,6 @@ private static Version parseUnchecked(String version) { } } - @UpdateForV9(owner = UpdateForV9.Owner.SEARCH_FOUNDATIONS) // remove the index versions with which v9 will not need to interact public static final IndexVersion ZERO = def(0, Version.LATEST); public static final IndexVersion V_7_0_0 = def(7_00_00_99, parseUnchecked("8.0.0")); @@ -244,10 +243,12 @@ static NavigableMap getAllVersionIds(Class cls) { return Collections.unmodifiableNavigableMap(builder); } - @UpdateForV9(owner = UpdateForV9.Owner.CORE_INFRA) - // We can simplify this once we've removed all references to index versions earlier than MINIMUM_COMPATIBLE + static Collection getAllWriteVersions() { + return VERSION_IDS.values().stream().filter(v -> v.onOrAfter(IndexVersions.MINIMUM_COMPATIBLE)).collect(Collectors.toSet()); + } + static Collection getAllVersions() { - return VERSION_IDS.values().stream().filter(v -> v.onOrAfter(MINIMUM_COMPATIBLE)).toList(); + return VERSION_IDS.values(); } static final IntFunction VERSION_LOOKUP = ReleaseVersions.generateVersionsLookup(IndexVersions.class, LATEST_DEFINED.id()); diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/HumanReadableIndexSettingsTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/HumanReadableIndexSettingsTests.java index 476ade8576586..8752e68112bff 100644 --- a/server/src/test/java/org/elasticsearch/cluster/metadata/HumanReadableIndexSettingsTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/metadata/HumanReadableIndexSettingsTests.java @@ -22,7 +22,7 @@ public class HumanReadableIndexSettingsTests extends ESTestCase { public void testHumanReadableSettings() { - IndexVersion versionCreated = randomVersion(random()); + IndexVersion versionCreated = randomVersion(); long created = System.currentTimeMillis(); Settings testSettings = Settings.builder() .put(IndexMetadata.SETTING_VERSION_CREATED, versionCreated) diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataCreateIndexServiceTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataCreateIndexServiceTests.java index c0e397c9fb9c9..d45b2c119d2ae 100644 --- a/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataCreateIndexServiceTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataCreateIndexServiceTests.java @@ -369,11 +369,7 @@ public void testValidateSplitIndex() { } public void testPrepareResizeIndexSettings() { - final List versions = Stream.of(IndexVersionUtils.randomVersion(random()), IndexVersionUtils.randomVersion(random())) - .sorted() - .toList(); - final IndexVersion version = versions.get(0); - final IndexVersion upgraded = versions.get(1); + final IndexVersion version = IndexVersionUtils.randomWriteVersion(); final Settings.Builder indexSettingsBuilder = Settings.builder() .put("index.version.created", version) .put("index.similarity.default.type", "BM25") diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataDeleteIndexServiceTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataDeleteIndexServiceTests.java index 0354b6f0bcea8..3ada92dbe7ae5 100644 --- a/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataDeleteIndexServiceTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataDeleteIndexServiceTests.java @@ -97,7 +97,7 @@ public void testDeleteSnapshotting() { Map.of(), null, SnapshotInfoTestUtils.randomUserMetadata(), - IndexVersionUtils.randomVersion(random()) + IndexVersionUtils.randomVersion() ) ); ClusterState state = ClusterState.builder(clusterState(index)).putCustom(SnapshotsInProgress.TYPE, snaps).build(); @@ -153,7 +153,7 @@ public void testDeleteIndexWithAnAlias() { String alias = randomAlphaOfLength(5); IndexMetadata idxMetadata = IndexMetadata.builder(index) - .settings(Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion(random()))) + .settings(Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion())) .putAlias(AliasMetadata.builder(alias).writeIndex(true).build()) .numberOfShards(1) .numberOfReplicas(1) @@ -348,7 +348,7 @@ public void testDeleteCurrentWriteFailureIndexForDataStream() { private ClusterState clusterState(String index) { IndexMetadata indexMetadata = IndexMetadata.builder(index) - .settings(Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion(random()))) + .settings(Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion())) .numberOfShards(1) .numberOfReplicas(1) .build(); diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexAliasesServiceTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexAliasesServiceTests.java index 4f2c84d76b5a4..22ddb5cc2ba35 100644 --- a/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexAliasesServiceTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexAliasesServiceTests.java @@ -744,7 +744,7 @@ private ClusterState applyHiddenAliasMix(ClusterState before, Boolean isHidden1, private ClusterState createIndex(ClusterState state, String index) { IndexMetadata indexMetadata = IndexMetadata.builder(index) - .settings(Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion(random()))) + .settings(Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomWriteVersion())) .numberOfShards(1) .numberOfReplicas(1) .build(); diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexStateServiceTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexStateServiceTests.java index db5a98a4878ca..bd11e636d51c1 100644 --- a/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexStateServiceTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/metadata/MetadataIndexStateServiceTests.java @@ -377,7 +377,7 @@ private static ClusterState addSnapshotIndex(final String index, final int numSh shardsBuilder, null, SnapshotInfoTestUtils.randomUserMetadata(), - IndexVersionUtils.randomVersion(random()) + IndexVersionUtils.randomVersion() ); return ClusterState.builder(newState).putCustom(SnapshotsInProgress.TYPE, SnapshotsInProgress.EMPTY.withAddedEntry(entry)).build(); } diff --git a/server/src/test/java/org/elasticsearch/env/NodeMetadataTests.java b/server/src/test/java/org/elasticsearch/env/NodeMetadataTests.java index 22308e15f4845..eccdd1c6ffea7 100644 --- a/server/src/test/java/org/elasticsearch/env/NodeMetadataTests.java +++ b/server/src/test/java/org/elasticsearch/env/NodeMetadataTests.java @@ -43,7 +43,7 @@ private BuildVersion randomBuildVersion() { } private IndexVersion randomIndexVersion() { - return rarely() ? IndexVersion.fromId(randomInt()) : IndexVersionUtils.randomVersion(random()); + return rarely() ? IndexVersion.fromId(randomInt()) : IndexVersionUtils.randomVersion(); } public void testEqualsHashcodeSerialization() { diff --git a/server/src/test/java/org/elasticsearch/index/IndexVersionTests.java b/server/src/test/java/org/elasticsearch/index/IndexVersionTests.java index 2a425c9256c31..8575b87c36799 100644 --- a/server/src/test/java/org/elasticsearch/index/IndexVersionTests.java +++ b/server/src/test/java/org/elasticsearch/index/IndexVersionTests.java @@ -11,7 +11,6 @@ import org.apache.lucene.util.Version; import org.elasticsearch.common.lucene.Lucene; -import org.elasticsearch.core.UpdateForV9; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.index.IndexVersionUtils; import org.hamcrest.Matchers; @@ -151,9 +150,7 @@ public void testMax() { } } - @UpdateForV9(owner = UpdateForV9.Owner.CORE_INFRA) - @AwaitsFix(bugUrl = "believe this fails because index version has not yet been bumped to 9.0") - public void testMinimumCompatibleVersion() { + public void testGetMinimumCompatibleIndexVersion() { assertThat(IndexVersion.getMinimumCompatibleIndexVersion(7170099), equalTo(IndexVersion.fromId(6000099))); assertThat(IndexVersion.getMinimumCompatibleIndexVersion(8000099), equalTo(IndexVersion.fromId(7000099))); assertThat(IndexVersion.getMinimumCompatibleIndexVersion(10000000), equalTo(IndexVersion.fromId(9000000))); @@ -193,8 +190,6 @@ public void testParseLenient() { } } - @UpdateForV9(owner = UpdateForV9.Owner.CORE_INFRA) - @AwaitsFix(bugUrl = "can be unmuted once lucene is bumped to version 10") public void testLuceneVersionOnUnknownVersions() { // between two known versions, should use the lucene version of the previous version IndexVersion previousVersion = IndexVersionUtils.getPreviousVersion(); @@ -207,7 +202,7 @@ public void testLuceneVersionOnUnknownVersions() { // too old version, major should be the oldest supported lucene version minus 1 IndexVersion oldVersion = IndexVersion.fromId(5020199); - assertThat(oldVersion.luceneVersion().major, equalTo(IndexVersionUtils.getFirstVersion().luceneVersion().major - 1)); + assertThat(oldVersion.luceneVersion().major, equalTo(IndexVersionUtils.getLowestReadCompatibleVersion().luceneVersion().major - 1)); // future version, should be the same version as today IndexVersion futureVersion = IndexVersion.fromId(currentVersion.id() + 100); diff --git a/server/src/test/java/org/elasticsearch/index/analysis/AnalysisRegistryTests.java b/server/src/test/java/org/elasticsearch/index/analysis/AnalysisRegistryTests.java index 04170030c1173..db780f0640986 100644 --- a/server/src/test/java/org/elasticsearch/index/analysis/AnalysisRegistryTests.java +++ b/server/src/test/java/org/elasticsearch/index/analysis/AnalysisRegistryTests.java @@ -106,7 +106,7 @@ public void setUp() throws Exception { } public void testDefaultAnalyzers() throws IOException { - IndexVersion version = IndexVersionUtils.randomVersion(random()); + IndexVersion version = IndexVersionUtils.randomVersion(); Settings settings = Settings.builder() .put(IndexMetadata.SETTING_VERSION_CREATED, version) .put(Environment.PATH_HOME_SETTING.getKey(), createTempDir().toString()) @@ -120,7 +120,7 @@ public void testDefaultAnalyzers() throws IOException { } public void testOverrideDefaultAnalyzer() throws IOException { - IndexVersion version = IndexVersionUtils.randomVersion(random()); + IndexVersion version = IndexVersionUtils.randomVersion(); Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version).build(); IndexAnalyzers indexAnalyzers = AnalysisRegistry.build( IndexCreationContext.CREATE_INDEX, @@ -137,7 +137,7 @@ public void testOverrideDefaultAnalyzer() throws IOException { } public void testOverrideDefaultAnalyzerWithoutAnalysisModeAll() throws IOException { - IndexVersion version = IndexVersionUtils.randomVersion(random()); + IndexVersion version = IndexVersionUtils.randomVersion(); Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version).build(); IndexSettings indexSettings = IndexSettingsModule.newIndexSettings("index", settings); TokenFilterFactory tokenFilter = new AbstractTokenFilterFactory("my_filter") { @@ -216,7 +216,7 @@ public void testOverrideDefaultIndexAnalyzerIsUnsupported() { } public void testOverrideDefaultSearchAnalyzer() { - IndexVersion version = IndexVersionUtils.randomVersion(random()); + IndexVersion version = IndexVersionUtils.randomVersion(); Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version).build(); IndexAnalyzers indexAnalyzers = AnalysisRegistry.build( IndexCreationContext.CREATE_INDEX, @@ -319,8 +319,8 @@ public void testBuiltInAnalyzersAreCached() throws IOException { } } - public void testNoTypeOrTokenizerErrorMessage() throws IOException { - IndexVersion version = IndexVersionUtils.randomVersion(random()); + public void testNoTypeOrTokenizerErrorMessage() { + IndexVersion version = IndexVersionUtils.randomVersion(); Settings settings = Settings.builder() .put(IndexMetadata.SETTING_VERSION_CREATED, version) .put(Environment.PATH_HOME_SETTING.getKey(), createTempDir().toString()) diff --git a/server/src/test/java/org/elasticsearch/index/analysis/PreBuiltAnalyzerTests.java b/server/src/test/java/org/elasticsearch/index/analysis/PreBuiltAnalyzerTests.java index 0a7bd495f2f22..f5b86f422915e 100644 --- a/server/src/test/java/org/elasticsearch/index/analysis/PreBuiltAnalyzerTests.java +++ b/server/src/test/java/org/elasticsearch/index/analysis/PreBuiltAnalyzerTests.java @@ -63,7 +63,7 @@ public void testThatInstancesAreCachedAndReused() { PreBuiltAnalyzers.STANDARD.getAnalyzer(IndexVersion.current()) ); // same index version should be cached - IndexVersion v = IndexVersionUtils.randomVersion(random()); + IndexVersion v = IndexVersionUtils.randomVersion(); assertSame(PreBuiltAnalyzers.STANDARD.getAnalyzer(v), PreBuiltAnalyzers.STANDARD.getAnalyzer(v)); assertNotSame( PreBuiltAnalyzers.STANDARD.getAnalyzer(IndexVersion.current()), @@ -71,7 +71,7 @@ public void testThatInstancesAreCachedAndReused() { ); // Same Lucene version should be cached: - IndexVersion v1 = IndexVersionUtils.randomVersion(random()); + IndexVersion v1 = IndexVersionUtils.randomVersion(); IndexVersion v2 = new IndexVersion(v1.id() - 1, v1.luceneVersion()); assertSame(PreBuiltAnalyzers.STOP.getAnalyzer(v1), PreBuiltAnalyzers.STOP.getAnalyzer(v2)); } @@ -81,7 +81,7 @@ public void testThatAnalyzersAreUsedInMapping() throws IOException { PreBuiltAnalyzers randomPreBuiltAnalyzer = PreBuiltAnalyzers.values()[randomInt]; String analyzerName = randomPreBuiltAnalyzer.name().toLowerCase(Locale.ROOT); - IndexVersion randomVersion = IndexVersionUtils.randomVersion(random()); + IndexVersion randomVersion = IndexVersionUtils.randomWriteVersion(); Settings indexSettings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, randomVersion).build(); NamedAnalyzer namedAnalyzer = new PreBuiltAnalyzerProvider( diff --git a/server/src/test/java/org/elasticsearch/index/analysis/PreConfiguredTokenFilterTests.java b/server/src/test/java/org/elasticsearch/index/analysis/PreConfiguredTokenFilterTests.java index 40b37452990c7..a1a91ef2373f3 100644 --- a/server/src/test/java/org/elasticsearch/index/analysis/PreConfiguredTokenFilterTests.java +++ b/server/src/test/java/org/elasticsearch/index/analysis/PreConfiguredTokenFilterTests.java @@ -41,7 +41,7 @@ public boolean incrementToken() { IndexSettings indexSettings = IndexSettingsModule.newIndexSettings("test", Settings.EMPTY); - IndexVersion version1 = IndexVersionUtils.randomVersion(random()); + IndexVersion version1 = IndexVersionUtils.randomVersion(); Settings settings1 = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version1).build(); TokenFilterFactory tff_v1_1 = pctf.get(indexSettings, TestEnvironment.newEnvironment(emptyNodeSettings), "singleton", settings1); TokenFilterFactory tff_v1_2 = pctf.get(indexSettings, TestEnvironment.newEnvironment(emptyNodeSettings), "singleton", settings1); @@ -66,7 +66,7 @@ public boolean incrementToken() { } ); - IndexVersion version1 = IndexVersionUtils.randomVersion(random()); + IndexVersion version1 = IndexVersionUtils.randomVersion(); IndexSettings indexSettings1 = IndexSettingsModule.newIndexSettings( "test", Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version1).build() @@ -133,7 +133,7 @@ public boolean incrementToken() { ); assertSame(tff_v1_1, tff_v1_2); - IndexVersion version2 = IndexVersionUtils.getPreviousMajorVersion(IndexVersionUtils.getFirstVersion()); + IndexVersion version2 = IndexVersionUtils.getPreviousMajorVersion(IndexVersionUtils.getLowestReadCompatibleVersion()); IndexSettings indexSettings2 = IndexSettingsModule.newIndexSettings( "test", Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version2).build() diff --git a/server/src/test/java/org/elasticsearch/index/engine/InternalEngineTests.java b/server/src/test/java/org/elasticsearch/index/engine/InternalEngineTests.java index 3e3be6a315af2..d07c775da7e2a 100644 --- a/server/src/test/java/org/elasticsearch/index/engine/InternalEngineTests.java +++ b/server/src/test/java/org/elasticsearch/index/engine/InternalEngineTests.java @@ -6645,7 +6645,7 @@ public void testStoreHonorsLuceneVersion() throws IOException { for (IndexVersion createdVersion : List.of( IndexVersion.current(), lowestCompatiblePreviousVersion, - IndexVersionUtils.getFirstVersion() + IndexVersionUtils.getLowestWriteCompatibleVersion() )) { Settings settings = Settings.builder().put(indexSettings()).put(IndexMetadata.SETTING_VERSION_CREATED, createdVersion).build(); IndexSettings indexSettings = IndexSettingsModule.newIndexSettings("test", settings); diff --git a/server/src/test/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapperTests.java b/server/src/test/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapperTests.java index 342d61b78defd..3f574a29469c2 100644 --- a/server/src/test/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapperTests.java +++ b/server/src/test/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapperTests.java @@ -1514,19 +1514,19 @@ public void testVectorSimilarity() { ); assertEquals( VectorSimilarityFunction.EUCLIDEAN, - VectorSimilarity.L2_NORM.vectorSimilarityFunction(IndexVersionUtils.randomVersion(random()), ElementType.BYTE) + VectorSimilarity.L2_NORM.vectorSimilarityFunction(IndexVersionUtils.randomVersion(), ElementType.BYTE) ); assertEquals( VectorSimilarityFunction.EUCLIDEAN, - VectorSimilarity.L2_NORM.vectorSimilarityFunction(IndexVersionUtils.randomVersion(random()), ElementType.FLOAT) + VectorSimilarity.L2_NORM.vectorSimilarityFunction(IndexVersionUtils.randomVersion(), ElementType.FLOAT) ); assertEquals( VectorSimilarityFunction.DOT_PRODUCT, - VectorSimilarity.DOT_PRODUCT.vectorSimilarityFunction(IndexVersionUtils.randomVersion(random()), ElementType.BYTE) + VectorSimilarity.DOT_PRODUCT.vectorSimilarityFunction(IndexVersionUtils.randomVersion(), ElementType.BYTE) ); assertEquals( VectorSimilarityFunction.DOT_PRODUCT, - VectorSimilarity.DOT_PRODUCT.vectorSimilarityFunction(IndexVersionUtils.randomVersion(random()), ElementType.FLOAT) + VectorSimilarity.DOT_PRODUCT.vectorSimilarityFunction(IndexVersionUtils.randomVersion(), ElementType.FLOAT) ); } diff --git a/server/src/test/java/org/elasticsearch/indices/analysis/AnalysisModuleTests.java b/server/src/test/java/org/elasticsearch/indices/analysis/AnalysisModuleTests.java index cf6941b84b791..1bcd84aadd6cd 100644 --- a/server/src/test/java/org/elasticsearch/indices/analysis/AnalysisModuleTests.java +++ b/server/src/test/java/org/elasticsearch/indices/analysis/AnalysisModuleTests.java @@ -233,7 +233,7 @@ public Map> getTokenizers() { new StablePluginsRegistry() ).getAnalysisRegistry(); - IndexVersion version = IndexVersionUtils.randomVersion(random()); + IndexVersion version = IndexVersionUtils.randomVersion(); IndexAnalyzers analyzers = getIndexAnalyzers( registry, Settings.builder() @@ -302,7 +302,7 @@ public List getPreConfiguredTokenFilters() { new StablePluginsRegistry() ).getAnalysisRegistry(); - IndexVersion version = IndexVersionUtils.randomVersion(random()); + IndexVersion version = IndexVersionUtils.randomVersion(); IndexAnalyzers analyzers = getIndexAnalyzers( registry, Settings.builder() @@ -389,7 +389,7 @@ public List getPreConfiguredTokenizers() { new StablePluginsRegistry() ).getAnalysisRegistry(); - IndexVersion version = IndexVersionUtils.randomVersion(random()); + IndexVersion version = IndexVersionUtils.randomVersion(); IndexAnalyzers analyzers = getIndexAnalyzers( registry, Settings.builder() diff --git a/server/src/test/java/org/elasticsearch/indices/analysis/IncorrectSetupStablePluginsTests.java b/server/src/test/java/org/elasticsearch/indices/analysis/IncorrectSetupStablePluginsTests.java index ca9184bca75da..181d3ec44f2b3 100644 --- a/server/src/test/java/org/elasticsearch/indices/analysis/IncorrectSetupStablePluginsTests.java +++ b/server/src/test/java/org/elasticsearch/indices/analysis/IncorrectSetupStablePluginsTests.java @@ -63,7 +63,7 @@ public void testIncorrectlyAnnotatedSettingsClass() throws IOException { Settings.builder() .put("index.analysis.analyzer.char_filter_test.tokenizer", "standard") .put("index.analysis.analyzer.char_filter_test.char_filter", "incorrectlyAnnotatedSettings") - .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion(random())) + .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion()) .build(), Map.of( "incorrectlyAnnotatedSettings", @@ -90,7 +90,7 @@ public void testIncorrectlyAnnotatedConstructor() throws IOException { Settings.builder() .put("index.analysis.analyzer.char_filter_test.tokenizer", "standard") .put("index.analysis.analyzer.char_filter_test.char_filter", "noInjectCharFilter") - .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion(random())) + .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion()) .build(), Map.of("noInjectCharFilter", new PluginInfo("noInjectCharFilter", NoInjectCharFilter.class.getName(), classLoader)) ) @@ -112,7 +112,7 @@ public void testMultiplePublicConstructors() throws IOException { Settings.builder() .put("index.analysis.analyzer.char_filter_test.tokenizer", "standard") .put("index.analysis.analyzer.char_filter_test.char_filter", "multipleConstructors") - .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion(random())) + .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion()) .build(), Map.of("multipleConstructors", new PluginInfo("multipleConstructors", MultipleConstructors.class.getName(), classLoader)) ) diff --git a/server/src/test/java/org/elasticsearch/indices/analysis/StableAnalysisPluginsNoSettingsTests.java b/server/src/test/java/org/elasticsearch/indices/analysis/StableAnalysisPluginsNoSettingsTests.java index 7cbda0e7086cb..6eac3847efa43 100644 --- a/server/src/test/java/org/elasticsearch/indices/analysis/StableAnalysisPluginsNoSettingsTests.java +++ b/server/src/test/java/org/elasticsearch/indices/analysis/StableAnalysisPluginsNoSettingsTests.java @@ -61,7 +61,7 @@ public IndexAnalyzers getIndexAnalyzers(Settings settings) throws IOException { } public void testStablePlugins() throws IOException { - IndexVersion version = IndexVersionUtils.randomVersion(random()); + IndexVersion version = IndexVersionUtils.randomVersion(); IndexAnalyzers analyzers = getIndexAnalyzers( Settings.builder() .put("index.analysis.analyzer.char_filter_test.tokenizer", "standard") diff --git a/server/src/test/java/org/elasticsearch/indices/analysis/StableAnalysisPluginsWithSettingsTests.java b/server/src/test/java/org/elasticsearch/indices/analysis/StableAnalysisPluginsWithSettingsTests.java index acde315b140ab..82f49888e911d 100644 --- a/server/src/test/java/org/elasticsearch/indices/analysis/StableAnalysisPluginsWithSettingsTests.java +++ b/server/src/test/java/org/elasticsearch/indices/analysis/StableAnalysisPluginsWithSettingsTests.java @@ -72,7 +72,7 @@ public void testCharFilters() throws IOException { .put("index.analysis.analyzer.char_filter_with_defaults_test.tokenizer", "standard") .put("index.analysis.analyzer.char_filter_with_defaults_test.char_filter", "stableCharFilterFactory") - .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion(random())) + .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion()) .build() ); assertTokenStreamContents(analyzers.get("char_filter_test").tokenStream("", "t#st"), new String[] { "t3st" }); @@ -88,7 +88,7 @@ public void testTokenFilters() throws IOException { .put("index.analysis.analyzer.token_filter_test.tokenizer", "standard") .put("index.analysis.analyzer.token_filter_test.filter", "my_token_filter") - .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion(random())) + .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion()) .build() ); assertTokenStreamContents( @@ -109,7 +109,7 @@ public void testTokenizer() throws IOException { .putList("index.analysis.tokenizer.my_tokenizer.tokenizer_list_of_chars", "_", " ") .put("index.analysis.analyzer.tokenizer_test.tokenizer", "my_tokenizer") - .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion(random())) + .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion()) .build() ); assertTokenStreamContents(analyzers.get("tokenizer_test").tokenStream("", "x_y z"), new String[] { "x", "y", "z" }); @@ -124,7 +124,7 @@ public void testAnalyzer() throws IOException { .put("index.analysis.analyzer.analyzer_provider_test.old_char", "#") .put("index.analysis.analyzer.analyzer_provider_test.new_number", 3) .put("index.analysis.analyzer.analyzer_provider_test.analyzerUseTokenListOfChars", true) - .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion(random())) + .put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion()) .build() ); assertTokenStreamContents(analyzers.get("analyzer_provider_test").tokenStream("", "1x_y_#z"), new String[] { "y", "3z" }); diff --git a/server/src/test/java/org/elasticsearch/indices/recovery/RecoverySourceHandlerTests.java b/server/src/test/java/org/elasticsearch/indices/recovery/RecoverySourceHandlerTests.java index d039c265c98ae..d9b2936dc30c0 100644 --- a/server/src/test/java/org/elasticsearch/indices/recovery/RecoverySourceHandlerTests.java +++ b/server/src/test/java/org/elasticsearch/indices/recovery/RecoverySourceHandlerTests.java @@ -721,7 +721,7 @@ public void testThrowExceptionOnPrimaryRelocatedBeforePhase1Started() throws IOE final IndexMetadata.Builder indexMetadata = IndexMetadata.builder("test") .settings( - indexSettings(IndexVersionUtils.randomVersion(random()), between(1, 5), between(0, 5)).put( + indexSettings(IndexVersionUtils.randomVersion(), between(1, 5), between(0, 5)).put( IndexMetadata.SETTING_INDEX_UUID, UUIDs.randomBase64UUID(random()) ) diff --git a/server/src/test/java/org/elasticsearch/nodesinfo/NodeInfoStreamingTests.java b/server/src/test/java/org/elasticsearch/nodesinfo/NodeInfoStreamingTests.java index 33801dfb98417..ace8499d8ffd0 100644 --- a/server/src/test/java/org/elasticsearch/nodesinfo/NodeInfoStreamingTests.java +++ b/server/src/test/java/org/elasticsearch/nodesinfo/NodeInfoStreamingTests.java @@ -243,7 +243,7 @@ private static NodeInfo createNodeInfo() { return new NodeInfo( randomAlphaOfLengthBetween(6, 32), new CompatibilityVersions(TransportVersionUtils.randomVersion(random()), Map.of()), - IndexVersionUtils.randomVersion(random()), + IndexVersionUtils.randomVersion(), componentVersions, build, node, diff --git a/server/src/test/java/org/elasticsearch/persistent/PersistentTasksClusterServiceTests.java b/server/src/test/java/org/elasticsearch/persistent/PersistentTasksClusterServiceTests.java index c568f6a38a5fb..cd2327d90c5c5 100644 --- a/server/src/test/java/org/elasticsearch/persistent/PersistentTasksClusterServiceTests.java +++ b/server/src/test/java/org/elasticsearch/persistent/PersistentTasksClusterServiceTests.java @@ -966,7 +966,7 @@ private ClusterState insignificantChange(ClusterState clusterState) { } // Just add a random index - that shouldn't change anything IndexMetadata indexMetadata = IndexMetadata.builder(randomAlphaOfLength(10)) - .settings(Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion(random()))) + .settings(Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion())) .numberOfShards(1) .numberOfReplicas(1) .build(); @@ -1044,7 +1044,7 @@ private ClusterState initialState() { private void changeRoutingTable(Metadata.Builder metadata, RoutingTable.Builder routingTable) { IndexMetadata indexMetadata = IndexMetadata.builder(randomAlphaOfLength(10)) - .settings(Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion(random()))) + .settings(Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion())) .numberOfShards(1) .numberOfReplicas(1) .build(); diff --git a/server/src/test/java/org/elasticsearch/snapshots/SnapshotsInProgressSerializationTests.java b/server/src/test/java/org/elasticsearch/snapshots/SnapshotsInProgressSerializationTests.java index a92d55f6d419c..91ab253b2e1fe 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SnapshotsInProgressSerializationTests.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SnapshotsInProgressSerializationTests.java @@ -133,7 +133,7 @@ private Entry randomSnapshot() { shards, null, SnapshotInfoTestUtils.randomUserMetadata(), - IndexVersionUtils.randomVersion(random()) + IndexVersionUtils.randomVersion() ); } diff --git a/test/framework/src/main/java/org/elasticsearch/index/KnownIndexVersions.java b/test/framework/src/main/java/org/elasticsearch/index/KnownIndexVersions.java index 47d239540814e..5cdb3f1808a38 100644 --- a/test/framework/src/main/java/org/elasticsearch/index/KnownIndexVersions.java +++ b/test/framework/src/main/java/org/elasticsearch/index/KnownIndexVersions.java @@ -16,7 +16,11 @@ */ public class KnownIndexVersions { /** - * A sorted list of all known transport versions + * A sorted list of all known index versions */ public static final List ALL_VERSIONS = List.copyOf(IndexVersions.getAllVersions()); + /** + * A sorted list of all known index versions that can be written to + */ + public static final List ALL_WRITE_VERSIONS = List.copyOf(IndexVersions.getAllWriteVersions()); } diff --git a/test/framework/src/main/java/org/elasticsearch/test/index/IndexVersionUtils.java b/test/framework/src/main/java/org/elasticsearch/test/index/IndexVersionUtils.java index f83e7e17f9aaa..592cffac33552 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/index/IndexVersionUtils.java +++ b/test/framework/src/main/java/org/elasticsearch/test/index/IndexVersionUtils.java @@ -24,32 +24,38 @@ public class IndexVersionUtils { private static final List ALL_VERSIONS = KnownIndexVersions.ALL_VERSIONS; + private static final List ALL_WRITE_VERSIONS = KnownIndexVersions.ALL_WRITE_VERSIONS; /** Returns all released versions */ public static List allReleasedVersions() { return ALL_VERSIONS; } - /** Returns the oldest known {@link IndexVersion} */ - public static IndexVersion getFirstVersion() { + /** Returns the oldest known {@link IndexVersion}. This version can only be read from and not written to */ + public static IndexVersion getLowestReadCompatibleVersion() { return ALL_VERSIONS.get(0); } + /** Returns the oldest known {@link IndexVersion} that can be written to */ + public static IndexVersion getLowestWriteCompatibleVersion() { + return ALL_WRITE_VERSIONS.get(0); + } + /** Returns a random {@link IndexVersion} from all available versions. */ public static IndexVersion randomVersion() { return ESTestCase.randomFrom(ALL_VERSIONS); } + /** Returns a random {@link IndexVersion} from all versions that can be written to. */ + public static IndexVersion randomWriteVersion() { + return ESTestCase.randomFrom(ALL_WRITE_VERSIONS); + } + /** Returns a random {@link IndexVersion} from all available versions without the ignore set */ public static IndexVersion randomVersion(Set ignore) { return ESTestCase.randomFrom(ALL_VERSIONS.stream().filter(v -> ignore.contains(v) == false).collect(Collectors.toList())); } - /** Returns a random {@link IndexVersion} from all available versions. */ - public static IndexVersion randomVersion(Random random) { - return ALL_VERSIONS.get(random.nextInt(ALL_VERSIONS.size())); - } - /** Returns a random {@link IndexVersion} between minVersion and maxVersion (inclusive). */ public static IndexVersion randomVersionBetween(Random random, @Nullable IndexVersion minVersion, @Nullable IndexVersion maxVersion) { if (minVersion != null && maxVersion != null && maxVersion.before(minVersion)) { diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/DeprecationRoleDescriptorConsumerTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/DeprecationRoleDescriptorConsumerTests.java index ee91b8b65e540..c572b3a35d5a4 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/DeprecationRoleDescriptorConsumerTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/DeprecationRoleDescriptorConsumerTests.java @@ -342,7 +342,7 @@ public void testMultipleIndicesSameAlias() throws Exception { private void addIndex(Metadata.Builder metadataBuilder, String index, String... aliases) { final IndexMetadata.Builder indexMetadataBuilder = IndexMetadata.builder(index) - .settings(Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion(random()))) + .settings(Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersionUtils.randomVersion())) .numberOfShards(1) .numberOfReplicas(1); for (final String alias : aliases) { From 54fa07450a6aeddf5cfc4c210cfe9241cb8e83c0 Mon Sep 17 00:00:00 2001 From: Liam Thompson <32779855+leemthompo@users.noreply.github.com> Date: Wed, 18 Dec 2024 13:54:17 +0100 Subject: [PATCH 40/60] [DOCS] Make Wolfi hardened Docker option more prominent (#118755) --- docs/reference/setup/install/docker.asciidoc | 21 ++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/docs/reference/setup/install/docker.asciidoc b/docs/reference/setup/install/docker.asciidoc index 86a0e567f6eec..f3576db0c786c 100644 --- a/docs/reference/setup/install/docker.asciidoc +++ b/docs/reference/setup/install/docker.asciidoc @@ -25,6 +25,21 @@ TIP: This setup doesn't run multiple {es} nodes or {kib} by default. To create a multi-node cluster with {kib}, use Docker Compose instead. See <>. +[[docker-wolfi-hardened-image]] +===== Hardened Docker images + +You can also use the hardened https://wolfi.dev/[Wolfi] image for additional security. +Using Wolfi images requires Docker version 20.10.10 or higher. + +To use the Wolfi image, append `-wolfi` to the image tag in the Docker command. + +For example: + +[source,sh,subs="attributes"] +---- +docker pull {docker-wolfi-image} +---- + ===== Start a single-node cluster . Install Docker. Visit https://docs.docker.com/get-docker/[Get Docker] to @@ -55,12 +70,6 @@ docker pull {docker-image} // REVIEWED[DEC.10.24] -- -Alternatevely, you can use the Wolfi based image. Using Wolfi based images requires Docker version 20.10.10 or superior. -[source,sh,subs="attributes"] ----- -docker pull {docker-wolfi-image} ----- - . Optional: Install https://docs.sigstore.dev/cosign/system_config/installation/[Cosign] for your environment. Then use Cosign to verify the {es} image's signature. From dbbcb09244cd65b52c13f78e500deb5fdcd3edd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Cea=20Fontenla?= Date: Wed, 18 Dec 2024 14:19:38 +0100 Subject: [PATCH 41/60] ESQL: Verify LOOKUP JOIN index has lookup mode (#118660) Verifies that LOOKUP JOIN indices resolve to a single concrete index with LOOKUP mode. --- .../esql/qa/mixed/MixedClusterEsqlSpecIT.java | 4 +- .../xpack/esql/ccq/MultiClusterSpecIT.java | 8 +- .../rest/RequestIndexFilteringTestCase.java | 2 +- .../src/main/resources/lookup-join.csv-spec | 128 +++++++++--------- .../xpack/esql/action/EsqlCapabilities.java | 4 +- .../xpack/esql/analysis/Analyzer.java | 31 +++++ .../xpack/esql/analysis/Verifier.java | 1 - .../elasticsearch/xpack/esql/CsvTests.java | 2 +- .../esql/analysis/AnalyzerTestUtils.java | 19 ++- .../xpack/esql/analysis/AnalyzerTests.java | 33 ++++- .../xpack/esql/analysis/ParsingTests.java | 8 +- .../xpack/esql/analysis/VerifierTests.java | 8 +- .../optimizer/LogicalPlanOptimizerTests.java | 12 +- .../optimizer/PhysicalPlanOptimizerTests.java | 2 +- .../session/IndexResolverFieldNamesTests.java | 24 ++-- .../test/esql/190_lookup_join.yml | 78 +++++++++++ 16 files changed, 261 insertions(+), 103 deletions(-) create mode 100644 x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/190_lookup_join.yml diff --git a/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java b/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java index 004beaafb4009..d4b087277df52 100644 --- a/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java +++ b/x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java @@ -21,7 +21,7 @@ import java.util.List; import static org.elasticsearch.xpack.esql.CsvTestUtils.isEnabled; -import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.JOIN_LOOKUP_V7; +import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.JOIN_LOOKUP_V8; import static org.elasticsearch.xpack.esql.qa.rest.EsqlSpecTestCase.Mode.ASYNC; public class MixedClusterEsqlSpecIT extends EsqlSpecTestCase { @@ -96,7 +96,7 @@ protected boolean supportsInferenceTestService() { @Override protected boolean supportsIndexModeLookup() throws IOException { - return hasCapabilities(List.of(JOIN_LOOKUP_V7.capabilityName())); + return hasCapabilities(List.of(JOIN_LOOKUP_V8.capabilityName())); } @Override diff --git a/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClusterSpecIT.java b/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClusterSpecIT.java index c75a920e16973..d7c57e23b7147 100644 --- a/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClusterSpecIT.java +++ b/x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClusterSpecIT.java @@ -48,7 +48,7 @@ import static org.elasticsearch.xpack.esql.EsqlTestUtils.classpathResources; import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.INLINESTATS; import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.INLINESTATS_V2; -import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.JOIN_LOOKUP_V7; +import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.JOIN_LOOKUP_V8; import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.JOIN_PLANNING_V1; import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.METADATA_FIELDS_REMOTE_TEST; import static org.elasticsearch.xpack.esql.qa.rest.EsqlSpecTestCase.Mode.SYNC; @@ -124,7 +124,7 @@ protected void shouldSkipTest(String testName) throws IOException { assumeFalse("INLINESTATS not yet supported in CCS", testCase.requiredCapabilities.contains(INLINESTATS.capabilityName())); assumeFalse("INLINESTATS not yet supported in CCS", testCase.requiredCapabilities.contains(INLINESTATS_V2.capabilityName())); assumeFalse("INLINESTATS not yet supported in CCS", testCase.requiredCapabilities.contains(JOIN_PLANNING_V1.capabilityName())); - assumeFalse("LOOKUP JOIN not yet supported in CCS", testCase.requiredCapabilities.contains(JOIN_LOOKUP_V7.capabilityName())); + assumeFalse("LOOKUP JOIN not yet supported in CCS", testCase.requiredCapabilities.contains(JOIN_LOOKUP_V8.capabilityName())); } private TestFeatureService remoteFeaturesService() throws IOException { @@ -283,8 +283,8 @@ protected boolean supportsInferenceTestService() { @Override protected boolean supportsIndexModeLookup() throws IOException { - // CCS does not yet support JOIN_LOOKUP_V7 and clusters falsely report they have this capability - // return hasCapabilities(List.of(JOIN_LOOKUP_V7.capabilityName())); + // CCS does not yet support JOIN_LOOKUP_V8 and clusters falsely report they have this capability + // return hasCapabilities(List.of(JOIN_LOOKUP_V8.capabilityName())); return false; } } diff --git a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RequestIndexFilteringTestCase.java b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RequestIndexFilteringTestCase.java index 40027249670f6..355c403ce2a86 100644 --- a/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RequestIndexFilteringTestCase.java +++ b/x-pack/plugin/esql/qa/server/src/main/java/org/elasticsearch/xpack/esql/qa/rest/RequestIndexFilteringTestCase.java @@ -221,7 +221,7 @@ public void testIndicesDontExist() throws IOException { assertThat(e.getMessage(), containsString("index_not_found_exception")); assertThat(e.getMessage(), containsString("no such index [foo]")); - if (EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()) { + if (EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()) { e = expectThrows( ResponseException.class, () -> runEsql(timestampFilter("gte", "2020-01-01").query("FROM test1 | LOOKUP JOIN foo ON id1")) diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/lookup-join.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/lookup-join.csv-spec index e75c68f4a379d..7d4f89ed920a9 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/lookup-join.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/lookup-join.csv-spec @@ -8,7 +8,7 @@ ############################################### basicOnTheDataNode -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM employees | EVAL language_code = languages @@ -25,7 +25,7 @@ emp_no:integer | language_code:integer | language_name:keyword ; basicRow -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW language_code = 1 | LOOKUP JOIN languages_lookup ON language_code @@ -36,7 +36,7 @@ language_code:integer | language_name:keyword ; basicOnTheCoordinator -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM employees | SORT emp_no @@ -53,7 +53,7 @@ emp_no:integer | language_code:integer | language_name:keyword ; subsequentEvalOnTheDataNode -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM employees | EVAL language_code = languages @@ -71,7 +71,7 @@ emp_no:integer | language_code:integer | language_name:keyword | language_code_x ; subsequentEvalOnTheCoordinator -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM employees | SORT emp_no @@ -89,7 +89,7 @@ emp_no:integer | language_code:integer | language_name:keyword | language_code_x ; sortEvalBeforeLookup -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM employees | SORT emp_no @@ -106,7 +106,7 @@ emp_no:integer | language_code:integer | language_name:keyword ; nonUniqueLeftKeyOnTheDataNode -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM employees | WHERE emp_no <= 10030 @@ -130,7 +130,7 @@ emp_no:integer | language_code:integer | language_name:keyword ; nonUniqueRightKeyOnTheDataNode -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM employees | EVAL language_code = emp_no % 10 @@ -150,7 +150,7 @@ emp_no:integer | language_code:integer | language_name:keyword | country:k ; nonUniqueRightKeyOnTheCoordinator -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM employees | SORT emp_no @@ -170,7 +170,7 @@ emp_no:integer | language_code:integer | language_name:keyword | country:k ; nonUniqueRightKeyFromRow -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW language_code = 2 | LOOKUP JOIN languages_lookup_non_unique_key ON language_code @@ -183,7 +183,7 @@ language_code:integer | language_name:keyword | country:keyword ; repeatedIndexOnFrom -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 required_capability: join_lookup_repeated_index_from FROM languages_lookup @@ -203,7 +203,7 @@ language_code:integer | language_name:keyword ############################################### filterOnLeftSide -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM employees | EVAL language_code = languages @@ -220,7 +220,7 @@ emp_no:integer | language_code:integer | language_name:keyword ; filterOnRightSide -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | LOOKUP JOIN message_types_lookup ON message @@ -236,7 +236,7 @@ FROM sample_data ; filterOnRightSideAfterStats -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | LOOKUP JOIN message_types_lookup ON message @@ -249,7 +249,7 @@ count:long | type:keyword ; filterOnJoinKey -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM employees | EVAL language_code = languages @@ -264,7 +264,7 @@ emp_no:integer | language_code:integer | language_name:keyword ; filterOnJoinKeyAndRightSide -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM employees | WHERE emp_no < 10006 @@ -281,7 +281,7 @@ emp_no:integer | language_code:integer | language_name:keyword ; filterOnRightSideOnTheCoordinator -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM employees | SORT emp_no @@ -297,7 +297,7 @@ emp_no:integer | language_code:integer | language_name:keyword ; filterOnJoinKeyOnTheCoordinator -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM employees | SORT emp_no @@ -313,7 +313,7 @@ emp_no:integer | language_code:integer | language_name:keyword ; filterOnJoinKeyAndRightSideOnTheCoordinator -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM employees | SORT emp_no @@ -330,7 +330,7 @@ emp_no:integer | language_code:integer | language_name:keyword ; filterOnTheDataNodeThenFilterOnTheCoordinator -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM employees | EVAL language_code = languages @@ -351,7 +351,7 @@ emp_no:integer | language_code:integer | language_name:keyword ########################################################################### nullJoinKeyOnTheDataNode -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM employees | WHERE emp_no < 10004 @@ -368,7 +368,7 @@ emp_no:integer | language_code:integer | language_name:keyword ; mvJoinKeyOnTheDataNode -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM employees | WHERE 10003 < emp_no AND emp_no < 10008 @@ -386,7 +386,7 @@ emp_no:integer | language_code:integer | language_name:keyword ; mvJoinKeyFromRow -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW language_code = [4, 5, 6, 7] | LOOKUP JOIN languages_lookup_non_unique_key ON language_code @@ -399,7 +399,7 @@ language_code:integer | language_name:keyword | country:keyword ; mvJoinKeyFromRowExpanded -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW language_code = [4, 5, 6, 7, 8] | MV_EXPAND language_code @@ -421,7 +421,7 @@ language_code:integer | language_name:keyword | country:keyword ############################################### lookupIPFromRow -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW left = "left", client_ip = "172.21.0.5", right = "right" | LOOKUP JOIN clientips_lookup ON client_ip @@ -432,7 +432,7 @@ left | 172.21.0.5 | right | Development ; lookupIPFromKeepRow -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW left = "left", client_ip = "172.21.0.5", right = "right" | KEEP left, client_ip, right @@ -444,7 +444,7 @@ left | 172.21.0.5 | right | Development ; lookupIPFromRowWithShadowing -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW left = "left", client_ip = "172.21.0.5", env = "env", right = "right" | LOOKUP JOIN clientips_lookup ON client_ip @@ -455,7 +455,7 @@ left | 172.21.0.5 | right | Development ; lookupIPFromRowWithShadowingKeep -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW left = "left", client_ip = "172.21.0.5", env = "env", right = "right" | EVAL client_ip = client_ip::keyword @@ -468,7 +468,7 @@ left | 172.21.0.5 | right | Development ; lookupIPFromRowWithShadowingKeepReordered -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW left = "left", client_ip = "172.21.0.5", env = "env", right = "right" | EVAL client_ip = client_ip::keyword @@ -481,7 +481,7 @@ right | Development | 172.21.0.5 ; lookupIPFromIndex -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | EVAL client_ip = client_ip::keyword @@ -500,7 +500,7 @@ ignoreOrder:true ; lookupIPFromIndexKeep -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | EVAL client_ip = client_ip::keyword @@ -520,7 +520,7 @@ ignoreOrder:true ; lookupIPFromIndexKeepKeep -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | KEEP client_ip, event_duration, @timestamp, message @@ -542,7 +542,7 @@ timestamp:date | client_ip:keyword | event_duration:long | msg:keyword ; lookupIPFromIndexStats -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | EVAL client_ip = client_ip::keyword @@ -558,7 +558,7 @@ count:long | env:keyword ; lookupIPFromIndexStatsKeep -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | EVAL client_ip = client_ip::keyword @@ -575,7 +575,7 @@ count:long | env:keyword ; statsAndLookupIPFromIndex -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | EVAL client_ip = client_ip::keyword @@ -596,7 +596,7 @@ count:long | client_ip:keyword | env:keyword ############################################### lookupMessageFromRow -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW left = "left", message = "Connected to 10.1.0.1", right = "right" | LOOKUP JOIN message_types_lookup ON message @@ -607,7 +607,7 @@ left | Connected to 10.1.0.1 | right | Success ; lookupMessageFromKeepRow -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW left = "left", message = "Connected to 10.1.0.1", right = "right" | KEEP left, message, right @@ -619,7 +619,7 @@ left | Connected to 10.1.0.1 | right | Success ; lookupMessageFromRowWithShadowing -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW left = "left", message = "Connected to 10.1.0.1", type = "unknown", right = "right" | LOOKUP JOIN message_types_lookup ON message @@ -630,7 +630,7 @@ left | Connected to 10.1.0.1 | right | Success ; lookupMessageFromRowWithShadowingKeep -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW left = "left", message = "Connected to 10.1.0.1", type = "unknown", right = "right" | LOOKUP JOIN message_types_lookup ON message @@ -642,7 +642,7 @@ left | Connected to 10.1.0.1 | right | Success ; lookupMessageFromIndex -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | LOOKUP JOIN message_types_lookup ON message @@ -660,7 +660,7 @@ ignoreOrder:true ; lookupMessageFromIndexKeep -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | LOOKUP JOIN message_types_lookup ON message @@ -679,7 +679,7 @@ ignoreOrder:true ; lookupMessageFromIndexKeepKeep -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | KEEP client_ip, event_duration, @timestamp, message @@ -699,7 +699,7 @@ ignoreOrder:true ; lookupMessageFromIndexKeepReordered -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | LOOKUP JOIN message_types_lookup ON message @@ -718,7 +718,7 @@ Success | 172.21.2.162 | 3450233 | Connected to 10.1.0.3 ; lookupMessageFromIndexStats -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | LOOKUP JOIN message_types_lookup ON message @@ -733,7 +733,7 @@ count:long | type:keyword ; lookupMessageFromIndexStatsKeep -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | LOOKUP JOIN message_types_lookup ON message @@ -749,7 +749,7 @@ count:long | type:keyword ; statsAndLookupMessageFromIndex -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | STATS count = count(message) BY message @@ -767,7 +767,7 @@ count:long | type:keyword | message:keyword ; lookupMessageFromIndexTwice -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | LOOKUP JOIN message_types_lookup ON message @@ -789,7 +789,7 @@ ignoreOrder:true ; lookupMessageFromIndexTwiceKeep -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | LOOKUP JOIN message_types_lookup ON message @@ -816,7 +816,7 @@ ignoreOrder:true ############################################### lookupIPAndMessageFromRow -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW left = "left", client_ip = "172.21.0.5", message = "Connected to 10.1.0.1", right = "right" | LOOKUP JOIN clientips_lookup ON client_ip @@ -828,7 +828,7 @@ left | 172.21.0.5 | Connected to 10.1.0.1 | right | Devel ; lookupIPAndMessageFromRowKeepBefore -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW left = "left", client_ip = "172.21.0.5", message = "Connected to 10.1.0.1", right = "right" | KEEP left, client_ip, message, right @@ -841,7 +841,7 @@ left | 172.21.0.5 | Connected to 10.1.0.1 | right | Devel ; lookupIPAndMessageFromRowKeepBetween -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW left = "left", client_ip = "172.21.0.5", message = "Connected to 10.1.0.1", right = "right" | LOOKUP JOIN clientips_lookup ON client_ip @@ -854,7 +854,7 @@ left | 172.21.0.5 | Connected to 10.1.0.1 | right | Devel ; lookupIPAndMessageFromRowKeepAfter -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW left = "left", client_ip = "172.21.0.5", message = "Connected to 10.1.0.1", right = "right" | LOOKUP JOIN clientips_lookup ON client_ip @@ -867,7 +867,7 @@ left | 172.21.0.5 | Connected to 10.1.0.1 | right | Devel ; lookupIPAndMessageFromRowWithShadowing -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW left = "left", client_ip = "172.21.0.5", message = "Connected to 10.1.0.1", env = "env", type = "type", right = "right" | LOOKUP JOIN clientips_lookup ON client_ip @@ -879,7 +879,7 @@ left | 172.21.0.5 | Connected to 10.1.0.1 | right | Devel ; lookupIPAndMessageFromRowWithShadowingKeep -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW left = "left", client_ip = "172.21.0.5", message = "Connected to 10.1.0.1", env = "env", right = "right" | EVAL client_ip = client_ip::keyword @@ -893,7 +893,7 @@ left | 172.21.0.5 | Connected to 10.1.0.1 | right | Devel ; lookupIPAndMessageFromRowWithShadowingKeepKeep -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW left = "left", client_ip = "172.21.0.5", message = "Connected to 10.1.0.1", env = "env", right = "right" | EVAL client_ip = client_ip::keyword @@ -908,7 +908,7 @@ left | 172.21.0.5 | Connected to 10.1.0.1 | right | Devel ; lookupIPAndMessageFromRowWithShadowingKeepKeepKeep -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW left = "left", client_ip = "172.21.0.5", message = "Connected to 10.1.0.1", env = "env", right = "right" | EVAL client_ip = client_ip::keyword @@ -924,7 +924,7 @@ left | 172.21.0.5 | Connected to 10.1.0.1 | right | Devel ; lookupIPAndMessageFromRowWithShadowingKeepReordered -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 ROW left = "left", client_ip = "172.21.0.5", message = "Connected to 10.1.0.1", env = "env", right = "right" | EVAL client_ip = client_ip::keyword @@ -938,7 +938,7 @@ right | Development | Success | 172.21.0.5 ; lookupIPAndMessageFromIndex -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | EVAL client_ip = client_ip::keyword @@ -958,7 +958,7 @@ ignoreOrder:true ; lookupIPAndMessageFromIndexKeep -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | EVAL client_ip = client_ip::keyword @@ -979,7 +979,7 @@ ignoreOrder:true ; lookupIPAndMessageFromIndexStats -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | EVAL client_ip = client_ip::keyword @@ -997,7 +997,7 @@ count:long | env:keyword | type:keyword ; lookupIPAndMessageFromIndexStatsKeep -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | EVAL client_ip = client_ip::keyword @@ -1016,7 +1016,7 @@ count:long | env:keyword | type:keyword ; statsAndLookupIPAndMessageFromIndex -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | EVAL client_ip = client_ip::keyword @@ -1035,7 +1035,7 @@ count:long | client_ip:keyword | message:keyword | env:keyword | type:keyw ; lookupIPAndMessageFromIndexChainedEvalKeep -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | EVAL client_ip = client_ip::keyword @@ -1057,7 +1057,7 @@ ignoreOrder:true ; lookupIPAndMessageFromIndexChainedRenameKeep -required_capability: join_lookup_v7 +required_capability: join_lookup_v8 FROM sample_data | EVAL client_ip = client_ip::keyword diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java index bfc2675d59791..a6e0f1d89c364 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/action/EsqlCapabilities.java @@ -555,12 +555,12 @@ public enum Cap { /** * LOOKUP JOIN */ - JOIN_LOOKUP_V7(Build.current().isSnapshot()), + JOIN_LOOKUP_V8(Build.current().isSnapshot()), /** * LOOKUP JOIN with the same index as the FROM */ - JOIN_LOOKUP_REPEATED_INDEX_FROM(JOIN_LOOKUP_V7.isEnabled()), + JOIN_LOOKUP_REPEATED_INDEX_FROM(JOIN_LOOKUP_V8.isEnabled()), /** * Fix for https://github.com/elastic/elasticsearch/issues/117054 diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java index e15731ca79038..ecd0821c626bf 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Analyzer.java @@ -235,6 +235,37 @@ private LogicalPlan resolveIndex(UnresolvedRelation plan, IndexResolution indexR } EsIndex esIndex = indexResolution.get(); + + if (plan.indexMode().equals(IndexMode.LOOKUP)) { + String indexResolutionMessage = null; + + var indexNameWithModes = esIndex.indexNameWithModes(); + if (indexNameWithModes.size() != 1) { + indexResolutionMessage = "invalid [" + + table + + "] resolution in lookup mode to [" + + indexNameWithModes.size() + + "] indices"; + } else if (indexNameWithModes.values().iterator().next() != IndexMode.LOOKUP) { + indexResolutionMessage = "invalid [" + + table + + "] resolution in lookup mode to an index in [" + + indexNameWithModes.values().iterator().next() + + "] mode"; + } + + if (indexResolutionMessage != null) { + return new UnresolvedRelation( + plan.source(), + plan.table(), + plan.frozen(), + plan.metadataFields(), + plan.indexMode(), + indexResolutionMessage, + plan.commandName() + ); + } + } var attributes = mappingAsAttributes(plan.source(), esIndex.mapping()); attributes.addAll(plan.metadataFields()); return new EsRelation(plan.source(), esIndex, attributes.isEmpty() ? NO_FIELDS : attributes, plan.indexMode()); diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java index 6b98b7d69834f..93e9d59ed8c6e 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/analysis/Verifier.java @@ -865,7 +865,6 @@ private static void checkJoin(LogicalPlan plan, Set failures) { ); } } - } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java index 70794e4a82130..b81b80a9fdbb4 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java @@ -263,7 +263,7 @@ public final void test() throws Throwable { ); assumeFalse( "lookup join disabled for csv tests", - testCase.requiredCapabilities.contains(EsqlCapabilities.Cap.JOIN_LOOKUP_V7.capabilityName()) + testCase.requiredCapabilities.contains(EsqlCapabilities.Cap.JOIN_LOOKUP_V8.capabilityName()) ); assumeFalse( "can't use TERM function in csv tests", diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTestUtils.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTestUtils.java index 85dd36ba0aaa5..d4e786a9d9bb0 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTestUtils.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTestUtils.java @@ -46,6 +46,10 @@ public static Analyzer analyzer(IndexResolution indexResolution) { return analyzer(indexResolution, TEST_VERIFIER); } + public static Analyzer analyzer(IndexResolution indexResolution, Map lookupResolution) { + return analyzer(indexResolution, lookupResolution, TEST_VERIFIER); + } + public static Analyzer analyzer(IndexResolution indexResolution, Verifier verifier) { return new Analyzer( new AnalyzerContext( @@ -59,6 +63,19 @@ public static Analyzer analyzer(IndexResolution indexResolution, Verifier verifi ); } + public static Analyzer analyzer(IndexResolution indexResolution, Map lookupResolution, Verifier verifier) { + return new Analyzer( + new AnalyzerContext( + EsqlTestUtils.TEST_CFG, + new EsqlFunctionRegistry(), + indexResolution, + lookupResolution, + defaultEnrichResolution() + ), + verifier + ); + } + public static Analyzer analyzer(IndexResolution indexResolution, Verifier verifier, Configuration config) { return new Analyzer( new AnalyzerContext(config, new EsqlFunctionRegistry(), indexResolution, defaultLookupResolution(), defaultEnrichResolution()), @@ -111,7 +128,7 @@ public static IndexResolution loadMapping(String resource, String indexName, Ind } public static IndexResolution loadMapping(String resource, String indexName) { - EsIndex test = new EsIndex(indexName, EsqlTestUtils.loadMapping(resource)); + EsIndex test = new EsIndex(indexName, EsqlTestUtils.loadMapping(resource), Map.of(indexName, IndexMode.STANDARD)); return IndexResolution.valid(test); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java index 9c71f20dcde0e..5d1ff43dfe31b 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/AnalyzerTests.java @@ -2139,7 +2139,7 @@ public void testLookupMatchTypeWrong() { } public void testLookupJoinUnknownIndex() { - assumeTrue("requires LOOKUP JOIN capability", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("requires LOOKUP JOIN capability", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); String errorMessage = "Unknown index [foobar]"; IndexResolution missingLookupIndex = IndexResolution.invalid(errorMessage); @@ -2168,7 +2168,7 @@ public void testLookupJoinUnknownIndex() { } public void testLookupJoinUnknownField() { - assumeTrue("requires LOOKUP JOIN capability", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("requires LOOKUP JOIN capability", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); String query = "FROM test | LOOKUP JOIN languages_lookup ON last_name"; String errorMessage = "1:45: Unknown column [last_name] in right side of join"; @@ -2190,6 +2190,35 @@ public void testLookupJoinUnknownField() { assertThat(e.getMessage(), containsString(errorMessage3 + "right side of join")); } + public void testLookupJoinIndexMode() { + assumeTrue("requires LOOKUP JOIN capability", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); + + var indexResolution = AnalyzerTestUtils.expandedDefaultIndexResolution(); + var lookupResolution = AnalyzerTestUtils.defaultLookupResolution(); + var indexResolutionAsLookup = Map.of("test", indexResolution); + var lookupResolutionAsIndex = lookupResolution.get("languages_lookup"); + + analyze("FROM test | EVAL language_code = languages | LOOKUP JOIN languages_lookup ON language_code"); + analyze( + "FROM languages_lookup | LOOKUP JOIN languages_lookup ON language_code", + AnalyzerTestUtils.analyzer(lookupResolutionAsIndex, lookupResolution) + ); + + VerificationException e = expectThrows( + VerificationException.class, + () -> analyze( + "FROM languages_lookup | EVAL languages = language_code | LOOKUP JOIN test ON languages", + AnalyzerTestUtils.analyzer(lookupResolutionAsIndex, indexResolutionAsLookup) + ) + ); + assertThat(e.getMessage(), containsString("1:70: invalid [test] resolution in lookup mode to an index in [standard] mode")); + e = expectThrows( + VerificationException.class, + () -> analyze("FROM test | LOOKUP JOIN test ON languages", AnalyzerTestUtils.analyzer(indexResolution, indexResolutionAsLookup)) + ); + assertThat(e.getMessage(), containsString("1:25: invalid [test] resolution in lookup mode to an index in [standard] mode")); + } + public void testImplicitCasting() { var e = expectThrows(VerificationException.class, () -> analyze(""" from test | eval x = concat("2024", "-04", "-01") + 1 day diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java index 90a215653f251..549ddce03c206 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/ParsingTests.java @@ -113,7 +113,7 @@ public void testTooBigQuery() { } public void testJoinOnConstant() { - assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); assertEquals( "1:55: JOIN ON clause only supports fields at the moment, found [123]", error("row languages = 1, gender = \"f\" | lookup join test on 123") @@ -129,7 +129,7 @@ public void testJoinOnConstant() { } public void testJoinOnMultipleFields() { - assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); assertEquals( "1:35: JOIN ON clause only supports one field at the moment, found [2]", error("row languages = 1, gender = \"f\" | lookup join test on gender, languages") @@ -137,7 +137,7 @@ public void testJoinOnMultipleFields() { } public void testJoinTwiceOnTheSameField() { - assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); assertEquals( "1:35: JOIN ON clause only supports one field at the moment, found [2]", error("row languages = 1, gender = \"f\" | lookup join test on languages, languages") @@ -145,7 +145,7 @@ public void testJoinTwiceOnTheSameField() { } public void testJoinTwiceOnTheSameField_TwoLookups() { - assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); assertEquals( "1:80: JOIN ON clause only supports one field at the moment, found [2]", error("row languages = 1, gender = \"f\" | lookup join test on languages | eval x = 1 | lookup join test on gender, gender") diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java index a1e29117a25d3..43d764ab2007d 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/analysis/VerifierTests.java @@ -1974,7 +1974,7 @@ public void testSortByAggregate() { } public void testLookupJoinDataTypeMismatch() { - assumeTrue("requires LOOKUP JOIN capability", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("requires LOOKUP JOIN capability", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); query("FROM test | EVAL language_code = languages | LOOKUP JOIN languages_lookup ON language_code"); @@ -1985,7 +1985,11 @@ public void testLookupJoinDataTypeMismatch() { } private void query(String query) { - defaultAnalyzer.analyze(parser.createStatement(query)); + query(query, defaultAnalyzer); + } + + private void query(String query, Analyzer analyzer) { + analyzer.analyze(parser.createStatement(query)); } private String error(String query) { diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java index cfb993a7dd73d..17e158f088fb3 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/LogicalPlanOptimizerTests.java @@ -4906,7 +4906,7 @@ public void testPlanSanityCheck() throws Exception { } public void testPlanSanityCheckWithBinaryPlans() throws Exception { - assumeTrue("Requires LOOKUP JOIN", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("Requires LOOKUP JOIN", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); var plan = optimizedPlan(""" FROM test @@ -5911,7 +5911,7 @@ public void testLookupStats() { * \_EsRelation[languages_lookup][LOOKUP][language_code{f}#18, language_name{f}#19] */ public void testLookupJoinPushDownFilterOnJoinKeyWithRename() { - assumeTrue("Requires LOOKUP JOIN", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("Requires LOOKUP JOIN", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); String query = """ FROM test @@ -5954,7 +5954,7 @@ public void testLookupJoinPushDownFilterOnJoinKeyWithRename() { * \_EsRelation[languages_lookup][LOOKUP][language_code{f}#18, language_name{f}#19] */ public void testLookupJoinPushDownFilterOnLeftSideField() { - assumeTrue("Requires LOOKUP JOIN", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("Requires LOOKUP JOIN", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); String query = """ FROM test @@ -5998,7 +5998,7 @@ public void testLookupJoinPushDownFilterOnLeftSideField() { * \_EsRelation[languages_lookup][LOOKUP][language_code{f}#18, language_name{f}#19] */ public void testLookupJoinPushDownDisabledForLookupField() { - assumeTrue("Requires LOOKUP JOIN", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("Requires LOOKUP JOIN", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); String query = """ FROM test @@ -6043,7 +6043,7 @@ public void testLookupJoinPushDownDisabledForLookupField() { * \_EsRelation[languages_lookup][LOOKUP][language_code{f}#19, language_name{f}#20] */ public void testLookupJoinPushDownSeparatedForConjunctionBetweenLeftAndRightField() { - assumeTrue("Requires LOOKUP JOIN", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("Requires LOOKUP JOIN", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); String query = """ FROM test @@ -6096,7 +6096,7 @@ public void testLookupJoinPushDownSeparatedForConjunctionBetweenLeftAndRightFiel * \_EsRelation[languages_lookup][LOOKUP][language_code{f}#19, language_name{f}#20] */ public void testLookupJoinPushDownDisabledForDisjunctionBetweenLeftAndRightField() { - assumeTrue("Requires LOOKUP JOIN", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("Requires LOOKUP JOIN", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); String query = """ FROM test diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java index 964dd4642d7c2..c7bb6e49703ed 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/optimizer/PhysicalPlanOptimizerTests.java @@ -2331,7 +2331,7 @@ public void testVerifierOnMissingReferences() { } public void testVerifierOnMissingReferencesWithBinaryPlans() throws Exception { - assumeTrue("Requires LOOKUP JOIN", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("Requires LOOKUP JOIN", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); // Do not assert serialization: // This will have a LookupJoinExec, which is not serializable because it doesn't leave the coordinator. diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/session/IndexResolverFieldNamesTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/session/IndexResolverFieldNamesTests.java index 31ec4663738f7..60bdf4e7f73d3 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/session/IndexResolverFieldNamesTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/session/IndexResolverFieldNamesTests.java @@ -1365,7 +1365,7 @@ public void testMetrics() { } public void testLookupJoin() { - assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); assertFieldNames( "FROM employees | KEEP languages | RENAME languages AS language_code | LOOKUP JOIN languages_lookup ON language_code", Set.of("languages", "languages.*", "language_code", "language_code.*"), @@ -1374,7 +1374,7 @@ public void testLookupJoin() { } public void testLookupJoinKeep() { - assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); assertFieldNames( """ FROM employees @@ -1388,7 +1388,7 @@ public void testLookupJoinKeep() { } public void testLookupJoinKeepWildcard() { - assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); assertFieldNames( """ FROM employees @@ -1402,7 +1402,7 @@ public void testLookupJoinKeepWildcard() { } public void testMultiLookupJoin() { - assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); assertFieldNames( """ FROM sample_data @@ -1415,7 +1415,7 @@ public void testMultiLookupJoin() { } public void testMultiLookupJoinKeepBefore() { - assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); assertFieldNames( """ FROM sample_data @@ -1429,7 +1429,7 @@ public void testMultiLookupJoinKeepBefore() { } public void testMultiLookupJoinKeepBetween() { - assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); assertFieldNames( """ FROM sample_data @@ -1454,7 +1454,7 @@ public void testMultiLookupJoinKeepBetween() { } public void testMultiLookupJoinKeepAfter() { - assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); assertFieldNames( """ FROM sample_data @@ -1481,7 +1481,7 @@ public void testMultiLookupJoinKeepAfter() { } public void testMultiLookupJoinKeepAfterWildcard() { - assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); assertFieldNames( """ FROM sample_data @@ -1495,7 +1495,7 @@ public void testMultiLookupJoinKeepAfterWildcard() { } public void testMultiLookupJoinSameIndex() { - assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); assertFieldNames( """ FROM sample_data @@ -1509,7 +1509,7 @@ public void testMultiLookupJoinSameIndex() { } public void testMultiLookupJoinSameIndexKeepBefore() { - assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); assertFieldNames( """ FROM sample_data @@ -1524,7 +1524,7 @@ public void testMultiLookupJoinSameIndexKeepBefore() { } public void testMultiLookupJoinSameIndexKeepBetween() { - assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); assertFieldNames( """ FROM sample_data @@ -1550,7 +1550,7 @@ public void testMultiLookupJoinSameIndexKeepBetween() { } public void testMultiLookupJoinSameIndexKeepAfter() { - assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V7.isEnabled()); + assumeTrue("LOOKUP JOIN available as snapshot only", EsqlCapabilities.Cap.JOIN_LOOKUP_V8.isEnabled()); assertFieldNames( """ FROM sample_data diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/190_lookup_join.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/190_lookup_join.yml new file mode 100644 index 0000000000000..cbaac4e47fdd4 --- /dev/null +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/190_lookup_join.yml @@ -0,0 +1,78 @@ +--- +setup: + - requires: + test_runner_features: [capabilities] + capabilities: + - method: POST + path: /_query + parameters: [] + capabilities: [join_lookup_v8] + reason: "uses LOOKUP JOIN" + - do: + indices.create: + index: test + body: + settings: + number_of_shards: 5 + mappings: + properties: + key: + type: long + color: + type: keyword + - do: + indices.create: + index: test-lookup + body: + settings: + index: + mode: lookup + mappings: + properties: + key: + type: long + color: + type: keyword + - do: + bulk: + index: "test" + refresh: true + body: + - { "index": { } } + - { "key": 1, "color": "red" } + - { "index": { } } + - { "key": 2, "color": "blue" } + - do: + bulk: + index: "test-lookup" + refresh: true + body: + - { "index": { } } + - { "key": 1, "color": "cyan" } + - { "index": { } } + - { "key": 2, "color": "yellow" } + +--- +basic: + - do: + esql.query: + body: + query: 'FROM test | SORT key | LOOKUP JOIN `test-lookup` ON key | LIMIT 3' + + - match: {columns.0.name: "key"} + - match: {columns.0.type: "long"} + - match: {columns.1.name: "color"} + - match: {columns.1.type: "keyword"} + - match: {values.0: [1, "cyan"]} + - match: {values.1: [2, "yellow"]} + +--- +non-lookup index: + - do: + esql.query: + body: + query: 'FROM test-lookup | SORT key | LOOKUP JOIN `test` ON key | LIMIT 3' + catch: "bad_request" + + - match: { error.type: "verification_exception" } + - match: { error.reason: "Found 1 problem\nline 1:43: invalid [test] resolution in lookup mode to an index in [standard] mode" } From 6e725163dc2f466c4c64d8076d693a3feddf3213 Mon Sep 17 00:00:00 2001 From: elasticsearchmachine <58790826+elasticsearchmachine@users.noreply.github.com> Date: Thu, 19 Dec 2024 00:47:40 +1100 Subject: [PATCH 42/60] Mute org.elasticsearch.smoketest.SmokeTestMultiNodeClientYamlTestSuiteIT org.elasticsearch.smoketest.SmokeTestMultiNodeClientYamlTestSuiteIT #118955 --- muted-tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/muted-tests.yml b/muted-tests.yml index 2677b3e75d86e..3a8594acf3bb1 100644 --- a/muted-tests.yml +++ b/muted-tests.yml @@ -290,6 +290,8 @@ tests: - class: org.elasticsearch.cluster.service.MasterServiceTests method: testThreadContext issue: https://github.com/elastic/elasticsearch/issues/118914 +- class: org.elasticsearch.smoketest.SmokeTestMultiNodeClientYamlTestSuiteIT + issue: https://github.com/elastic/elasticsearch/issues/118955 # Examples: # From 49f991bd982e3a81276ce0c43ea15eb399c5a322 Mon Sep 17 00:00:00 2001 From: Artem Prigoda Date: Wed, 18 Dec 2024 14:56:57 +0100 Subject: [PATCH 43/60] [test] Fix RecoverySourcePruneMergePolicyTests#testPruneSome (#118944) The `extra_source_size` field is set to a value between 10 and 10000 inclusive, so the assertion should be `greaterThanOrEqualTo(10)` rather than `greaterThan(10)`. See #114618 Resolve #118728 --- .../index/engine/RecoverySourcePruneMergePolicyTests.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/test/java/org/elasticsearch/index/engine/RecoverySourcePruneMergePolicyTests.java b/server/src/test/java/org/elasticsearch/index/engine/RecoverySourcePruneMergePolicyTests.java index 74d6e83aff266..b8600842effe4 100644 --- a/server/src/test/java/org/elasticsearch/index/engine/RecoverySourcePruneMergePolicyTests.java +++ b/server/src/test/java/org/elasticsearch/index/engine/RecoverySourcePruneMergePolicyTests.java @@ -44,7 +44,7 @@ import java.util.stream.Collectors; import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; public class RecoverySourcePruneMergePolicyTests extends ESTestCase { @@ -191,7 +191,7 @@ public void testPruneSome() throws IOException { } assertEquals(i, extra_source.docID()); if (syntheticRecoverySource) { - assertThat(extra_source.longValue(), greaterThan(10L)); + assertThat(extra_source.longValue(), greaterThanOrEqualTo(10L)); } else { assertThat(extra_source.longValue(), equalTo(1L)); } From ad9caae09918207f8ac0e8b1a92a95bdb189c507 Mon Sep 17 00:00:00 2001 From: Jim Ferenczi Date: Wed, 18 Dec 2024 14:01:05 +0000 Subject: [PATCH 44/60] Improve handling of nested fields in index reader wrappers (#118757) This update enhances the handling of parent filters to ensure proper exclusion of child documents. --- docs/changelog/118757.yaml | 5 + .../test/AbstractBuilderTestCase.java | 4 + .../authz/permission/DocumentPermissions.java | 6 +- ...ityIndexReaderWrapperIntegrationTests.java | 180 ++++++++++++++++++ 4 files changed, 193 insertions(+), 2 deletions(-) create mode 100644 docs/changelog/118757.yaml diff --git a/docs/changelog/118757.yaml b/docs/changelog/118757.yaml new file mode 100644 index 0000000000000..956e220f21aeb --- /dev/null +++ b/docs/changelog/118757.yaml @@ -0,0 +1,5 @@ +pr: 118757 +summary: Improve handling of nested fields in index reader wrappers +area: Authorization +type: enhancement +issues: [] diff --git a/test/framework/src/main/java/org/elasticsearch/test/AbstractBuilderTestCase.java b/test/framework/src/main/java/org/elasticsearch/test/AbstractBuilderTestCase.java index 20cb66affddee..d239c6453a7fe 100644 --- a/test/framework/src/main/java/org/elasticsearch/test/AbstractBuilderTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/test/AbstractBuilderTestCase.java @@ -241,6 +241,10 @@ protected static IndexSettings indexSettings() { return serviceHolder.idxSettings; } + protected static MapperService mapperService() { + return serviceHolder.mapperService; + } + protected static String expectedFieldName(String builderFieldName) { return ALIAS_TO_CONCRETE_FIELD_NAME.getOrDefault(builderFieldName, builderFieldName); } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/DocumentPermissions.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/DocumentPermissions.java index 24f0a52436203..92bb037888495 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/DocumentPermissions.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/DocumentPermissions.java @@ -159,13 +159,15 @@ private static void buildRoleQuery( if (queryBuilder != null) { failIfQueryUsesClient(queryBuilder, context); Query roleQuery = context.toQuery(queryBuilder).query(); - filter.add(roleQuery, SHOULD); - if (context.nestedLookup() != NestedLookup.EMPTY) { + if (context.nestedLookup() == NestedLookup.EMPTY) { + filter.add(roleQuery, SHOULD); + } else { if (NestedHelper.mightMatchNestedDocs(roleQuery, context)) { roleQuery = new BooleanQuery.Builder().add(roleQuery, FILTER) .add(Queries.newNonNestedFilter(context.indexVersionCreated()), FILTER) .build(); } + filter.add(roleQuery, SHOULD); // If access is allowed on root doc then also access is allowed on all nested docs of that root document: BitSetProducer rootDocs = context.bitsetFilter(Queries.newNonNestedFilter(context.indexVersionCreated())); ToChildBlockJoinQuery includeNestedDocs = new ToChildBlockJoinQuery(roleQuery, rootDocs); diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/accesscontrol/SecurityIndexReaderWrapperIntegrationTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/accesscontrol/SecurityIndexReaderWrapperIntegrationTests.java index 4751f66cf548e..89b42228d8918 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/accesscontrol/SecurityIndexReaderWrapperIntegrationTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/accesscontrol/SecurityIndexReaderWrapperIntegrationTests.java @@ -23,9 +23,12 @@ import org.apache.lucene.search.TotalHitCountCollectorManager; import org.apache.lucene.store.Directory; import org.elasticsearch.client.internal.Client; +import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.bytes.BytesReference; +import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.lucene.index.ElasticsearchDirectoryReader; +import org.elasticsearch.common.lucene.search.Queries; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.index.IndexSettings; @@ -33,9 +36,11 @@ import org.elasticsearch.index.mapper.KeywordFieldMapper.KeywordFieldType; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MapperMetrics; +import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.mapper.Mapping; import org.elasticsearch.index.mapper.MappingLookup; import org.elasticsearch.index.mapper.MockFieldMapper; +import org.elasticsearch.index.mapper.SourceToParse; import org.elasticsearch.index.query.ParsedQuery; import org.elasticsearch.index.query.SearchExecutionContext; import org.elasticsearch.index.query.TermsQueryBuilder; @@ -45,6 +50,9 @@ import org.elasticsearch.search.internal.ContextIndexSearcher; import org.elasticsearch.test.AbstractBuilderTestCase; import org.elasticsearch.test.IndexSettingsModule; +import org.elasticsearch.xcontent.XContentBuilder; +import org.elasticsearch.xcontent.XContentFactory; +import org.elasticsearch.xcontent.XContentType; import org.elasticsearch.xpack.core.security.SecurityContext; import org.elasticsearch.xpack.core.security.authc.Authentication; import org.elasticsearch.xpack.core.security.authc.AuthenticationTestHelper; @@ -52,6 +60,8 @@ import org.elasticsearch.xpack.core.security.authz.permission.DocumentPermissions; import org.elasticsearch.xpack.core.security.authz.permission.FieldPermissions; +import java.io.IOException; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -340,6 +350,176 @@ protected IndicesAccessControl getIndicesAccessControl() { directory.close(); } + @Override + protected void initializeAdditionalMappings(MapperService mapperService) throws IOException { + XContentBuilder builder = XContentFactory.jsonBuilder() + .startObject() + .startObject("properties") + .startObject("f1") + .field("type", "keyword") + .endObject() + .startObject("nested1") + .field("type", "nested") + .startObject("properties") + .startObject("field") + .field("type", "keyword") + .endObject() + .endObject() + .endObject() + .endObject() + .endObject(); + mapperService.merge( + MapperService.SINGLE_MAPPING_NAME, + new CompressedXContent(Strings.toString(builder)), + MapperService.MergeReason.MAPPING_UPDATE + ); + } + + public void testDLSWithNestedDocs() throws Exception { + Directory directory = newDirectory(); + try ( + IndexWriter iw = new IndexWriter( + directory, + new IndexWriterConfig(new StandardAnalyzer()).setMergePolicy(NoMergePolicy.INSTANCE) + ) + ) { + var parser = mapperService().documentParser(); + String doc = """ + { + "f1": "value", + "nested1": [ + { + "field": "0" + }, + { + "field": "1" + }, + {} + ] + } + """; + var parsedDoc = parser.parseDocument( + new SourceToParse("0", new BytesArray(doc), XContentType.JSON), + mapperService().mappingLookup() + ); + iw.addDocuments(parsedDoc.docs()); + + doc = """ + { + "nested1": [ + { + "field": "12" + }, + { + "field": "13" + }, + {} + ] + } + """; + parsedDoc = parser.parseDocument( + new SourceToParse("1", new BytesArray(doc), XContentType.JSON), + mapperService().mappingLookup() + ); + iw.addDocuments(parsedDoc.docs()); + + doc = """ + { + "f1": "value", + "nested1": [ + { + "field": "12" + }, + {} + ] + } + """; + parsedDoc = parser.parseDocument( + new SourceToParse("2", new BytesArray(doc), XContentType.JSON), + mapperService().mappingLookup() + ); + iw.addDocuments(parsedDoc.docs()); + + doc = """ + { + "nested1": [ + { + "field": "12" + }, + {} + ] + } + """; + parsedDoc = parser.parseDocument( + new SourceToParse("3", new BytesArray(doc), XContentType.JSON), + mapperService().mappingLookup() + ); + iw.addDocuments(parsedDoc.docs()); + + iw.commit(); + } + + DirectoryReader directoryReader = ElasticsearchDirectoryReader.wrap( + DirectoryReader.open(directory), + new ShardId(indexSettings().getIndex(), 0) + ); + SearchExecutionContext context = createSearchExecutionContext(new IndexSearcher(directoryReader)); + + final ThreadContext threadContext = new ThreadContext(Settings.EMPTY); + final SecurityContext securityContext = new SecurityContext(Settings.EMPTY, threadContext); + final Authentication authentication = AuthenticationTestHelper.builder().build(); + new AuthenticationContextSerializer().writeToContext(authentication, threadContext); + + Set queries = new HashSet<>(); + queries.add(new BytesArray("{\"bool\": { \"must_not\": { \"exists\": { \"field\": \"f1\" } } } }")); + IndicesAccessControl.IndexAccessControl indexAccessControl = new IndicesAccessControl.IndexAccessControl( + FieldPermissions.DEFAULT, + DocumentPermissions.filteredBy(queries) + ); + + DocumentSubsetBitsetCache bitsetCache = new DocumentSubsetBitsetCache(Settings.EMPTY, Executors.newSingleThreadExecutor()); + + final MockLicenseState licenseState = mock(MockLicenseState.class); + when(licenseState.isAllowed(DOCUMENT_LEVEL_SECURITY_FEATURE)).thenReturn(true); + ScriptService scriptService = mock(ScriptService.class); + SecurityIndexReaderWrapper wrapper = new SecurityIndexReaderWrapper( + s -> context, + bitsetCache, + securityContext, + licenseState, + scriptService + ) { + + @Override + protected IndicesAccessControl getIndicesAccessControl() { + IndicesAccessControl indicesAccessControl = new IndicesAccessControl( + true, + singletonMap(indexSettings().getIndex().getName(), indexAccessControl) + ); + return indicesAccessControl; + } + }; + + DirectoryReader wrappedDirectoryReader = wrapper.apply(directoryReader); + IndexSearcher indexSearcher = new ContextIndexSearcher( + wrappedDirectoryReader, + IndexSearcher.getDefaultSimilarity(), + IndexSearcher.getDefaultQueryCache(), + IndexSearcher.getDefaultQueryCachingPolicy(), + true + ); + + ScoreDoc[] hits = indexSearcher.search(new MatchAllDocsQuery(), 1000).scoreDocs; + assertThat(Arrays.stream(hits).map(h -> h.doc).collect(Collectors.toSet()), containsInAnyOrder(4, 5, 6, 7, 11, 12, 13)); + + hits = indexSearcher.search(Queries.newNonNestedFilter(context.indexVersionCreated()), 1000).scoreDocs; + assertThat(Arrays.stream(hits).map(h -> h.doc).collect(Collectors.toSet()), containsInAnyOrder(7, 13)); + + bitsetCache.close(); + directoryReader.close(); + directory.close(); + } + private static MappingLookup createMappingLookup(List concreteFields) { List mappers = concreteFields.stream().map(MockFieldMapper::new).collect(Collectors.toList()); return MappingLookup.fromMappers(Mapping.EMPTY, mappers, emptyList()); From 5255bfb6fb2f18afaebaf5f9951619a77a58667d Mon Sep 17 00:00:00 2001 From: Sean Story Date: Wed, 18 Dec 2024 08:03:08 -0600 Subject: [PATCH 45/60] Replace 'ent-search-generic' with 'search-default' pipeline (#118899) * Replace 'ent-search-generic' with 'search-default' pipeline * missed one * [CI] Auto commit changes from spotless --------- Co-authored-by: elasticsearchmachine --- .java-version | 1 + .../connectors-content-extraction.asciidoc | 2 +- ...nnectors-filter-extract-transform.asciidoc | 4 +- .../search-inference-processing.asciidoc | 2 +- .../ingest/search-ingest-pipelines.asciidoc | 33 +++-- .../ingest/search-nlp-tutorial.asciidoc | 4 +- .../elastic-connectors-mappings.json | 2 +- .../entsearch/generic_ingestion_pipeline.json | 130 ------------------ .../connector/ConnectorTemplateRegistry.java | 10 -- .../ConnectorIngestPipelineTests.java | 2 +- .../ConnectorTemplateRegistryTests.java | 15 +- .../application/connector/ConnectorTests.java | 6 +- .../syncjob/ConnectorSyncJobTests.java | 8 +- 13 files changed, 37 insertions(+), 182 deletions(-) create mode 100644 .java-version delete mode 100644 x-pack/plugin/core/template-resources/src/main/resources/entsearch/generic_ingestion_pipeline.json diff --git a/.java-version b/.java-version new file mode 100644 index 0000000000000..aabe6ec3909c9 --- /dev/null +++ b/.java-version @@ -0,0 +1 @@ +21 diff --git a/docs/reference/connector/docs/connectors-content-extraction.asciidoc b/docs/reference/connector/docs/connectors-content-extraction.asciidoc index a87d38c9bf531..744fe1d87cb45 100644 --- a/docs/reference/connector/docs/connectors-content-extraction.asciidoc +++ b/docs/reference/connector/docs/connectors-content-extraction.asciidoc @@ -8,7 +8,7 @@ The logic for content extraction is defined in {connectors-python}/connectors/ut While intended primarily for PDF and Microsoft Office formats, you can use any of the <>. Enterprise Search uses an {ref}/ingest.html[Elasticsearch ingest pipeline^] to power the web crawler's binary content extraction. -The default pipeline, `ent-search-generic-ingestion`, is automatically created when Enterprise Search first starts. +The default pipeline, `search-default-ingestion`, is automatically created when Enterprise Search first starts. You can {ref}/ingest.html#create-manage-ingest-pipelines[view^] this pipeline in Kibana. Customizing your pipeline usage is also an option. diff --git a/docs/reference/connector/docs/connectors-filter-extract-transform.asciidoc b/docs/reference/connector/docs/connectors-filter-extract-transform.asciidoc index 278478c908bf0..62a99928bfb46 100644 --- a/docs/reference/connector/docs/connectors-filter-extract-transform.asciidoc +++ b/docs/reference/connector/docs/connectors-filter-extract-transform.asciidoc @@ -13,7 +13,7 @@ The following diagram provides an overview of how content extraction, sync rules [.screenshot] image::images/pipelines-extraction-sync-rules.png[Architecture diagram of data pipeline with content extraction, sync rules, and ingest pipelines] -By default, only the connector specific logic (2) and the default `ent-search-generic-ingestion` pipeline (6) extract and transform your data, as configured in your deployment. +By default, only the connector specific logic (2) and the default `search-default-ingestion` pipeline (6) extract and transform your data, as configured in your deployment. The following tools are available for more advanced use cases: @@ -50,4 +50,4 @@ Use ingest pipelines for data enrichment, normalization, and more. Elastic connectors use a default ingest pipeline, which you can copy and customize to meet your needs. -Refer to {ref}/ingest-pipeline-search.html[ingest pipelines in Search] in the {es} documentation. \ No newline at end of file +Refer to {ref}/ingest-pipeline-search.html[ingest pipelines in Search] in the {es} documentation. diff --git a/docs/reference/ingest/search-inference-processing.asciidoc b/docs/reference/ingest/search-inference-processing.asciidoc index 006cc96294477..73642b3bb3447 100644 --- a/docs/reference/ingest/search-inference-processing.asciidoc +++ b/docs/reference/ingest/search-inference-processing.asciidoc @@ -88,7 +88,7 @@ The `monitor_ml` <> is req To create the index-specific ML inference pipeline, go to *Search -> Content -> Indices -> -> Pipelines* in the Kibana UI. -If you only see the `ent-search-generic-ingestion` pipeline, you will need to click *Copy and customize* to create index-specific pipelines. +If you only see the `search-default-ingestion` pipeline, you will need to click *Copy and customize* to create index-specific pipelines. This will create the `{index_name}@ml-inference` pipeline. Once your index-specific ML inference pipeline is ready, you can add inference processors that use your ML trained models. diff --git a/docs/reference/ingest/search-ingest-pipelines.asciidoc b/docs/reference/ingest/search-ingest-pipelines.asciidoc index e414dacaab964..272c6ba2884b9 100644 --- a/docs/reference/ingest/search-ingest-pipelines.asciidoc +++ b/docs/reference/ingest/search-ingest-pipelines.asciidoc @@ -40,7 +40,7 @@ Considerations such as error handling, conditional execution, sequencing, versio To this end, when you create indices for search use cases, (including {enterprise-search-ref}/crawler.html[Elastic web crawler], <>. , and API indices), each index already has a pipeline set up with several processors that optimize your content for search. -This pipeline is called `ent-search-generic-ingestion`. +This pipeline is called `search-default-ingestion`. While it is a "managed" pipeline (meaning it should not be tampered with), you can view its details via the Kibana UI or the Elasticsearch API. You can also <>. @@ -56,14 +56,14 @@ This will not effect existing indices. Each index also provides the capability to easily create index-specific ingest pipelines with customizable processing. If you need that extra flexibility, you can create a custom pipeline by going to your pipeline settings and choosing to "copy and customize". -This will replace the index's use of `ent-search-generic-ingestion` with 3 newly generated pipelines: +This will replace the index's use of `search-default-ingestion` with 3 newly generated pipelines: 1. `` 2. `@custom` 3. `@ml-inference` -Like `ent-search-generic-ingestion`, the first of these is "managed", but the other two can and should be modified to fit your needs. -You can view these pipelines using the platform tools (Kibana UI, Elasticsearch API), and can also +Like `search-default-ingestion`, the first of these is "managed", but the other two can and should be modified to fit your needs. +You can view these pipelines using the platform tools (Kibana UI, Elasticsearch API), and can also <>. [discrete#ingest-pipeline-search-pipeline-settings] @@ -123,7 +123,7 @@ If the pipeline is not specified, the underscore-prefixed fields will actually b === Details [discrete#ingest-pipeline-search-details-generic-reference] -==== `ent-search-generic-ingestion` Reference +==== `search-default-ingestion` Reference You can access this pipeline with the <> or via Kibana's < Ingest Pipelines>> UI. @@ -149,7 +149,7 @@ If you want to make customizations, we recommend you utilize index-specific pipe [discrete#ingest-pipeline-search-details-generic-reference-params] ===== Control flow parameters -The `ent-search-generic-ingestion` pipeline does not always run all processors. +The `search-default-ingestion` pipeline does not always run all processors. It utilizes a feature of ingest pipelines to <> based on the contents of each individual document. * `_extract_binary_content` - if this field is present and has a value of `true` on a source document, the pipeline will attempt to run the `attachment`, `set_body`, and `remove_replacement_chars` processors. @@ -167,8 +167,8 @@ See <>. ==== Index-specific ingest pipelines In the Kibana UI for your index, by clicking on the Pipelines tab, then *Settings > Copy and customize*, you can quickly generate 3 pipelines which are specific to your index. -These 3 pipelines replace `ent-search-generic-ingestion` for the index. -There is nothing lost in this action, as the `` pipeline is a superset of functionality over the `ent-search-generic-ingestion` pipeline. +These 3 pipelines replace `search-default-ingestion` for the index. +There is nothing lost in this action, as the `` pipeline is a superset of functionality over the `search-default-ingestion` pipeline. [IMPORTANT] ==== @@ -179,7 +179,7 @@ Refer to the Elastic subscriptions pages for https://www.elastic.co/subscription [discrete#ingest-pipeline-search-details-specific-reference] ===== `` Reference -This pipeline looks and behaves a lot like the <>, but with <>. +This pipeline looks and behaves a lot like the <>, but with <>. [WARNING] ========================= @@ -197,7 +197,7 @@ If you want to make customizations, we recommend you utilize <>, the index-specific pipeline also defines: +In addition to the processors inherited from the <>, the index-specific pipeline also defines: * `index_ml_inference_pipeline` - this uses the <> processor to run the `@ml-inference` pipeline. This processor will only be run if the source document includes a `_run_ml_inference` field with the value `true`. @@ -206,7 +206,7 @@ In addition to the processors inherited from the <` pipeline does not always run all processors. +Like the `search-default-ingestion` pipeline, the `` pipeline does not always run all processors. In addition to the `_extract_binary_content` and `_reduce_whitespace` control flow parameters, the `` pipeline also supports: * `_run_ml_inference` - if this field is present and has a value of `true` on a source document, the pipeline will attempt to run the `index_ml_inference_pipeline` processor. @@ -220,7 +220,7 @@ See <>. ===== `@ml-inference` Reference This pipeline is empty to start (no processors), but can be added to via the Kibana UI either through the Pipelines tab of your index, or from the *Stack Management > Ingest Pipelines* page. -Unlike the `ent-search-generic-ingestion` pipeline and the `` pipeline, this pipeline is NOT "managed". +Unlike the `search-default-ingestion` pipeline and the `` pipeline, this pipeline is NOT "managed". It's possible to add one or more ML inference pipelines to an index in the *Content* UI. This pipeline will serve as a container for all of the ML inference pipelines configured for the index. @@ -241,7 +241,7 @@ The `monitor_ml` Elasticsearch cluster permission is required in order to manage This pipeline is empty to start (no processors), but can be added to via the Kibana UI either through the Pipelines tab of your index, or from the *Stack Management > Ingest Pipelines* page. -Unlike the `ent-search-generic-ingestion` pipeline and the `` pipeline, this pipeline is NOT "managed". +Unlike the `search-default-ingestion` pipeline and the `` pipeline, this pipeline is NOT "managed". You are encouraged to make additions and edits to this pipeline, provided its name remains the same. This provides a convenient hook from which to add custom processing and transformations for your data. @@ -272,9 +272,12 @@ extraction. These changes should be re-applied to each index's `@custom` pipeline in order to ensure a consistent data processing experience. In 8.5+, the <> is required *in addition* to the configurations mentioned in the {enterprise-search-ref}/crawler-managing.html#crawler-managing-binary-content[Elastic web crawler Guide]. -* `ent-search-generic-ingestion` - Since 8.5, Native Connectors, Connector Clients, and new (>8.4) Elastic web crawler indices will all make use of this pipeline by default. +* `ent-search-generic-ingestion` - Since 8.5, Native Connectors, Connector Clients, and new (>8.4) Elastic web crawler indices all made use of this pipeline by default. + This pipeline evolved into the `search-default-ingestion` pipeline. + +* `search-default-ingestion` - Since 9.0, Connectors have made use of this pipeline by default. You can <> above. - As this pipeline is "managed", any modifications that were made to `app_search_crawler` and/or `ent_search_crawler` should NOT be made to `ent-search-generic-ingestion`. + As this pipeline is "managed", any modifications that were made to `app_search_crawler` and/or `ent_search_crawler` should NOT be made to `search-default-ingestion`. Instead, if such customizations are desired, you should utilize <>, placing all modifications in the `@custom` pipeline(s). ============= diff --git a/docs/reference/ingest/search-nlp-tutorial.asciidoc b/docs/reference/ingest/search-nlp-tutorial.asciidoc index afdceeeb8bac2..b23a15c96b1a2 100644 --- a/docs/reference/ingest/search-nlp-tutorial.asciidoc +++ b/docs/reference/ingest/search-nlp-tutorial.asciidoc @@ -164,8 +164,8 @@ Now it's time to create an inference pipeline. 1. From the overview page for your `search-photo-comments` index in "Search", click the *Pipelines* tab. By default, Elasticsearch does not create any index-specific ingest pipelines. -2. Because we want to customize these pipelines, we need to *Copy and customize* the `ent-search-generic-ingestion` ingest pipeline. -Find this option above the settings for the `ent-search-generic-ingestion` ingest pipeline. +2. Because we want to customize these pipelines, we need to *Copy and customize* the `search-default-ingestion` ingest pipeline. +Find this option above the settings for the `search-default-ingestion` ingest pipeline. This will create two new index-specific ingest pipelines. Next, we'll add an inference pipeline. diff --git a/x-pack/plugin/core/template-resources/src/main/resources/entsearch/connector/elastic-connectors-mappings.json b/x-pack/plugin/core/template-resources/src/main/resources/entsearch/connector/elastic-connectors-mappings.json index 651e1c84da73a..5afa557e1405e 100644 --- a/x-pack/plugin/core/template-resources/src/main/resources/entsearch/connector/elastic-connectors-mappings.json +++ b/x-pack/plugin/core/template-resources/src/main/resources/entsearch/connector/elastic-connectors-mappings.json @@ -7,7 +7,7 @@ "dynamic": "false", "_meta": { "pipeline": { - "default_name": "ent-search-generic-ingestion", + "default_name": "search-default-ingestion", "default_extract_binary_content": true, "default_run_ml_inference": true, "default_reduce_whitespace": true diff --git a/x-pack/plugin/core/template-resources/src/main/resources/entsearch/generic_ingestion_pipeline.json b/x-pack/plugin/core/template-resources/src/main/resources/entsearch/generic_ingestion_pipeline.json deleted file mode 100644 index e2a2cbd460117..0000000000000 --- a/x-pack/plugin/core/template-resources/src/main/resources/entsearch/generic_ingestion_pipeline.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "version": ${xpack.application.connector.template.version}, - "description": "Generic Enterprise Search ingest pipeline", - "_meta": { - "managed_by": "Enterprise Search", - "managed": true - }, - "processors": [ - { - "attachment": { - "description": "Extract text from binary attachments", - "field": "_attachment", - "target_field": "_extracted_attachment", - "ignore_missing": true, - "indexed_chars_field": "_attachment_indexed_chars", - "if": "ctx?._extract_binary_content == true", - "on_failure": [ - { - "append": { - "description": "Record error information", - "field": "_ingestion_errors", - "value": "Processor 'attachment' in pipeline '{{ _ingest.on_failure_pipeline }}' failed with message '{{ _ingest.on_failure_message }}'" - } - } - ], - "remove_binary": false - } - }, - { - "set": { - "tag": "set_body", - "description": "Set any extracted text on the 'body' field", - "field": "body", - "copy_from": "_extracted_attachment.content", - "ignore_empty_value": true, - "if": "ctx?._extract_binary_content == true", - "on_failure": [ - { - "append": { - "description": "Record error information", - "field": "_ingestion_errors", - "value": "Processor 'set' with tag 'set_body' in pipeline '{{ _ingest.on_failure_pipeline }}' failed with message '{{ _ingest.on_failure_message }}'" - } - } - ] - } - }, - { - "gsub": { - "tag": "remove_replacement_chars", - "description": "Remove unicode 'replacement' characters", - "field": "body", - "pattern": "�", - "replacement": "", - "ignore_missing": true, - "if": "ctx?._extract_binary_content == true", - "on_failure": [ - { - "append": { - "description": "Record error information", - "field": "_ingestion_errors", - "value": "Processor 'gsub' with tag 'remove_replacement_chars' in pipeline '{{ _ingest.on_failure_pipeline }}' failed with message '{{ _ingest.on_failure_message }}'" - } - } - ] - } - }, - { - "gsub": { - "tag": "remove_extra_whitespace", - "description": "Squish whitespace", - "field": "body", - "pattern": "\\s+", - "replacement": " ", - "ignore_missing": true, - "if": "ctx?._reduce_whitespace == true", - "on_failure": [ - { - "append": { - "description": "Record error information", - "field": "_ingestion_errors", - "value": "Processor 'gsub' with tag 'remove_extra_whitespace' in pipeline '{{ _ingest.on_failure_pipeline }}' failed with message '{{ _ingest.on_failure_message }}'" - } - } - ] - } - }, - { - "trim" : { - "description": "Trim leading and trailing whitespace", - "field": "body", - "ignore_missing": true, - "if": "ctx?._reduce_whitespace == true", - "on_failure": [ - { - "append": { - "description": "Record error information", - "field": "_ingestion_errors", - "value": "Processor 'trim' in pipeline '{{ _ingest.on_failure_pipeline }}' failed with message '{{ _ingest.on_failure_message }}'" - } - } - ] - } - }, - { - "remove": { - "tag": "remove_meta_fields", - "description": "Remove meta fields", - "field": [ - "_attachment", - "_attachment_indexed_chars", - "_extracted_attachment", - "_extract_binary_content", - "_reduce_whitespace", - "_run_ml_inference" - ], - "ignore_missing": true, - "on_failure": [ - { - "append": { - "description": "Record error information", - "field": "_ingestion_errors", - "value": "Processor 'remove' with tag 'remove_meta_fields' in pipeline '{{ _ingest.on_failure_pipeline }}' failed with message '{{ _ingest.on_failure_message }}'" - } - } - ] - } - } - ] -} diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistry.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistry.java index e630f929bc09b..fd35acc89db5c 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistry.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistry.java @@ -48,10 +48,6 @@ public class ConnectorTemplateRegistry extends IndexTemplateRegistry { public static final String MANAGED_CONNECTOR_INDEX_PREFIX = "content-"; // Pipeline constants - - public static final String ENT_SEARCH_GENERIC_PIPELINE_NAME = "ent-search-generic-ingestion"; - public static final String ENT_SEARCH_GENERIC_PIPELINE_FILE = "generic_ingestion_pipeline"; - public static final String SEARCH_DEFAULT_PIPELINE_NAME = "search-default-ingestion"; public static final String SEARCH_DEFAULT_PIPELINE_FILE = "search_default_pipeline"; @@ -111,12 +107,6 @@ public class ConnectorTemplateRegistry extends IndexTemplateRegistry { @Override protected List getIngestPipelines() { return List.of( - new JsonIngestPipelineConfig( - ENT_SEARCH_GENERIC_PIPELINE_NAME, - ROOT_RESOURCE_PATH + ENT_SEARCH_GENERIC_PIPELINE_FILE + ".json", - REGISTRY_VERSION, - TEMPLATE_VERSION_VARIABLE - ), new JsonIngestPipelineConfig( SEARCH_DEFAULT_PIPELINE_NAME, ROOT_RESOURCE_PATH + SEARCH_DEFAULT_PIPELINE_FILE + ".json", diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIngestPipelineTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIngestPipelineTests.java index f4a92e51e8c6a..c3d4bf8b72ff5 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIngestPipelineTests.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorIngestPipelineTests.java @@ -50,7 +50,7 @@ public void testToXContent() throws IOException { String content = XContentHelper.stripWhitespace(""" { "extract_binary_content": true, - "name": "ent-search-generic-ingestion", + "name": "search-default-ingestion", "reduce_whitespace": true, "run_ml_inference": false } diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistryTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistryTests.java index a4c7015afafcb..068b99626af9d 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistryTests.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTemplateRegistryTests.java @@ -132,10 +132,7 @@ public void testThatNonExistingComponentTemplatesAreAddedImmediately() throws Ex ClusterChangedEvent event = createClusterChangedEvent( Collections.emptyMap(), Collections.emptyMap(), - Collections.singletonMap( - ConnectorTemplateRegistry.ENT_SEARCH_GENERIC_PIPELINE_NAME, - ConnectorTemplateRegistry.REGISTRY_VERSION - ), + Collections.singletonMap(ConnectorTemplateRegistry.SEARCH_DEFAULT_PIPELINE_NAME, ConnectorTemplateRegistry.REGISTRY_VERSION), Collections.emptyMap(), nodes ); @@ -169,10 +166,7 @@ public void testThatVersionedOldComponentTemplatesAreUpgraded() throws Exception ConnectorTemplateRegistry.CONNECTOR_TEMPLATE_NAME + "-settings", ConnectorTemplateRegistry.REGISTRY_VERSION - 1 ), - Collections.singletonMap( - ConnectorTemplateRegistry.ENT_SEARCH_GENERIC_PIPELINE_NAME, - ConnectorTemplateRegistry.REGISTRY_VERSION - ), + Collections.singletonMap(ConnectorTemplateRegistry.SEARCH_DEFAULT_PIPELINE_NAME, ConnectorTemplateRegistry.REGISTRY_VERSION), Collections.emptyMap(), nodes ); @@ -189,10 +183,7 @@ public void testThatUnversionedOldComponentTemplatesAreUpgraded() throws Excepti ClusterChangedEvent event = createClusterChangedEvent( Collections.emptyMap(), Collections.singletonMap(ConnectorTemplateRegistry.CONNECTOR_TEMPLATE_NAME + "-mappings", null), - Collections.singletonMap( - ConnectorTemplateRegistry.ENT_SEARCH_GENERIC_PIPELINE_NAME, - ConnectorTemplateRegistry.REGISTRY_VERSION - ), + Collections.singletonMap(ConnectorTemplateRegistry.SEARCH_DEFAULT_PIPELINE_NAME, ConnectorTemplateRegistry.REGISTRY_VERSION), Collections.emptyMap(), nodes ); diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTests.java index 734c6eaf86965..bcb647d978abb 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTests.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/ConnectorTests.java @@ -225,7 +225,7 @@ public void testToXContent() throws IOException { "name":"test-name", "pipeline":{ "extract_binary_content":true, - "name":"ent-search-generic-ingestion", + "name":"search-default-ingestion", "reduce_whitespace":true, "run_ml_inference":false }, @@ -286,7 +286,7 @@ public void testToContent_WithNullValues() throws IOException { "name": null, "pipeline":{ "extract_binary_content":true, - "name":"ent-search-generic-ingestion", + "name":"search-default-ingestion", "reduce_whitespace":true, "run_ml_inference":false }, @@ -350,7 +350,7 @@ public void testToXContent_withOptionalFieldsMissing() throws IOException { "name": null, "pipeline":{ "extract_binary_content":true, - "name":"ent-search-generic-ingestion", + "name":"search-default-ingestion", "reduce_whitespace":true, "run_ml_inference":false }, diff --git a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobTests.java b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobTests.java index 81b05ce25e177..ed3338c715bdf 100644 --- a/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobTests.java +++ b/x-pack/plugin/ent-search/src/test/java/org/elasticsearch/xpack/application/connector/syncjob/ConnectorSyncJobTests.java @@ -77,7 +77,7 @@ public void testFromXContent_WithAllFields_AllSet() throws IOException { "language": "english", "pipeline": { "extract_binary_content": true, - "name": "ent-search-generic-ingestion", + "name": "search-default-ingestion", "reduce_whitespace": true, "run_ml_inference": false }, @@ -160,7 +160,7 @@ public void testFromXContent_WithOnlyNonNullableFieldsSet_DoesNotThrow() throws "language": "english", "pipeline": { "extract_binary_content": true, - "name": "ent-search-generic-ingestion", + "name": "search-default-ingestion", "reduce_whitespace": true, "run_ml_inference": false }, @@ -218,7 +218,7 @@ public void testFromXContent_WithAllNullableFieldsSetToNull_DoesNotThrow() throw "language": "english", "pipeline": { "extract_binary_content": true, - "name": "ent-search-generic-ingestion", + "name": "search-default-ingestion", "reduce_whitespace": true, "run_ml_inference": false }, @@ -275,7 +275,7 @@ public void testSyncJobConnectorFromXContent_WithAllFieldsSet() throws IOExcepti "language": "english", "pipeline": { "extract_binary_content": true, - "name": "ent-search-generic-ingestion", + "name": "search-default-ingestion", "reduce_whitespace": true, "run_ml_inference": false }, From a2360d18b434b89f0aae9dbc264a16a5e75d1475 Mon Sep 17 00:00:00 2001 From: elasticsearchmachine <58790826+elasticsearchmachine@users.noreply.github.com> Date: Thu, 19 Dec 2024 01:20:54 +1100 Subject: [PATCH 46/60] Mute org.elasticsearch.xpack.migrate.task.ReindexDataStreamStatusTests testEqualsAndHashcode #118965 --- muted-tests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/muted-tests.yml b/muted-tests.yml index 3a8594acf3bb1..b35a70391f195 100644 --- a/muted-tests.yml +++ b/muted-tests.yml @@ -292,6 +292,9 @@ tests: issue: https://github.com/elastic/elasticsearch/issues/118914 - class: org.elasticsearch.smoketest.SmokeTestMultiNodeClientYamlTestSuiteIT issue: https://github.com/elastic/elasticsearch/issues/118955 +- class: org.elasticsearch.xpack.migrate.task.ReindexDataStreamStatusTests + method: testEqualsAndHashcode + issue: https://github.com/elastic/elasticsearch/issues/118965 # Examples: # From 97bc2919ffb5d9e90f809a18233c49a52cf58faa Mon Sep 17 00:00:00 2001 From: Matteo Piergiovanni <134913285+piergm@users.noreply.github.com> Date: Wed, 18 Dec 2024 15:29:35 +0100 Subject: [PATCH 47/60] Prevent data nodes from sending stack traces to coordinator when `error_trace=false` (#118266) * first iterations * added tests * Update docs/changelog/118266.yaml * constant for error_trace and typos * centralized putHeader * moved threadContext to parent class * uses NodeClient.threadpool * updated async tests to retrieve final result * moved test to avoid starting up a node * added transport version to avoid sending useless bytes * more async tests --- docs/changelog/118266.yaml | 5 + .../bucket/SearchCancellationIT.java | 2 + .../http/SearchErrorTraceIT.java | 175 ++++++++++++++ .../org/elasticsearch/TransportVersions.java | 1 + .../action/search/SearchTransportService.java | 6 +- .../common/util/concurrent/ThreadContext.java | 21 ++ .../elasticsearch/rest/BaseRestHandler.java | 1 - .../elasticsearch/rest/RestController.java | 3 +- .../org/elasticsearch/rest/RestResponse.java | 3 +- .../action/search/RestMultiSearchAction.java | 3 + .../rest/action/search/RestSearchAction.java | 4 +- .../elasticsearch/search/SearchService.java | 56 ++++- .../elasticsearch/rest/RestResponseTests.java | 3 +- .../search/SearchServiceSingleNodeTests.java | 3 +- .../search/SearchServiceTests.java | 34 +++ .../xpack/search/AsyncSearchErrorTraceIT.java | 222 ++++++++++++++++++ .../search/RestSubmitAsyncSearchAction.java | 3 + .../ServerSentEventsRestActionListener.java | 3 +- 18 files changed, 535 insertions(+), 13 deletions(-) create mode 100644 docs/changelog/118266.yaml create mode 100644 qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/SearchErrorTraceIT.java create mode 100644 x-pack/plugin/async-search/src/internalClusterTest/java/org/elasticsearch/xpack/search/AsyncSearchErrorTraceIT.java diff --git a/docs/changelog/118266.yaml b/docs/changelog/118266.yaml new file mode 100644 index 0000000000000..1b14b12b973c5 --- /dev/null +++ b/docs/changelog/118266.yaml @@ -0,0 +1,5 @@ +pr: 118266 +summary: Prevent data nodes from sending stack traces to coordinator when `error_trace=false` +area: Search +type: enhancement +issues: [] diff --git a/modules/aggregations/src/internalClusterTest/java/org/elasticsearch/aggregations/bucket/SearchCancellationIT.java b/modules/aggregations/src/internalClusterTest/java/org/elasticsearch/aggregations/bucket/SearchCancellationIT.java index 5249077bdfdbb..7adf6a09e9a19 100644 --- a/modules/aggregations/src/internalClusterTest/java/org/elasticsearch/aggregations/bucket/SearchCancellationIT.java +++ b/modules/aggregations/src/internalClusterTest/java/org/elasticsearch/aggregations/bucket/SearchCancellationIT.java @@ -96,6 +96,8 @@ public void testCancellationDuringTimeSeriesAggregation() throws Exception { } logger.info("Executing search"); + // we have to explicitly set error_trace=true for the later exception check for `TimeSeriesIndexSearcher` + client().threadPool().getThreadContext().putHeader("error_trace", "true"); TimeSeriesAggregationBuilder timeSeriesAggregationBuilder = new TimeSeriesAggregationBuilder("test_agg"); ActionFuture searchResponse = prepareSearch("test").setQuery(matchAllQuery()) .addAggregation( diff --git a/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/SearchErrorTraceIT.java b/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/SearchErrorTraceIT.java new file mode 100644 index 0000000000000..6f9ab8ccdfdec --- /dev/null +++ b/qa/smoke-test-http/src/javaRestTest/java/org/elasticsearch/http/SearchErrorTraceIT.java @@ -0,0 +1,175 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +package org.elasticsearch.http; + +import org.apache.http.entity.ContentType; +import org.apache.http.nio.entity.NByteArrayEntity; +import org.elasticsearch.ExceptionsHelper; +import org.elasticsearch.action.search.MultiSearchRequest; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.client.Request; +import org.elasticsearch.search.builder.SearchSourceBuilder; +import org.elasticsearch.transport.TransportMessageListener; +import org.elasticsearch.transport.TransportService; +import org.elasticsearch.xcontent.XContentType; +import org.junit.Before; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.elasticsearch.index.query.QueryBuilders.simpleQueryStringQuery; + +public class SearchErrorTraceIT extends HttpSmokeTestCase { + private AtomicBoolean hasStackTrace; + + @Before + private void setupMessageListener() { + internalCluster().getDataNodeInstances(TransportService.class).forEach(ts -> { + ts.addMessageListener(new TransportMessageListener() { + @Override + public void onResponseSent(long requestId, String action, Exception error) { + TransportMessageListener.super.onResponseSent(requestId, action, error); + if (action.startsWith("indices:data/read/search")) { + Optional throwable = ExceptionsHelper.unwrapCausesAndSuppressed( + error, + t -> t.getStackTrace().length > 0 + ); + hasStackTrace.set(throwable.isPresent()); + } + } + }); + }); + } + + private void setupIndexWithDocs() { + createIndex("test1", "test2"); + indexRandom( + true, + prepareIndex("test1").setId("1").setSource("field", "foo"), + prepareIndex("test2").setId("10").setSource("field", 5) + ); + refresh(); + } + + public void testSearchFailingQueryErrorTraceDefault() throws IOException { + hasStackTrace = new AtomicBoolean(); + setupIndexWithDocs(); + + Request searchRequest = new Request("POST", "/_search"); + searchRequest.setJsonEntity(""" + { + "query": { + "simple_query_string" : { + "query": "foo", + "fields": ["field"] + } + } + } + """); + getRestClient().performRequest(searchRequest); + assertFalse(hasStackTrace.get()); + } + + public void testSearchFailingQueryErrorTraceTrue() throws IOException { + hasStackTrace = new AtomicBoolean(); + setupIndexWithDocs(); + + Request searchRequest = new Request("POST", "/_search"); + searchRequest.setJsonEntity(""" + { + "query": { + "simple_query_string" : { + "query": "foo", + "fields": ["field"] + } + } + } + """); + searchRequest.addParameter("error_trace", "true"); + getRestClient().performRequest(searchRequest); + assertTrue(hasStackTrace.get()); + } + + public void testSearchFailingQueryErrorTraceFalse() throws IOException { + hasStackTrace = new AtomicBoolean(); + setupIndexWithDocs(); + + Request searchRequest = new Request("POST", "/_search"); + searchRequest.setJsonEntity(""" + { + "query": { + "simple_query_string" : { + "query": "foo", + "fields": ["field"] + } + } + } + """); + searchRequest.addParameter("error_trace", "false"); + getRestClient().performRequest(searchRequest); + assertFalse(hasStackTrace.get()); + } + + public void testMultiSearchFailingQueryErrorTraceDefault() throws IOException { + hasStackTrace = new AtomicBoolean(); + setupIndexWithDocs(); + + XContentType contentType = XContentType.JSON; + MultiSearchRequest multiSearchRequest = new MultiSearchRequest().add( + new SearchRequest("test*").source(new SearchSourceBuilder().query(simpleQueryStringQuery("foo").field("field"))) + ); + Request searchRequest = new Request("POST", "/_msearch"); + byte[] requestBody = MultiSearchRequest.writeMultiLineFormat(multiSearchRequest, contentType.xContent()); + searchRequest.setEntity( + new NByteArrayEntity(requestBody, ContentType.create(contentType.mediaTypeWithoutParameters(), (Charset) null)) + ); + getRestClient().performRequest(searchRequest); + assertFalse(hasStackTrace.get()); + } + + public void testMultiSearchFailingQueryErrorTraceTrue() throws IOException { + hasStackTrace = new AtomicBoolean(); + setupIndexWithDocs(); + + XContentType contentType = XContentType.JSON; + MultiSearchRequest multiSearchRequest = new MultiSearchRequest().add( + new SearchRequest("test*").source(new SearchSourceBuilder().query(simpleQueryStringQuery("foo").field("field"))) + ); + Request searchRequest = new Request("POST", "/_msearch"); + byte[] requestBody = MultiSearchRequest.writeMultiLineFormat(multiSearchRequest, contentType.xContent()); + searchRequest.setEntity( + new NByteArrayEntity(requestBody, ContentType.create(contentType.mediaTypeWithoutParameters(), (Charset) null)) + ); + searchRequest.addParameter("error_trace", "true"); + getRestClient().performRequest(searchRequest); + assertTrue(hasStackTrace.get()); + } + + public void testMultiSearchFailingQueryErrorTraceFalse() throws IOException { + hasStackTrace = new AtomicBoolean(); + setupIndexWithDocs(); + + XContentType contentType = XContentType.JSON; + MultiSearchRequest multiSearchRequest = new MultiSearchRequest().add( + new SearchRequest("test*").source(new SearchSourceBuilder().query(simpleQueryStringQuery("foo").field("field"))) + ); + Request searchRequest = new Request("POST", "/_msearch"); + byte[] requestBody = MultiSearchRequest.writeMultiLineFormat(multiSearchRequest, contentType.xContent()); + searchRequest.setEntity( + new NByteArrayEntity(requestBody, ContentType.create(contentType.mediaTypeWithoutParameters(), (Charset) null)) + ); + searchRequest.addParameter("error_trace", "false"); + getRestClient().performRequest(searchRequest); + + assertFalse(hasStackTrace.get()); + } +} diff --git a/server/src/main/java/org/elasticsearch/TransportVersions.java b/server/src/main/java/org/elasticsearch/TransportVersions.java index d3e235f1cd82a..bda66d6a2c8cd 100644 --- a/server/src/main/java/org/elasticsearch/TransportVersions.java +++ b/server/src/main/java/org/elasticsearch/TransportVersions.java @@ -140,6 +140,7 @@ static TransportVersion def(int id) { public static final TransportVersion ESQL_QUERY_BUILDER_IN_SEARCH_FUNCTIONS = def(8_808_00_0); public static final TransportVersion EQL_ALLOW_PARTIAL_SEARCH_RESULTS = def(8_809_00_0); public static final TransportVersion NODE_VERSION_INFORMATION_WITH_MIN_READ_ONLY_INDEX_VERSION = def(8_810_00_0); + public static final TransportVersion ERROR_TRACE_IN_TRANSPORT_HEADER = def(8_811_00_0); /* * STOP! READ THIS FIRST! No, really, diff --git a/server/src/main/java/org/elasticsearch/action/search/SearchTransportService.java b/server/src/main/java/org/elasticsearch/action/search/SearchTransportService.java index cfc2e1bcdaf2b..2041754bc2bcc 100644 --- a/server/src/main/java/org/elasticsearch/action/search/SearchTransportService.java +++ b/server/src/main/java/org/elasticsearch/action/search/SearchTransportService.java @@ -456,7 +456,8 @@ public static void registerRequestHandler(TransportService transportService, Sea (request, channel, task) -> searchService.executeQueryPhase( request, (SearchShardTask) task, - new ChannelActionListener<>(channel) + new ChannelActionListener<>(channel), + channel.getVersion() ) ); TransportActionProxy.registerProxyAction(transportService, QUERY_ID_ACTION_NAME, true, QuerySearchResult::new); @@ -468,7 +469,8 @@ public static void registerRequestHandler(TransportService transportService, Sea (request, channel, task) -> searchService.executeQueryPhase( request, (SearchShardTask) task, - new ChannelActionListener<>(channel) + new ChannelActionListener<>(channel), + channel.getVersion() ) ); TransportActionProxy.registerProxyAction(transportService, QUERY_SCROLL_ACTION_NAME, true, ScrollQuerySearchResult::new); diff --git a/server/src/main/java/org/elasticsearch/common/util/concurrent/ThreadContext.java b/server/src/main/java/org/elasticsearch/common/util/concurrent/ThreadContext.java index a9e13b86a5159..6841cb5bead0a 100644 --- a/server/src/main/java/org/elasticsearch/common/util/concurrent/ThreadContext.java +++ b/server/src/main/java/org/elasticsearch/common/util/concurrent/ThreadContext.java @@ -24,6 +24,8 @@ import org.elasticsearch.core.Releasable; import org.elasticsearch.core.Tuple; import org.elasticsearch.http.HttpTransportSettings; +import org.elasticsearch.rest.RestController; +import org.elasticsearch.rest.RestRequest; import org.elasticsearch.tasks.Task; import org.elasticsearch.telemetry.tracing.TraceContext; @@ -530,6 +532,17 @@ public String getHeader(String key) { return value; } + /** + * Returns the header for the given key or defaultValue if not present + */ + public String getHeaderOrDefault(String key, String defaultValue) { + String value = getHeader(key); + if (value == null) { + return defaultValue; + } + return value; + } + /** * Returns all of the request headers from the thread's context.
    * Be advised, headers might contain credentials. @@ -589,6 +602,14 @@ public void putHeader(Map header) { threadLocal.set(threadLocal.get().putHeaders(header)); } + public void setErrorTraceTransportHeader(RestRequest r) { + // set whether data nodes should send back stack trace based on the `error_trace` query parameter + if (r.paramAsBoolean("error_trace", RestController.ERROR_TRACE_DEFAULT)) { + // We only set it if error_trace is true (defaults to false) to avoid sending useless bytes + putHeader("error_trace", "true"); + } + } + /** * Puts a transient header object into this context */ diff --git a/server/src/main/java/org/elasticsearch/rest/BaseRestHandler.java b/server/src/main/java/org/elasticsearch/rest/BaseRestHandler.java index 4564a37dacf4a..509086b982319 100644 --- a/server/src/main/java/org/elasticsearch/rest/BaseRestHandler.java +++ b/server/src/main/java/org/elasticsearch/rest/BaseRestHandler.java @@ -269,5 +269,4 @@ protected Set responseParams() { protected Set responseParams(RestApiVersion restApiVersion) { return responseParams(); } - } diff --git a/server/src/main/java/org/elasticsearch/rest/RestController.java b/server/src/main/java/org/elasticsearch/rest/RestController.java index 49fe794bbe615..49801499ea991 100644 --- a/server/src/main/java/org/elasticsearch/rest/RestController.java +++ b/server/src/main/java/org/elasticsearch/rest/RestController.java @@ -93,6 +93,7 @@ public class RestController implements HttpServerTransport.Dispatcher { public static final String STATUS_CODE_KEY = "es_rest_status_code"; public static final String HANDLER_NAME_KEY = "es_rest_handler_name"; public static final String REQUEST_METHOD_KEY = "es_rest_request_method"; + public static final boolean ERROR_TRACE_DEFAULT = false; static { try (InputStream stream = RestController.class.getResourceAsStream("/config/favicon.ico")) { @@ -638,7 +639,7 @@ private void tryAllHandlers(final RestRequest request, final RestChannel channel private static void validateErrorTrace(RestRequest request, RestChannel channel) { // error_trace cannot be used when we disable detailed errors // we consume the error_trace parameter first to ensure that it is always consumed - if (request.paramAsBoolean("error_trace", false) && channel.detailedErrorsEnabled() == false) { + if (request.paramAsBoolean("error_trace", ERROR_TRACE_DEFAULT) && channel.detailedErrorsEnabled() == false) { throw new IllegalArgumentException("error traces in responses are disabled."); } } diff --git a/server/src/main/java/org/elasticsearch/rest/RestResponse.java b/server/src/main/java/org/elasticsearch/rest/RestResponse.java index d043974055667..0c359e0a4a053 100644 --- a/server/src/main/java/org/elasticsearch/rest/RestResponse.java +++ b/server/src/main/java/org/elasticsearch/rest/RestResponse.java @@ -37,6 +37,7 @@ import static java.util.Collections.singletonMap; import static org.elasticsearch.ElasticsearchException.REST_EXCEPTION_SKIP_STACK_TRACE; import static org.elasticsearch.rest.RestController.ELASTIC_PRODUCT_HTTP_HEADER; +import static org.elasticsearch.rest.RestController.ERROR_TRACE_DEFAULT; public final class RestResponse implements Releasable { @@ -143,7 +144,7 @@ public RestResponse(RestChannel channel, RestStatus status, Exception e) throws // switched in the xcontent rendering parameters. // For authorization problems (RestStatus.UNAUTHORIZED) we don't want to do this since this could // leak information to the caller who is unauthorized to make this call - if (params.paramAsBoolean("error_trace", false) && status != RestStatus.UNAUTHORIZED) { + if (params.paramAsBoolean("error_trace", ERROR_TRACE_DEFAULT) && status != RestStatus.UNAUTHORIZED) { params = new ToXContent.DelegatingMapParams(singletonMap(REST_EXCEPTION_SKIP_STACK_TRACE, "false"), params); } diff --git a/server/src/main/java/org/elasticsearch/rest/action/search/RestMultiSearchAction.java b/server/src/main/java/org/elasticsearch/rest/action/search/RestMultiSearchAction.java index 24fab92ced392..87b1a6b9c2fa8 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/search/RestMultiSearchAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/search/RestMultiSearchAction.java @@ -72,6 +72,9 @@ public String getName() { @Override public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException { + if (client.threadPool() != null && client.threadPool().getThreadContext() != null) { + client.threadPool().getThreadContext().setErrorTraceTransportHeader(request); + } final MultiSearchRequest multiSearchRequest = parseRequest(request, allowExplicitIndex, searchUsageHolder, clusterSupportsFeature); return channel -> { final RestCancellableNodeClient cancellableClient = new RestCancellableNodeClient(client, request.getHttpChannel()); diff --git a/server/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java b/server/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java index a9c2ff7576b05..99c11bb60b8f0 100644 --- a/server/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java +++ b/server/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java @@ -95,7 +95,9 @@ public Set supportedCapabilities() { @Override public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException { - + if (client.threadPool() != null && client.threadPool().getThreadContext() != null) { + client.threadPool().getThreadContext().setErrorTraceTransportHeader(request); + } SearchRequest searchRequest = new SearchRequest(); // access the BwC param, but just drop it // this might be set by old clients diff --git a/server/src/main/java/org/elasticsearch/search/SearchService.java b/server/src/main/java/org/elasticsearch/search/SearchService.java index b9bd398500c71..4557ccb3d2220 100644 --- a/server/src/main/java/org/elasticsearch/search/SearchService.java +++ b/server/src/main/java/org/elasticsearch/search/SearchService.java @@ -17,6 +17,8 @@ import org.apache.lucene.search.Query; import org.apache.lucene.search.TopDocs; import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.ExceptionsHelper; +import org.elasticsearch.TransportVersion; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.ActionRunnable; import org.elasticsearch.action.ResolvedIndices; @@ -152,6 +154,7 @@ import java.util.function.LongSupplier; import java.util.function.Supplier; +import static org.elasticsearch.TransportVersions.ERROR_TRACE_IN_TRANSPORT_HEADER; import static org.elasticsearch.core.TimeValue.timeValueHours; import static org.elasticsearch.core.TimeValue.timeValueMillis; import static org.elasticsearch.core.TimeValue.timeValueMinutes; @@ -272,6 +275,7 @@ public class SearchService extends AbstractLifecycleComponent implements IndexEv public static final int DEFAULT_SIZE = 10; public static final int DEFAULT_FROM = 0; + private static final StackTraceElement[] EMPTY_STACK_TRACE_ARRAY = new StackTraceElement[0]; private final ThreadPool threadPool; @@ -506,7 +510,41 @@ protected void doClose() { keepAliveReaper.cancel(); } + /** + * Wraps the listener to avoid sending StackTraces back to the coordinating + * node if the `error_trace` header is set to {@code false}. Upon reading we + * default to {@code true} to maintain the same behavior as before the change, + * due to older nodes not being able to specify whether it needs stack traces. + * + * @param the type of the response + * @param listener the action listener to be wrapped + * @param version channel version of the request + * @param threadPool with context where to write the new header + * @return the wrapped action listener + */ + static ActionListener maybeWrapListenerForStackTrace( + ActionListener listener, + TransportVersion version, + ThreadPool threadPool + ) { + boolean header = true; + if (version.onOrAfter(ERROR_TRACE_IN_TRANSPORT_HEADER) && threadPool.getThreadContext() != null) { + header = Boolean.parseBoolean(threadPool.getThreadContext().getHeaderOrDefault("error_trace", "false")); + } + if (header == false) { + return listener.delegateResponse((l, e) -> { + ExceptionsHelper.unwrapCausesAndSuppressed(e, err -> { + err.setStackTrace(EMPTY_STACK_TRACE_ARRAY); + return false; + }); + l.onFailure(e); + }); + } + return listener; + } + public void executeDfsPhase(ShardSearchRequest request, SearchShardTask task, ActionListener listener) { + listener = maybeWrapListenerForStackTrace(listener, request.getChannelVersion(), threadPool); final IndexShard shard = getShard(request); rewriteAndFetchShardRequest(shard, request, listener.delegateFailure((l, rewritten) -> { // fork the execution in the search thread pool @@ -544,10 +582,11 @@ private void loadOrExecuteQueryPhase(final ShardSearchRequest request, final Sea } public void executeQueryPhase(ShardSearchRequest request, SearchShardTask task, ActionListener listener) { + ActionListener finalListener = maybeWrapListenerForStackTrace(listener, request.getChannelVersion(), threadPool); assert request.canReturnNullResponseIfMatchNoDocs() == false || request.numberOfShards() > 1 : "empty responses require more than one shard"; final IndexShard shard = getShard(request); - rewriteAndFetchShardRequest(shard, request, listener.delegateFailure((l, orig) -> { + rewriteAndFetchShardRequest(shard, request, finalListener.delegateFailure((l, orig) -> { // check if we can shortcut the query phase entirely. if (orig.canReturnNullResponseIfMatchNoDocs()) { assert orig.scroll() == null; @@ -561,7 +600,7 @@ public void executeQueryPhase(ShardSearchRequest request, SearchShardTask task, ); CanMatchShardResponse canMatchResp = canMatch(canMatchContext, false); if (canMatchResp.canMatch() == false) { - listener.onResponse(QuerySearchResult.nullInstance()); + finalListener.onResponse(QuerySearchResult.nullInstance()); return; } } @@ -736,6 +775,7 @@ private SearchPhaseResult executeQueryPhase(ShardSearchRequest request, SearchSh } public void executeRankFeaturePhase(RankFeatureShardRequest request, SearchShardTask task, ActionListener listener) { + listener = maybeWrapListenerForStackTrace(listener, request.getShardSearchRequest().getChannelVersion(), threadPool); final ReaderContext readerContext = findReaderContext(request.contextId(), request); final ShardSearchRequest shardSearchRequest = readerContext.getShardSearchRequest(request.getShardSearchRequest()); final Releasable markAsUsed = readerContext.markAsUsed(getKeepAlive(shardSearchRequest)); @@ -779,8 +819,10 @@ private QueryFetchSearchResult executeFetchPhase(ReaderContext reader, SearchCon public void executeQueryPhase( InternalScrollSearchRequest request, SearchShardTask task, - ActionListener listener + ActionListener listener, + TransportVersion version ) { + listener = maybeWrapListenerForStackTrace(listener, version, threadPool); final LegacyReaderContext readerContext = (LegacyReaderContext) findReaderContext(request.contextId(), request); final Releasable markAsUsed; try { @@ -816,7 +858,13 @@ public void executeQueryPhase( * It is the responsibility of the caller to ensure that the ref count is correctly decremented * when the object is no longer needed. */ - public void executeQueryPhase(QuerySearchRequest request, SearchShardTask task, ActionListener listener) { + public void executeQueryPhase( + QuerySearchRequest request, + SearchShardTask task, + ActionListener listener, + TransportVersion version + ) { + listener = maybeWrapListenerForStackTrace(listener, version, threadPool); final ReaderContext readerContext = findReaderContext(request.contextId(), request.shardSearchRequest()); final ShardSearchRequest shardSearchRequest = readerContext.getShardSearchRequest(request.shardSearchRequest()); final Releasable markAsUsed = readerContext.markAsUsed(getKeepAlive(shardSearchRequest)); diff --git a/server/src/test/java/org/elasticsearch/rest/RestResponseTests.java b/server/src/test/java/org/elasticsearch/rest/RestResponseTests.java index b85ad31288c8c..bd810cea216fc 100644 --- a/server/src/test/java/org/elasticsearch/rest/RestResponseTests.java +++ b/server/src/test/java/org/elasticsearch/rest/RestResponseTests.java @@ -51,6 +51,7 @@ import static org.elasticsearch.ElasticsearchException.REST_EXCEPTION_SKIP_STACK_TRACE; import static org.elasticsearch.ElasticsearchExceptionTests.assertDeepEquals; import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken; +import static org.elasticsearch.rest.RestController.ERROR_TRACE_DEFAULT; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; @@ -180,7 +181,7 @@ public void testStackTrace() throws IOException { } else { assertThat(response.status(), is(RestStatus.BAD_REQUEST)); } - boolean traceExists = request.paramAsBoolean("error_trace", false) && channel.detailedErrorsEnabled(); + boolean traceExists = request.paramAsBoolean("error_trace", ERROR_TRACE_DEFAULT) && channel.detailedErrorsEnabled(); if (traceExists) { assertThat(response.content().utf8ToString(), containsString(ElasticsearchException.STACK_TRACE)); } else { diff --git a/server/src/test/java/org/elasticsearch/search/SearchServiceSingleNodeTests.java b/server/src/test/java/org/elasticsearch/search/SearchServiceSingleNodeTests.java index 02593e41f5d84..0fc1694d39926 100644 --- a/server/src/test/java/org/elasticsearch/search/SearchServiceSingleNodeTests.java +++ b/server/src/test/java/org/elasticsearch/search/SearchServiceSingleNodeTests.java @@ -2684,7 +2684,8 @@ public void testDfsQueryPhaseRewrite() { service.executeQueryPhase( new QuerySearchRequest(null, context.id(), request, new AggregatedDfs(Map.of(), Map.of(), 10)), new SearchShardTask(42L, "", "", "", null, emptyMap()), - plainActionFuture + plainActionFuture, + TransportVersion.current() ); plainActionFuture.actionGet(); diff --git a/server/src/test/java/org/elasticsearch/search/SearchServiceTests.java b/server/src/test/java/org/elasticsearch/search/SearchServiceTests.java index 31bcab31ca8a7..d041121b8a96b 100644 --- a/server/src/test/java/org/elasticsearch/search/SearchServiceTests.java +++ b/server/src/test/java/org/elasticsearch/search/SearchServiceTests.java @@ -13,6 +13,8 @@ import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.SortField; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.TransportVersion; +import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.OriginalIndices; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.cluster.metadata.IndexMetadata; @@ -53,9 +55,14 @@ import java.io.IOException; import java.util.Collections; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.BiFunction; import java.util.function.Predicate; +import static org.elasticsearch.search.SearchService.maybeWrapListenerForStackTrace; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.not; + public class SearchServiceTests extends IndexShardTestCase { public void testCanMatchMatchAll() throws IOException { @@ -117,6 +124,33 @@ public Type getType() { doTestCanMatch(searchRequest, sortField, true, null, false); } + public void testMaybeWrapListenerForStackTrace() { + // Tests that the same listener has stack trace if is not wrapped or does not have stack trace if it is wrapped. + AtomicBoolean isWrapped = new AtomicBoolean(false); + ActionListener listener = new ActionListener<>() { + @Override + public void onResponse(SearchPhaseResult searchPhaseResult) { + // noop - we only care about failure scenarios + } + + @Override + public void onFailure(Exception e) { + if (isWrapped.get()) { + assertThat(e.getStackTrace().length, is(0)); + } else { + assertThat(e.getStackTrace().length, is(not(0))); + } + } + }; + Exception e = new Exception(); + e.fillInStackTrace(); + assertThat(e.getStackTrace().length, is(not(0))); + listener.onFailure(e); + listener = maybeWrapListenerForStackTrace(listener, TransportVersion.current(), threadPool); + isWrapped.set(true); + listener.onFailure(e); + } + private void doTestCanMatch( SearchRequest searchRequest, SortField sortField, diff --git a/x-pack/plugin/async-search/src/internalClusterTest/java/org/elasticsearch/xpack/search/AsyncSearchErrorTraceIT.java b/x-pack/plugin/async-search/src/internalClusterTest/java/org/elasticsearch/xpack/search/AsyncSearchErrorTraceIT.java new file mode 100644 index 0000000000000..39a6fa1e4b34f --- /dev/null +++ b/x-pack/plugin/async-search/src/internalClusterTest/java/org/elasticsearch/xpack/search/AsyncSearchErrorTraceIT.java @@ -0,0 +1,222 @@ +/* + * 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.search; + +import org.elasticsearch.ExceptionsHelper; +import org.elasticsearch.client.Request; +import org.elasticsearch.client.Response; +import org.elasticsearch.common.xcontent.XContentHelper; +import org.elasticsearch.core.TimeValue; +import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.test.ESIntegTestCase; +import org.elasticsearch.transport.TransportMessageListener; +import org.elasticsearch.transport.TransportService; +import org.elasticsearch.xcontent.XContentType; +import org.junit.Before; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicBoolean; + +public class AsyncSearchErrorTraceIT extends ESIntegTestCase { + + @Override + protected boolean addMockHttpTransport() { + return false; // enable http + } + + @Override + protected Collection> nodePlugins() { + return List.of(AsyncSearch.class); + } + + private AtomicBoolean transportMessageHasStackTrace; + + @Before + private void setupMessageListener() { + internalCluster().getDataNodeInstances(TransportService.class).forEach(ts -> { + ts.addMessageListener(new TransportMessageListener() { + @Override + public void onResponseSent(long requestId, String action, Exception error) { + TransportMessageListener.super.onResponseSent(requestId, action, error); + if (action.startsWith("indices:data/read/search")) { + Optional throwable = ExceptionsHelper.unwrapCausesAndSuppressed( + error, + t -> t.getStackTrace().length > 0 + ); + transportMessageHasStackTrace.set(throwable.isPresent()); + } + } + }); + }); + } + + private void setupIndexWithDocs() { + createIndex("test1", "test2"); + indexRandom( + true, + prepareIndex("test1").setId("1").setSource("field", "foo"), + prepareIndex("test2").setId("10").setSource("field", 5) + ); + refresh(); + } + + public void testAsyncSearchFailingQueryErrorTraceDefault() throws IOException, InterruptedException { + transportMessageHasStackTrace = new AtomicBoolean(); + setupIndexWithDocs(); + + Request searchRequest = new Request("POST", "/_async_search"); + searchRequest.setJsonEntity(""" + { + "query": { + "simple_query_string" : { + "query": "foo", + "fields": ["field"] + } + } + } + """); + searchRequest.addParameter("keep_on_completion", "true"); + searchRequest.addParameter("wait_for_completion_timeout", "0ms"); + Map responseEntity = performRequestAndGetResponseEntityAfterDelay(searchRequest, TimeValue.ZERO); + String asyncExecutionId = (String) responseEntity.get("id"); + Request request = new Request("GET", "/_async_search/" + asyncExecutionId); + while (responseEntity.get("is_running") instanceof Boolean isRunning && isRunning) { + responseEntity = performRequestAndGetResponseEntityAfterDelay(request, TimeValue.timeValueSeconds(1L)); + } + // check that the stack trace was not sent from the data node to the coordinating node + assertFalse(transportMessageHasStackTrace.get()); + } + + public void testAsyncSearchFailingQueryErrorTraceTrue() throws IOException, InterruptedException { + transportMessageHasStackTrace = new AtomicBoolean(); + setupIndexWithDocs(); + + Request searchRequest = new Request("POST", "/_async_search"); + searchRequest.setJsonEntity(""" + { + "query": { + "simple_query_string" : { + "query": "foo", + "fields": ["field"] + } + } + } + """); + searchRequest.addParameter("error_trace", "true"); + searchRequest.addParameter("keep_on_completion", "true"); + searchRequest.addParameter("wait_for_completion_timeout", "0ms"); + Map responseEntity = performRequestAndGetResponseEntityAfterDelay(searchRequest, TimeValue.ZERO); + String asyncExecutionId = (String) responseEntity.get("id"); + Request request = new Request("GET", "/_async_search/" + asyncExecutionId); + request.addParameter("error_trace", "true"); + while (responseEntity.get("is_running") instanceof Boolean isRunning && isRunning) { + responseEntity = performRequestAndGetResponseEntityAfterDelay(request, TimeValue.timeValueSeconds(1L)); + } + // check that the stack trace was sent from the data node to the coordinating node + assertTrue(transportMessageHasStackTrace.get()); + } + + public void testAsyncSearchFailingQueryErrorTraceFalse() throws IOException, InterruptedException { + transportMessageHasStackTrace = new AtomicBoolean(); + setupIndexWithDocs(); + + Request searchRequest = new Request("POST", "/_async_search"); + searchRequest.setJsonEntity(""" + { + "query": { + "simple_query_string" : { + "query": "foo", + "fields": ["field"] + } + } + } + """); + searchRequest.addParameter("error_trace", "false"); + searchRequest.addParameter("keep_on_completion", "true"); + searchRequest.addParameter("wait_for_completion_timeout", "0ms"); + Map responseEntity = performRequestAndGetResponseEntityAfterDelay(searchRequest, TimeValue.ZERO); + String asyncExecutionId = (String) responseEntity.get("id"); + Request request = new Request("GET", "/_async_search/" + asyncExecutionId); + request.addParameter("error_trace", "false"); + while (responseEntity.get("is_running") instanceof Boolean isRunning && isRunning) { + responseEntity = performRequestAndGetResponseEntityAfterDelay(request, TimeValue.timeValueSeconds(1L)); + } + // check that the stack trace was not sent from the data node to the coordinating node + assertFalse(transportMessageHasStackTrace.get()); + } + + public void testAsyncSearchFailingQueryErrorTraceFalseOnSubmitAndTrueOnGet() throws IOException, InterruptedException { + transportMessageHasStackTrace = new AtomicBoolean(); + setupIndexWithDocs(); + + Request searchRequest = new Request("POST", "/_async_search"); + searchRequest.setJsonEntity(""" + { + "query": { + "simple_query_string" : { + "query": "foo", + "fields": ["field"] + } + } + } + """); + searchRequest.addParameter("error_trace", "false"); + searchRequest.addParameter("keep_on_completion", "true"); + searchRequest.addParameter("wait_for_completion_timeout", "0ms"); + Map responseEntity = performRequestAndGetResponseEntityAfterDelay(searchRequest, TimeValue.ZERO); + String asyncExecutionId = (String) responseEntity.get("id"); + Request request = new Request("GET", "/_async_search/" + asyncExecutionId); + request.addParameter("error_trace", "true"); + while (responseEntity.get("is_running") instanceof Boolean isRunning && isRunning) { + responseEntity = performRequestAndGetResponseEntityAfterDelay(request, TimeValue.timeValueSeconds(1L)); + } + // check that the stack trace was not sent from the data node to the coordinating node + assertFalse(transportMessageHasStackTrace.get()); + } + + public void testAsyncSearchFailingQueryErrorTraceTrueOnSubmitAndFalseOnGet() throws IOException, InterruptedException { + transportMessageHasStackTrace = new AtomicBoolean(); + setupIndexWithDocs(); + + Request searchRequest = new Request("POST", "/_async_search"); + searchRequest.setJsonEntity(""" + { + "query": { + "simple_query_string" : { + "query": "foo", + "fields": ["field"] + } + } + } + """); + searchRequest.addParameter("error_trace", "true"); + searchRequest.addParameter("keep_on_completion", "true"); + searchRequest.addParameter("wait_for_completion_timeout", "0ms"); + Map responseEntity = performRequestAndGetResponseEntityAfterDelay(searchRequest, TimeValue.ZERO); + String asyncExecutionId = (String) responseEntity.get("id"); + Request request = new Request("GET", "/_async_search/" + asyncExecutionId); + request.addParameter("error_trace", "false"); + while (responseEntity.get("is_running") instanceof Boolean isRunning && isRunning) { + responseEntity = performRequestAndGetResponseEntityAfterDelay(request, TimeValue.timeValueSeconds(1L)); + } + // check that the stack trace was sent from the data node to the coordinating node + assertTrue(transportMessageHasStackTrace.get()); + } + + private Map performRequestAndGetResponseEntityAfterDelay(Request r, TimeValue sleep) throws IOException, + InterruptedException { + Thread.sleep(sleep.millis()); + Response response = getRestClient().performRequest(r); + XContentType entityContentType = XContentType.fromMediaType(response.getEntity().getContentType().getValue()); + return XContentHelper.convertToMap(entityContentType.xContent(), response.getEntity().getContent(), false); + } +} diff --git a/x-pack/plugin/async-search/src/main/java/org/elasticsearch/xpack/search/RestSubmitAsyncSearchAction.java b/x-pack/plugin/async-search/src/main/java/org/elasticsearch/xpack/search/RestSubmitAsyncSearchAction.java index bd09d8f7740a1..952febd46c34c 100644 --- a/x-pack/plugin/async-search/src/main/java/org/elasticsearch/xpack/search/RestSubmitAsyncSearchAction.java +++ b/x-pack/plugin/async-search/src/main/java/org/elasticsearch/xpack/search/RestSubmitAsyncSearchAction.java @@ -55,6 +55,9 @@ public String getName() { @Override protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + if (client.threadPool() != null && client.threadPool().getThreadContext() != null) { + client.threadPool().getThreadContext().setErrorTraceTransportHeader(request); + } SubmitAsyncSearchRequest submit = new SubmitAsyncSearchRequest(); IntConsumer setSize = size -> submit.getSearchRequest().source().size(size); // for simplicity, we share parsing with ordinary search. That means a couple of unsupported parameters, like scroll diff --git a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/rest/ServerSentEventsRestActionListener.java b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/rest/ServerSentEventsRestActionListener.java index 3177474ea8ca6..bf94f072b6e04 100644 --- a/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/rest/ServerSentEventsRestActionListener.java +++ b/x-pack/plugin/inference/src/main/java/org/elasticsearch/xpack/inference/rest/ServerSentEventsRestActionListener.java @@ -43,6 +43,7 @@ import static org.elasticsearch.ElasticsearchException.REST_EXCEPTION_SKIP_CAUSE; import static org.elasticsearch.ElasticsearchException.REST_EXCEPTION_SKIP_STACK_TRACE; +import static org.elasticsearch.rest.RestController.ERROR_TRACE_DEFAULT; /** * A version of {@link org.elasticsearch.rest.action.RestChunkedToXContentListener} that reads from a {@link Flow.Publisher} and encodes @@ -161,7 +162,7 @@ private ChunkedToXContent errorChunk(Throwable t) { } var errorParams = p; - if (errorParams.paramAsBoolean("error_trace", false) && status != RestStatus.UNAUTHORIZED) { + if (errorParams.paramAsBoolean("error_trace", ERROR_TRACE_DEFAULT) && status != RestStatus.UNAUTHORIZED) { errorParams = new ToXContent.DelegatingMapParams( Map.of(REST_EXCEPTION_SKIP_STACK_TRACE, "false", REST_EXCEPTION_SKIP_CAUSE, "true"), params From 4e5b94ae033c10921a4a3ebb7274d89420d11d6b Mon Sep 17 00:00:00 2001 From: Salvatore Campagna <93581129+salvatore-campagna@users.noreply.github.com> Date: Wed, 18 Dec 2024 15:38:42 +0100 Subject: [PATCH 48/60] feature: extend shard chanbes api to support data streams and aliases (#118937) Extends the `/{index}/ccr/shard_changes` API to accept data stream and alias names in addition to index names. This allows users to retrieve shard changes for data streams and indices accessed through aliases. When a data stream is provided, the API targets the **first backing index** for retrieving shard changes. Similarly, for an alias, the API targets the **first index** associated with the alias. --- .../xpack/ccr/rest/ShardChangesRestIT.java | 140 ++++++++++++++++-- .../ccr/rest/RestShardChangesAction.java | 112 ++++++++++---- 2 files changed, 214 insertions(+), 38 deletions(-) diff --git a/x-pack/plugin/ccr/src/javaRestTest/java/org/elasticsearch/xpack/ccr/rest/ShardChangesRestIT.java b/x-pack/plugin/ccr/src/javaRestTest/java/org/elasticsearch/xpack/ccr/rest/ShardChangesRestIT.java index e5dfea7b772f2..4c61904475093 100644 --- a/x-pack/plugin/ccr/src/javaRestTest/java/org/elasticsearch/xpack/ccr/rest/ShardChangesRestIT.java +++ b/x-pack/plugin/ccr/src/javaRestTest/java/org/elasticsearch/xpack/ccr/rest/ShardChangesRestIT.java @@ -26,6 +26,9 @@ import org.junit.ClassRule; import java.io.IOException; +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Locale; import java.util.Map; @@ -33,11 +36,14 @@ public class ShardChangesRestIT extends ESRestTestCase { private static final String CCR_SHARD_CHANGES_ENDPOINT = "/%s/ccr/shard_changes"; private static final String BULK_INDEX_ENDPOINT = "/%s/_bulk"; + private static final String DATA_STREAM_ENDPOINT = "/_data_stream/%s"; + private static final String INDEX_TEMPLATE_ENDPOINT = "/_index_template/%s"; private static final String[] SHARD_RESPONSE_FIELDS = new String[] { "took_in_millis", "operations", "shard_id", + "index_abstraction", "index", "settings_version", "max_seq_no_of_updates_or_deletes", @@ -46,6 +52,11 @@ public class ShardChangesRestIT extends ESRestTestCase { "aliases_version", "max_seq_no", "global_checkpoint" }; + + private static final String BULK_INDEX_TEMPLATE = """ + { "index": { "op_type": "create" } } + { "@timestamp": "%s", "name": "%s" } + """;; private static final String[] NAMES = { "skywalker", "leia", "obi-wan", "yoda", "chewbacca", "r2-d2", "c-3po", "darth-vader" }; @ClassRule public static ElasticsearchCluster cluster = ElasticsearchCluster.local() @@ -99,13 +110,86 @@ public void testShardChangesDefaultParams() throws IOException { createIndex(indexName, settings, mappings); assertTrue(indexExists(indexName)); - assertOK(client().performRequest(bulkRequest(indexName, randomIntBetween(10, 20)))); + assertOK(bulkIndex(indexName, randomIntBetween(10, 20))); final Request shardChangesRequest = new Request("GET", shardChangesEndpoint(indexName)); final Response response = client().performRequest(shardChangesRequest); assertOK(response); assertShardChangesResponse( - XContentHelper.convertToMap(JsonXContent.jsonXContent, EntityUtils.toString(response.getEntity()), false) + XContentHelper.convertToMap(JsonXContent.jsonXContent, EntityUtils.toString(response.getEntity()), false), + indexName + ); + } + + public void testDataStreamShardChangesDefaultParams() throws IOException { + final String templateName = randomAlphanumericOfLength(8).toLowerCase(Locale.ROOT); + assertOK(createIndexTemplate(templateName, """ + { + "index_patterns": [ "test-*-*" ], + "data_stream": {}, + "priority": 100, + "template": { + "mappings": { + "properties": { + "@timestamp": { + "type": "date" + }, + "name": { + "type": "keyword" + } + } + } + } + }""")); + + final String dataStreamName = "test-" + + randomAlphanumericOfLength(5).toLowerCase(Locale.ROOT) + + "-" + + randomAlphaOfLength(5).toLowerCase(Locale.ROOT); + assertOK(createDataStream(dataStreamName)); + + assertOK(bulkIndex(dataStreamName, randomIntBetween(10, 20))); + + final Request shardChangesRequest = new Request("GET", shardChangesEndpoint(dataStreamName)); + final Response response = client().performRequest(shardChangesRequest); + assertOK(response); + assertShardChangesResponse( + XContentHelper.convertToMap(JsonXContent.jsonXContent, EntityUtils.toString(response.getEntity()), false), + dataStreamName + ); + } + + public void testIndexAliasShardChangesDefaultParams() throws IOException { + final String indexName = randomAlphanumericOfLength(10).toLowerCase(Locale.ROOT); + final String aliasName = randomAlphanumericOfLength(8).toLowerCase(Locale.ROOT); + final Settings settings = Settings.builder() + .put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1) + .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0) + .put(IndexSettings.INDEX_TRANSLOG_SYNC_INTERVAL_SETTING.getKey(), "1s") + .build(); + final String mappings = """ + { + "properties": { + "name": { + "type": "keyword" + } + } + } + """; + createIndex(indexName, settings, mappings); + assertTrue(indexExists(indexName)); + + final Request putAliasRequest = new Request("PUT", "/" + indexName + "/_alias/" + aliasName); + assertOK(client().performRequest(putAliasRequest)); + + assertOK(bulkIndex(aliasName, randomIntBetween(10, 20))); + + final Request shardChangesRequest = new Request("GET", shardChangesEndpoint(aliasName)); + final Response response = client().performRequest(shardChangesRequest); + assertOK(response); + assertShardChangesResponse( + XContentHelper.convertToMap(JsonXContent.jsonXContent, EntityUtils.toString(response.getEntity()), false), + aliasName ); } @@ -121,7 +205,7 @@ public void testShardChangesWithAllParameters() throws IOException { ); assertTrue(indexExists(indexName)); - assertOK(client().performRequest(bulkRequest(indexName, randomIntBetween(100, 200)))); + assertOK(bulkIndex(indexName, randomIntBetween(100, 200))); final Request shardChangesRequest = new Request("GET", shardChangesEndpoint(indexName)); shardChangesRequest.addParameter("from_seq_no", "0"); @@ -132,7 +216,8 @@ public void testShardChangesWithAllParameters() throws IOException { final Response response = client().performRequest(shardChangesRequest); assertOK(response); assertShardChangesResponse( - XContentHelper.convertToMap(JsonXContent.jsonXContent, EntityUtils.toString(response.getEntity()), false) + XContentHelper.convertToMap(JsonXContent.jsonXContent, EntityUtils.toString(response.getEntity()), false), + indexName ); } @@ -148,7 +233,7 @@ public void testShardChangesMultipleRequests() throws IOException { ); assertTrue(indexExists(indexName)); - assertOK(client().performRequest(bulkRequest(indexName, randomIntBetween(100, 200)))); + assertOK(bulkIndex(indexName, randomIntBetween(100, 200))); final Request firstRequest = new Request("GET", shardChangesEndpoint(indexName)); firstRequest.addParameter("from_seq_no", "0"); @@ -159,7 +244,8 @@ public void testShardChangesMultipleRequests() throws IOException { final Response firstResponse = client().performRequest(firstRequest); assertOK(firstResponse); assertShardChangesResponse( - XContentHelper.convertToMap(JsonXContent.jsonXContent, EntityUtils.toString(firstResponse.getEntity()), false) + XContentHelper.convertToMap(JsonXContent.jsonXContent, EntityUtils.toString(firstResponse.getEntity()), false), + indexName ); final Request secondRequest = new Request("GET", shardChangesEndpoint(indexName)); @@ -171,7 +257,8 @@ public void testShardChangesMultipleRequests() throws IOException { final Response secondResponse = client().performRequest(secondRequest); assertOK(secondResponse); assertShardChangesResponse( - XContentHelper.convertToMap(JsonXContent.jsonXContent, EntityUtils.toString(secondResponse.getEntity()), false) + XContentHelper.convertToMap(JsonXContent.jsonXContent, EntityUtils.toString(secondResponse.getEntity()), false), + indexName ); } @@ -231,17 +318,36 @@ public void testShardChangesMissingIndex() throws IOException { assertResponseException(ex, RestStatus.BAD_REQUEST, "Failed to process shard changes for index [" + indexName + "]"); } - private static Request bulkRequest(final String indexName, int numberOfDocuments) { + private static Response bulkIndex(final String indexName, int numberOfDocuments) throws IOException { final StringBuilder sb = new StringBuilder(); + long timestamp = System.currentTimeMillis(); for (int i = 0; i < numberOfDocuments; i++) { - sb.append(String.format(Locale.ROOT, "{ \"index\": { \"_id\": \"%d\" } }\n{ \"name\": \"%s\" }\n", i + 1, randomFrom(NAMES))); + sb.append( + String.format( + Locale.ROOT, + BULK_INDEX_TEMPLATE, + Instant.ofEpochMilli(timestamp).atOffset(ZoneOffset.UTC).format(DateTimeFormatter.ISO_OFFSET_DATE_TIME), + randomFrom(NAMES) + ) + ); + timestamp += 1000; // 1 second } final Request request = new Request("POST", bulkEndpoint(indexName)); request.setJsonEntity(sb.toString()); request.addParameter("refresh", "true"); - return request; + return client().performRequest(request); + } + + private Response createDataStream(final String dataStreamName) throws IOException { + return client().performRequest(new Request("PUT", dataStreamEndpoint(dataStreamName))); + } + + private static Response createIndexTemplate(final String templateName, final String mappings) throws IOException { + final Request request = new Request("PUT", indexTemplateEndpoint(templateName)); + request.setJsonEntity(mappings); + return client().performRequest(request); } private static String shardChangesEndpoint(final String indexName) { @@ -252,16 +358,28 @@ private static String bulkEndpoint(final String indexName) { return String.format(Locale.ROOT, BULK_INDEX_ENDPOINT, indexName); } + private static String dataStreamEndpoint(final String dataStreamName) { + return String.format(Locale.ROOT, DATA_STREAM_ENDPOINT, dataStreamName); + } + + private static String indexTemplateEndpoint(final String templateName) { + return String.format(Locale.ROOT, INDEX_TEMPLATE_ENDPOINT, templateName); + } + private void assertResponseException(final ResponseException ex, final RestStatus restStatus, final String error) { assertEquals(restStatus.getStatus(), ex.getResponse().getStatusLine().getStatusCode()); assertThat(ex.getMessage(), Matchers.containsString(error)); } - private void assertShardChangesResponse(final Map shardChangesResponseBody) { + private void assertShardChangesResponse(final Map shardChangesResponseBody, final String indexAbstractionName) { for (final String fieldName : SHARD_RESPONSE_FIELDS) { final Object fieldValue = shardChangesResponseBody.get(fieldName); assertNotNull("Field " + fieldName + " is missing or has a null value.", fieldValue); + if ("index_abstraction".equals(fieldName)) { + assertEquals(indexAbstractionName, fieldValue); + } + if ("operations".equals(fieldName)) { if (fieldValue instanceof List operationsList) { assertFalse("Field 'operations' is empty.", operationsList.isEmpty()); diff --git a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/rest/RestShardChangesAction.java b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/rest/RestShardChangesAction.java index 84171ebce162f..4a1d26d05a980 100644 --- a/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/rest/RestShardChangesAction.java +++ b/x-pack/plugin/ccr/src/main/java/org/elasticsearch/xpack/ccr/rest/RestShardChangesAction.java @@ -10,6 +10,8 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.admin.indices.stats.ShardStats; import org.elasticsearch.client.internal.node.NodeClient; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.metadata.IndexAbstraction; import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.common.unit.ByteSizeUnit; import org.elasticsearch.common.unit.ByteSizeValue; @@ -32,6 +34,7 @@ import java.util.Arrays; import java.util.Comparator; import java.util.List; +import java.util.Locale; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -42,10 +45,14 @@ import static org.elasticsearch.rest.RestRequest.Method.GET; /** - * A REST handler that retrieves shard changes in a specific index whose name is provided as a parameter. - * It handles GET requests to the "/{index}/ccr/shard_changes" endpoint retrieving shard-level changes, - * such as translog operations, mapping version, settings version, aliases version, the global checkpoint, - * maximum sequence number and maximum sequence number of updates or deletes. + * A REST handler that retrieves shard changes in a specific index, data stream or alias whose name is + * provided as a parameter. It handles GET requests to the "/{index}/ccr/shard_changes" endpoint retrieving + * shard-level changes, such as Translog operations, mapping version, settings version, aliases version, + * the global checkpoint, maximum sequence number and maximum sequence number of updates or deletes. + *

    + * In the case of a data stream, the first backing index is considered the target for retrieving shard changes. + * In the case of an alias, the first index that the alias points to is considered the target for retrieving + * shard changes. *

    * Note: This handler is only available for snapshot builds. */ @@ -84,32 +91,36 @@ public List routes() { */ @Override protected RestChannelConsumer prepareRequest(final RestRequest restRequest, final NodeClient client) throws IOException { - final var indexName = restRequest.param(INDEX_PARAM_NAME); + final var indexAbstractionName = restRequest.param(INDEX_PARAM_NAME); final var fromSeqNo = restRequest.paramAsLong(FROM_SEQ_NO_PARAM_NAME, DEFAULT_FROM_SEQ_NO); final var maxBatchSize = restRequest.paramAsSize(MAX_BATCH_SIZE_PARAM_NAME, DEFAULT_MAX_BATCH_SIZE); final var pollTimeout = restRequest.paramAsTime(POLL_TIMEOUT_PARAM_NAME, DEFAULT_POLL_TIMEOUT); final var maxOperationsCount = restRequest.paramAsInt(MAX_OPERATIONS_COUNT_PARAM_NAME, DEFAULT_MAX_OPERATIONS_COUNT); - final CompletableFuture indexUUIDCompletableFuture = asyncGetIndexUUID( + // NOTE: we first retrieve the concrete index name in case we are dealing with an alias or data stream. + // Then we use the concrete index name to retrieve the index UUID and shard stats. + final CompletableFuture indexNameCompletableFuture = asyncGetIndexName( client, - indexName, + indexAbstractionName, client.threadPool().executor(Ccr.CCR_THREAD_POOL_NAME) ); - final CompletableFuture shardStatsCompletableFuture = asyncShardStats( - client, - indexName, - client.threadPool().executor(Ccr.CCR_THREAD_POOL_NAME) + final CompletableFuture indexUUIDCompletableFuture = indexNameCompletableFuture.thenCompose( + concreteIndexName -> asyncGetIndexUUID(client, concreteIndexName, client.threadPool().executor(Ccr.CCR_THREAD_POOL_NAME)) + ); + final CompletableFuture shardStatsCompletableFuture = indexNameCompletableFuture.thenCompose( + concreteIndexName -> asyncShardStats(client, concreteIndexName, client.threadPool().executor(Ccr.CCR_THREAD_POOL_NAME)) ); return channel -> CompletableFuture.allOf(indexUUIDCompletableFuture, shardStatsCompletableFuture).thenRun(() -> { try { + final String concreteIndexName = indexNameCompletableFuture.get(DEFAULT_TIMEOUT_SECONDS, TimeUnit.SECONDS); final String indexUUID = indexUUIDCompletableFuture.get(DEFAULT_TIMEOUT_SECONDS, TimeUnit.SECONDS); final ShardStats shardStats = shardStatsCompletableFuture.get(DEFAULT_TIMEOUT_SECONDS, TimeUnit.SECONDS); final ShardId shardId = shardStats.getShardRouting().shardId(); final String expectedHistoryUUID = shardStats.getCommitStats().getUserData().get(Engine.HISTORY_UUID_KEY); final ShardChangesAction.Request shardChangesRequest = shardChangesRequest( - indexName, + concreteIndexName, indexUUID, shardId, expectedHistoryUUID, @@ -121,7 +132,12 @@ protected RestChannelConsumer prepareRequest(final RestRequest restRequest, fina client.execute(ShardChangesAction.INSTANCE, shardChangesRequest, new RestActionListener<>(channel) { @Override protected void processResponse(final ShardChangesAction.Response response) { - channel.sendResponse(new RestResponse(RestStatus.OK, shardChangesResponseToXContent(response, indexName, shardId))); + channel.sendResponse( + new RestResponse( + RestStatus.OK, + shardChangesResponseToXContent(response, indexAbstractionName, concreteIndexName, shardId) + ) + ); } }); @@ -132,7 +148,12 @@ protected void processResponse(final ShardChangesAction.Response response) { throw new IllegalStateException("Timeout while waiting for shard stats or index UUID", te); } }).exceptionally(ex -> { - channel.sendResponse(new RestResponse(RestStatus.BAD_REQUEST, "Failed to process shard changes for index [" + indexName + "]")); + channel.sendResponse( + new RestResponse( + RestStatus.BAD_REQUEST, + "Failed to process shard changes for index [" + indexAbstractionName + "] " + ex.getMessage() + ) + ); return null; }); } @@ -175,17 +196,20 @@ private static ShardChangesAction.Request shardChangesRequest( * Converts the response to XContent JSOn format. * * @param response The ShardChangesAction response. - * @param indexName The name of the index. + * @param indexAbstractionName The name of the index abstraction. + * @param concreteIndexName The name of the index. * @param shardId The ShardId. */ private static XContentBuilder shardChangesResponseToXContent( final ShardChangesAction.Response response, - final String indexName, + final String indexAbstractionName, + final String concreteIndexName, final ShardId shardId ) { try (XContentBuilder builder = XContentFactory.jsonBuilder()) { builder.startObject(); - builder.field("index", indexName); + builder.field("index_abstraction", indexAbstractionName); + builder.field("index", concreteIndexName); builder.field("shard_id", shardId); builder.field("mapping_version", response.getMappingVersion()); builder.field("settings_version", response.getSettingsVersion()); @@ -249,26 +273,60 @@ private static CompletableFuture supplyAsyncTask( }, executorService); } + /** + * Asynchronously retrieves the index name for a given index, alias or data stream. + * If the name represents a data stream, the name of the first backing index is returned. + * If the name represents an alias, the name of the first index that the alias points to is returned. + * + * @param client The NodeClient for executing the asynchronous request. + * @param indexAbstractionName The name of the index, alias or data stream. + * @return A CompletableFuture that completes with the retrieved index name. + */ + private static CompletableFuture asyncGetIndexName( + final NodeClient client, + final String indexAbstractionName, + final ExecutorService executorService + ) { + return supplyAsyncTask(() -> { + final ClusterState clusterState = client.admin() + .cluster() + .prepareState(new TimeValue(DEFAULT_TIMEOUT_SECONDS, TimeUnit.SECONDS)) + .get(GET_INDEX_UUID_TIMEOUT) + .getState(); + final IndexAbstraction indexAbstraction = clusterState.metadata().getIndicesLookup().get(indexAbstractionName); + if (indexAbstraction == null) { + throw new IllegalArgumentException( + String.format(Locale.ROOT, "Invalid index or data stream name [%s]", indexAbstractionName) + ); + } + if (indexAbstraction.getType() == IndexAbstraction.Type.DATA_STREAM + || indexAbstraction.getType() == IndexAbstraction.Type.ALIAS) { + return indexAbstraction.getIndices().getFirst().getName(); + } + return indexAbstractionName; + }, executorService, "Error while retrieving index name for index or data stream [" + indexAbstractionName + "]"); + } + /** * Asynchronously retrieves the shard stats for a given index using an executor service. * * @param client The NodeClient for executing the asynchronous request. - * @param indexName The name of the index for which to retrieve shard statistics. + * @param concreteIndexName The name of the index for which to retrieve shard statistics. * @param executorService The executorService service for executing the asynchronous task. * @return A CompletableFuture that completes with the retrieved ShardStats. * @throws ElasticsearchException If an error occurs while retrieving shard statistics. */ private static CompletableFuture asyncShardStats( final NodeClient client, - final String indexName, + final String concreteIndexName, final ExecutorService executorService ) { return supplyAsyncTask( - () -> Arrays.stream(client.admin().indices().prepareStats(indexName).clear().get(SHARD_STATS_TIMEOUT).getShards()) + () -> Arrays.stream(client.admin().indices().prepareStats(concreteIndexName).clear().get(SHARD_STATS_TIMEOUT).getShards()) .max(Comparator.comparingLong(shardStats -> shardStats.getCommitStats().getGeneration())) - .orElseThrow(() -> new ElasticsearchException("Unable to retrieve shard stats for index: " + indexName)), + .orElseThrow(() -> new ElasticsearchException("Unable to retrieve shard stats for index: " + concreteIndexName)), executorService, - "Error while retrieving shard stats for index [" + indexName + "]" + "Error while retrieving shard stats for index [" + concreteIndexName + "]" ); } @@ -276,25 +334,25 @@ private static CompletableFuture asyncShardStats( * Asynchronously retrieves the index UUID for a given index using an executor service. * * @param client The NodeClient for executing the asynchronous request. - * @param indexName The name of the index for which to retrieve the index UUID. + * @param concreteIndexName The name of the index for which to retrieve the index UUID. * @param executorService The executorService service for executing the asynchronous task. * @return A CompletableFuture that completes with the retrieved index UUID. * @throws ElasticsearchException If an error occurs while retrieving the index UUID. */ private static CompletableFuture asyncGetIndexUUID( final NodeClient client, - final String indexName, + final String concreteIndexName, final ExecutorService executorService ) { return supplyAsyncTask( () -> client.admin() .indices() .prepareGetIndex() - .setIndices(indexName) + .setIndices(concreteIndexName) .get(GET_INDEX_UUID_TIMEOUT) - .getSetting(indexName, IndexMetadata.SETTING_INDEX_UUID), + .getSetting(concreteIndexName, IndexMetadata.SETTING_INDEX_UUID), executorService, - "Error while retrieving index UUID for index [" + indexName + "]" + "Error while retrieving index UUID for index [" + concreteIndexName + "]" ); } } From 31578be7502c267e11bed31af064b857bbd2d490 Mon Sep 17 00:00:00 2001 From: elasticsearchmachine <58790826+elasticsearchmachine@users.noreply.github.com> Date: Thu, 19 Dec 2024 01:43:17 +1100 Subject: [PATCH 49/60] Mute org.elasticsearch.repositories.blobstore.testkit.analyze.SecureHdfsRepositoryAnalysisRestIT org.elasticsearch.repositories.blobstore.testkit.analyze.SecureHdfsRepositoryAnalysisRestIT #118970 --- muted-tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/muted-tests.yml b/muted-tests.yml index b35a70391f195..6b433f232defd 100644 --- a/muted-tests.yml +++ b/muted-tests.yml @@ -295,6 +295,8 @@ tests: - class: org.elasticsearch.xpack.migrate.task.ReindexDataStreamStatusTests method: testEqualsAndHashcode issue: https://github.com/elastic/elasticsearch/issues/118965 +- class: org.elasticsearch.repositories.blobstore.testkit.analyze.SecureHdfsRepositoryAnalysisRestIT + issue: https://github.com/elastic/elasticsearch/issues/118970 # Examples: # From 1141edee4797f772a542528a296df2d802b50122 Mon Sep 17 00:00:00 2001 From: Martijn van Groningen Date: Wed, 18 Dec 2024 15:49:53 +0100 Subject: [PATCH 50/60] Fix "create index with use_synthetic_source" yaml test. (#118946) The `flush` param defaults to `true` and some environments don't support that. Setting `flush` param to `false` to fix this. ``` [2024-12-18T19:51:01,213][INFO ][c.e.e.q.r.ServerlessClientYamlTestSuiteIT] [test] Stash dump on test failure [{ "stash" : { "body" : { "_shards" : { "total" : 3, "successful" : 0, "failed" : 3, "failures" : [ { "shard" : 0, "index" : "test", "status" : "BAD_REQUEST", "reason" : { "type" : "illegal_argument_exception", "reason" : "Search engine does not support acquiring last index commit with flush_first" } } ] } } } }] ``` --- .../test/indices.create/20_synthetic_source.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.create/20_synthetic_source.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.create/20_synthetic_source.yml index fc0bfa144bbc4..edb684168278b 100644 --- a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.create/20_synthetic_source.yml +++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/indices.create/20_synthetic_source.yml @@ -2049,5 +2049,6 @@ create index with use_synthetic_source: indices.disk_usage: index: test run_expensive_tasks: true - - gt: { test.fields.field.total_in_bytes: 0 } - - is_false: test.fields.field._recovery_source + flush: false + - gt: { test.store_size_in_bytes: 0 } + - is_false: test.fields._recovery_source From e0f4b01fb8655c82e1b62dcb07973016ed411297 Mon Sep 17 00:00:00 2001 From: Keith Massey Date: Wed, 18 Dec 2024 08:56:39 -0600 Subject: [PATCH 51/60] Fixing ReindexDataStreamStatusTests so that the in progress set max size is not less than min size (#118957) It is currently possible when we mutate a status object that we ask for a random set for the inProgress field where the max size of the set is less than the min size. This fixes that. --- .../migrate/task/ReindexDataStreamEnrichedStatusTests.java | 2 +- .../xpack/migrate/task/ReindexDataStreamStatusTests.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamEnrichedStatusTests.java b/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamEnrichedStatusTests.java index acd8cd1a6add2..993db1096aac2 100644 --- a/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamEnrichedStatusTests.java +++ b/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamEnrichedStatusTests.java @@ -74,7 +74,7 @@ private List randomList(int minSize) { } private Set randomSet(int minSize) { - return randomSet(minSize, 100, () -> randomAlphaOfLength(50)); + return randomSet(minSize, Math.max(minSize, 100), () -> randomAlphaOfLength(50)); } private List> randomErrorList() { diff --git a/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamStatusTests.java b/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamStatusTests.java index 47e2d02bee3b0..ad47eb6a23cd7 100644 --- a/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamStatusTests.java +++ b/x-pack/plugin/migrate/src/test/java/org/elasticsearch/xpack/migrate/task/ReindexDataStreamStatusTests.java @@ -70,7 +70,7 @@ private List randomList(int minSize) { } private Set randomSet(int minSize) { - return randomSet(minSize, 100, () -> randomAlphaOfLength(50)); + return randomSet(minSize, Math.max(minSize, 100), () -> randomAlphaOfLength(50)); } private List> randomErrorList() { From 8a8dfe8f688ea0d1291f1bc5b82a3d1fe12c7c59 Mon Sep 17 00:00:00 2001 From: Sean Story Date: Wed, 18 Dec 2024 09:44:52 -0600 Subject: [PATCH 52/60] Delete accidentally added file, and gitignore (#118971) --- .gitignore | 3 +++ .java-version | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) delete mode 100644 .java-version diff --git a/.gitignore b/.gitignore index d1af97cbaea3b..8b2da4dc0832a 100644 --- a/.gitignore +++ b/.gitignore @@ -69,3 +69,6 @@ testfixtures_shared/ # Generated checkstyle_ide.xml x-pack/plugin/esql/src/main/generated-src/generated/ + +# JEnv +.java-version diff --git a/.java-version b/.java-version deleted file mode 100644 index aabe6ec3909c9..0000000000000 --- a/.java-version +++ /dev/null @@ -1 +0,0 @@ -21 From bc3b629d8d7010a61f5179279446346ffd45263b Mon Sep 17 00:00:00 2001 From: Bogdan Pintea Date: Wed, 18 Dec 2024 17:12:14 +0100 Subject: [PATCH 53/60] ESQL: Docs: add example of date bucketing with offset (#116680) Add an example of how to create date histograms with an offset. Fixes #114167 --- .../esql/functions/examples/bucket.asciidoc | 14 ++++++++++++++ .../functions/kibana/definition/bucket.json | 3 ++- .../elasticsearch/xpack/esql/CsvTestUtils.java | 2 +- .../src/main/resources/bucket.csv-spec | 18 ++++++++++++++++++ .../expression/function/grouping/Bucket.java | 11 +++++++++++ .../org/elasticsearch/xpack/esql/CsvTests.java | 5 +++-- 6 files changed, 49 insertions(+), 4 deletions(-) diff --git a/docs/reference/esql/functions/examples/bucket.asciidoc b/docs/reference/esql/functions/examples/bucket.asciidoc index 4afea30660339..264efc191748f 100644 --- a/docs/reference/esql/functions/examples/bucket.asciidoc +++ b/docs/reference/esql/functions/examples/bucket.asciidoc @@ -116,4 +116,18 @@ include::{esql-specs}/bucket.csv-spec[tag=reuseGroupingFunctionWithExpression] |=== include::{esql-specs}/bucket.csv-spec[tag=reuseGroupingFunctionWithExpression-result] |=== +Sometimes you need to change the start value of each bucket by a given duration (similar to date histogram +aggregation's <> parameter). To do so, you will need to +take into account how the language handles expressions within the `STATS` command: if these contain functions or +arithmetic operators, a virtual `EVAL` is inserted before and/or after the `STATS` command. Consequently, a double +compensation is needed to adjust the bucketed date value before the aggregation and then again after. For instance, +inserting a negative offset of `1 hour` to buckets of `1 year` looks like this: +[source.merge.styled,esql] +---- +include::{esql-specs}/bucket.csv-spec[tag=bucketWithOffset] +---- +[%header.monospaced.styled,format=dsv,separator=|] +|=== +include::{esql-specs}/bucket.csv-spec[tag=bucketWithOffset-result] +|=== diff --git a/docs/reference/esql/functions/kibana/definition/bucket.json b/docs/reference/esql/functions/kibana/definition/bucket.json index 18802f5ff8fef..3d96de05c8407 100644 --- a/docs/reference/esql/functions/kibana/definition/bucket.json +++ b/docs/reference/esql/functions/kibana/definition/bucket.json @@ -1598,7 +1598,8 @@ "FROM employees\n| WHERE hire_date >= \"1985-01-01T00:00:00Z\" AND hire_date < \"1986-01-01T00:00:00Z\"\n| STATS c = COUNT(1) BY b = BUCKET(salary, 5000.)\n| SORT b", "FROM sample_data \n| WHERE @timestamp >= NOW() - 1 day and @timestamp < NOW()\n| STATS COUNT(*) BY bucket = BUCKET(@timestamp, 25, NOW() - 1 day, NOW())", "FROM employees\n| WHERE hire_date >= \"1985-01-01T00:00:00Z\" AND hire_date < \"1986-01-01T00:00:00Z\"\n| STATS AVG(salary) BY bucket = BUCKET(hire_date, 20, \"1985-01-01T00:00:00Z\", \"1986-01-01T00:00:00Z\")\n| SORT bucket", - "FROM employees\n| STATS s1 = b1 + 1, s2 = BUCKET(salary / 1000 + 999, 50.) + 2 BY b1 = BUCKET(salary / 100 + 99, 50.), b2 = BUCKET(salary / 1000 + 999, 50.)\n| SORT b1, b2\n| KEEP s1, b1, s2, b2" + "FROM employees\n| STATS s1 = b1 + 1, s2 = BUCKET(salary / 1000 + 999, 50.) + 2 BY b1 = BUCKET(salary / 100 + 99, 50.), b2 = BUCKET(salary / 1000 + 999, 50.)\n| SORT b1, b2\n| KEEP s1, b1, s2, b2", + "FROM employees \n| STATS dates = VALUES(birth_date) BY b = BUCKET(birth_date + 1 HOUR, 1 YEAR) - 1 HOUR\n| EVAL d_count = MV_COUNT(dates)\n| SORT d_count\n| LIMIT 3" ], "preview" : false, "snapshot_only" : false diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestUtils.java b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestUtils.java index 7adafa908ce4f..f0bdf089f69d1 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestUtils.java +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/java/org/elasticsearch/xpack/esql/CsvTestUtils.java @@ -63,7 +63,7 @@ import static org.elasticsearch.xpack.esql.core.util.SpatialCoordinateTypes.GEO; public final class CsvTestUtils { - private static final int MAX_WIDTH = 20; + private static final int MAX_WIDTH = 80; private static final CsvPreference CSV_SPEC_PREFERENCES = new CsvPreference.Builder('"', '|', "\r\n").build(); private static final String NULL_VALUE = "null"; private static final char ESCAPE_CHAR = '\\'; diff --git a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/bucket.csv-spec b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/bucket.csv-spec index b29c489910f65..8cfde2bb9bde7 100644 --- a/x-pack/plugin/esql/qa/testFixtures/src/main/resources/bucket.csv-spec +++ b/x-pack/plugin/esql/qa/testFixtures/src/main/resources/bucket.csv-spec @@ -145,6 +145,24 @@ AVG(salary):double | bucket:date // end::bucket_in_agg-result[] ; +bucketWithOffset#[skip:-8.13.99, reason:BUCKET renamed in 8.14] +// tag::bucketWithOffset[] +FROM employees +| STATS dates = MV_SORT(VALUES(birth_date)) BY b = BUCKET(birth_date + 1 HOUR, 1 YEAR) - 1 HOUR +| EVAL d_count = MV_COUNT(dates) +| SORT d_count, b +| LIMIT 3 +// end::bucketWithOffset[] +; + +// tag::bucketWithOffset-result[] +dates:date |b:date |d_count:integer +1965-01-03T00:00:00.000Z |1964-12-31T23:00:00.000Z|1 +[1955-01-21T00:00:00.000Z, 1955-08-20T00:00:00.000Z, 1955-08-28T00:00:00.000Z, 1955-10-04T00:00:00.000Z]|1954-12-31T23:00:00.000Z|4 +[1957-04-04T00:00:00.000Z, 1957-05-23T00:00:00.000Z, 1957-05-25T00:00:00.000Z, 1957-12-03T00:00:00.000Z]|1956-12-31T23:00:00.000Z|4 +// end::bucketWithOffset-result[] +; + docsBucketMonth#[skip:-8.13.99, reason:BUCKET renamed in 8.14] //tag::docsBucketMonth[] FROM employees diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/grouping/Bucket.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/grouping/Bucket.java index 347d542f5212d..12932ba8d6e11 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/grouping/Bucket.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/grouping/Bucket.java @@ -163,6 +163,17 @@ another in which the bucket size is provided directly (two parameters). grouping part, or that it is invoked with the exact same expression:""", file = "bucket", tag = "reuseGroupingFunctionWithExpression" + ), + @Example( + description = """ + Sometimes you need to change the start value of each bucket by a given duration (similar to date histogram + aggregation's <> parameter). To do so, you will need to + take into account how the language handles expressions within the `STATS` command: if these contain functions or + arithmetic operators, a virtual `EVAL` is inserted before and/or after the `STATS` command. Consequently, a double + compensation is needed to adjust the bucketed date value before the aggregation and then again after. For instance, + inserting a negative offset of `1 hour` to buckets of `1 year` looks like this:""", + file = "bucket", + tag = "bucketWithOffset" ) } ) public Bucket( diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java index b81b80a9fdbb4..e627f99322f08 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/CsvTests.java @@ -322,13 +322,14 @@ private void doTest() throws Exception { } protected void assertResults(ExpectedResults expected, ActualResults actual, boolean ignoreOrder, Logger logger) { - CsvAssert.assertResults(expected, actual, ignoreOrder, logger); /* - * Comment the assertion above and enable the next two lines to see the results returned by ES without any assertions being done. + * Enable the next two lines to see the results returned by ES. * This is useful when creating a new test or trying to figure out what are the actual results. */ // CsvTestUtils.logMetaData(actual.columnNames(), actual.columnTypes(), LOGGER); // CsvTestUtils.logData(actual.values(), LOGGER); + + CsvAssert.assertResults(expected, actual, ignoreOrder, logger); } private static IndexResolution loadIndexResolution(String mappingName, String indexName, Map typeMapping) { From a5ced2c48612b003dbbca3238526b29bfc6501d3 Mon Sep 17 00:00:00 2001 From: Lee Hinman Date: Wed, 18 Dec 2024 09:19:29 -0700 Subject: [PATCH 54/60] Unmute DotPrefixClientYamlTestSuiteIT (#118898) This failed due to an unrelated failure that appears to have affected more than just this suite. Resolves #118224 --- muted-tests.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/muted-tests.yml b/muted-tests.yml index 6b433f232defd..0442c2305c6f8 100644 --- a/muted-tests.yml +++ b/muted-tests.yml @@ -238,8 +238,6 @@ tests: - class: org.elasticsearch.datastreams.DataStreamsClientYamlTestSuiteIT method: test {p0=data_stream/120_data_streams_stats/Multiple data stream} issue: https://github.com/elastic/elasticsearch/issues/118217 -- class: org.elasticsearch.validation.DotPrefixClientYamlTestSuiteIT - issue: https://github.com/elastic/elasticsearch/issues/118224 - class: org.elasticsearch.packaging.test.ArchiveTests method: test60StartAndStop issue: https://github.com/elastic/elasticsearch/issues/118216 From be769ab1226d928b2428b4b784a18dbcb62a8b9c Mon Sep 17 00:00:00 2001 From: Keith Massey Date: Wed, 18 Dec 2024 10:19:44 -0600 Subject: [PATCH 55/60] Unmuting ReindexDataStreamStatusTests.testEqualsAndHashcode (#118974) This was fixed by #118957. Closes #118965 --- muted-tests.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/muted-tests.yml b/muted-tests.yml index 0442c2305c6f8..f534f24718f52 100644 --- a/muted-tests.yml +++ b/muted-tests.yml @@ -290,9 +290,6 @@ tests: issue: https://github.com/elastic/elasticsearch/issues/118914 - class: org.elasticsearch.smoketest.SmokeTestMultiNodeClientYamlTestSuiteIT issue: https://github.com/elastic/elasticsearch/issues/118955 -- class: org.elasticsearch.xpack.migrate.task.ReindexDataStreamStatusTests - method: testEqualsAndHashcode - issue: https://github.com/elastic/elasticsearch/issues/118965 - class: org.elasticsearch.repositories.blobstore.testkit.analyze.SecureHdfsRepositoryAnalysisRestIT issue: https://github.com/elastic/elasticsearch/issues/118970 From 1147c9da0ca1adeeacc1cad2a7b9957296070c10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Cea=20Fontenla?= Date: Wed, 18 Dec 2024 17:24:47 +0100 Subject: [PATCH 56/60] ESQL: Fix match in LOOKUP JOIN YAML test (#118975) CI is broken, as sometimes the error comes with a "verification_error: " at the beginning, and the match assertion fails. Changing it to a contains. --- .../resources/rest-api-spec/test/esql/190_lookup_join.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/190_lookup_join.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/190_lookup_join.yml index cbaac4e47fdd4..fdb6746bbeed8 100644 --- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/190_lookup_join.yml +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/esql/190_lookup_join.yml @@ -1,7 +1,7 @@ --- setup: - requires: - test_runner_features: [capabilities] + test_runner_features: [capabilities, contains] capabilities: - method: POST path: /_query @@ -75,4 +75,4 @@ non-lookup index: catch: "bad_request" - match: { error.type: "verification_exception" } - - match: { error.reason: "Found 1 problem\nline 1:43: invalid [test] resolution in lookup mode to an index in [standard] mode" } + - contains: { error.reason: "Found 1 problem\nline 1:43: invalid [test] resolution in lookup mode to an index in [standard] mode" } From 1004da29821471eea99afd64da0d151682f46595 Mon Sep 17 00:00:00 2001 From: Parker Timmins Date: Wed, 18 Dec 2024 10:35:19 -0600 Subject: [PATCH 57/60] Add action to create index from a source index (#118890) Add new action that creates an index from a source index, copying settings and mappings from the source index. This was refactored out of ReindexDataStreamIndexAction. --- docs/changelog/118890.yaml | 5 + .../action/CreateIndexFromSourceActionIT.java | 250 ++++++++++++++++++ ...ndexDatastreamIndexTransportActionIT.java} | 8 +- .../xpack/migrate/MigratePlugin.java | 3 + .../action/CreateIndexFromSourceAction.java | 117 ++++++++ .../CreateIndexFromSourceTransportAction.java | 126 +++++++++ .../action/ReindexDataStreamIndexAction.java | 4 - ...ReindexDataStreamIndexTransportAction.java | 104 ++++---- .../xpack/security/operator/Constants.java | 1 + 9 files changed, 552 insertions(+), 66 deletions(-) create mode 100644 docs/changelog/118890.yaml create mode 100644 x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/CreateIndexFromSourceActionIT.java rename x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/{ReindexDatastreamIndexIT.java => ReindexDatastreamIndexTransportActionIT.java} (98%) create mode 100644 x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/CreateIndexFromSourceAction.java create mode 100644 x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/CreateIndexFromSourceTransportAction.java diff --git a/docs/changelog/118890.yaml b/docs/changelog/118890.yaml new file mode 100644 index 0000000000000..d3fc17157f130 --- /dev/null +++ b/docs/changelog/118890.yaml @@ -0,0 +1,5 @@ +pr: 118890 +summary: Add action to create index from a source index +area: Data streams +type: enhancement +issues: [] diff --git a/x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/CreateIndexFromSourceActionIT.java b/x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/CreateIndexFromSourceActionIT.java new file mode 100644 index 0000000000000..b460c6abfeee4 --- /dev/null +++ b/x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/CreateIndexFromSourceActionIT.java @@ -0,0 +1,250 @@ +/* + * 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.migrate.action; + +import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; +import org.elasticsearch.action.admin.indices.get.GetIndexRequest; +import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; +import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest; +import org.elasticsearch.cluster.metadata.IndexMetadata; +import org.elasticsearch.cluster.metadata.MappingMetadata; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentHelper; +import org.elasticsearch.common.xcontent.support.XContentMapValues; +import org.elasticsearch.datastreams.DataStreamsPlugin; +import org.elasticsearch.index.IndexNotFoundException; +import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.reindex.ReindexPlugin; +import org.elasticsearch.test.ESIntegTestCase; +import org.elasticsearch.test.transport.MockTransportService; +import org.elasticsearch.xcontent.json.JsonXContent; +import org.elasticsearch.xpack.migrate.MigratePlugin; + +import java.util.Collection; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; +import static org.elasticsearch.xpack.migrate.action.ReindexDataStreamAction.REINDEX_DATA_STREAM_FEATURE_FLAG; + +public class CreateIndexFromSourceActionIT extends ESIntegTestCase { + + @Override + protected Collection> nodePlugins() { + return List.of(MigratePlugin.class, ReindexPlugin.class, MockTransportService.TestPlugin.class, DataStreamsPlugin.class); + } + + public void testDestIndexCreated() throws Exception { + assumeTrue("requires the migration reindex feature flag", REINDEX_DATA_STREAM_FEATURE_FLAG.isEnabled()); + + var sourceIndex = randomAlphaOfLength(20).toLowerCase(Locale.ROOT); + indicesAdmin().create(new CreateIndexRequest(sourceIndex)).get(); + + // create from source + var destIndex = randomAlphaOfLength(20).toLowerCase(Locale.ROOT); + assertAcked( + client().execute(CreateIndexFromSourceAction.INSTANCE, new CreateIndexFromSourceAction.Request(sourceIndex, destIndex)) + ); + + try { + indicesAdmin().getIndex(new GetIndexRequest().indices(destIndex)).actionGet(); + } catch (IndexNotFoundException e) { + fail(); + } + } + + public void testSettingsCopiedFromSource() throws Exception { + assumeTrue("requires the migration reindex feature flag", REINDEX_DATA_STREAM_FEATURE_FLAG.isEnabled()); + + // start with a static setting + var numShards = randomIntBetween(1, 10); + var staticSettings = Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, numShards).build(); + var sourceIndex = randomAlphaOfLength(20).toLowerCase(Locale.ROOT); + indicesAdmin().create(new CreateIndexRequest(sourceIndex, staticSettings)).get(); + + // update with a dynamic setting + var numReplicas = randomIntBetween(0, 10); + var dynamicSettings = Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, numReplicas).build(); + indicesAdmin().updateSettings(new UpdateSettingsRequest(dynamicSettings, sourceIndex)).actionGet(); + + // create from source + var destIndex = randomAlphaOfLength(20).toLowerCase(Locale.ROOT); + assertAcked( + client().execute(CreateIndexFromSourceAction.INSTANCE, new CreateIndexFromSourceAction.Request(sourceIndex, destIndex)) + ); + + // assert both static and dynamic settings set on dest index + var settingsResponse = indicesAdmin().getSettings(new GetSettingsRequest().indices(destIndex)).actionGet(); + assertEquals(numReplicas, Integer.parseInt(settingsResponse.getSetting(destIndex, IndexMetadata.SETTING_NUMBER_OF_REPLICAS))); + assertEquals(numShards, Integer.parseInt(settingsResponse.getSetting(destIndex, IndexMetadata.SETTING_NUMBER_OF_SHARDS))); + } + + public void testMappingsCopiedFromSource() { + assumeTrue("requires the migration reindex feature flag", REINDEX_DATA_STREAM_FEATURE_FLAG.isEnabled()); + + var sourceIndex = randomAlphaOfLength(20).toLowerCase(Locale.ROOT); + String mapping = """ + { + "_doc":{ + "dynamic":"strict", + "properties":{ + "foo1":{ + "type":"text" + } + } + } + } + """; + indicesAdmin().create(new CreateIndexRequest(sourceIndex).mapping(mapping)).actionGet(); + + // create from source + var destIndex = randomAlphaOfLength(20).toLowerCase(Locale.ROOT); + assertAcked( + client().execute(CreateIndexFromSourceAction.INSTANCE, new CreateIndexFromSourceAction.Request(sourceIndex, destIndex)) + ); + + var mappingsResponse = indicesAdmin().getMappings(new GetMappingsRequest().indices(sourceIndex, destIndex)).actionGet(); + Map mappings = mappingsResponse.mappings(); + var destMappings = mappings.get(destIndex).sourceAsMap(); + var sourceMappings = mappings.get(sourceIndex).sourceAsMap(); + + assertEquals(sourceMappings, destMappings); + // sanity check specific value from dest mapping + assertEquals("text", XContentMapValues.extractValue("properties.foo1.type", destMappings)); + } + + public void testSettingsOverridden() throws Exception { + assumeTrue("requires the migration reindex feature flag", REINDEX_DATA_STREAM_FEATURE_FLAG.isEnabled()); + + var numShardsSource = randomIntBetween(1, 10); + var numReplicasSource = randomIntBetween(0, 10); + var sourceIndex = randomAlphaOfLength(20).toLowerCase(Locale.ROOT); + var sourceSettings = Settings.builder() + .put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, numShardsSource) + .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, numReplicasSource) + .build(); + indicesAdmin().create(new CreateIndexRequest(sourceIndex, sourceSettings)).get(); + + boolean overrideNumShards = randomBoolean(); + Settings settingsOverride = overrideNumShards + ? Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, numShardsSource + 1).build() + : Settings.builder().put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, numReplicasSource + 1).build(); + + // create from source + var destIndex = randomAlphaOfLength(20).toLowerCase(Locale.ROOT); + assertAcked( + client().execute( + CreateIndexFromSourceAction.INSTANCE, + new CreateIndexFromSourceAction.Request(sourceIndex, destIndex, settingsOverride, Map.of()) + ) + ); + + // assert settings overridden + int expectedShards = overrideNumShards ? numShardsSource + 1 : numShardsSource; + int expectedReplicas = overrideNumShards ? numReplicasSource : numReplicasSource + 1; + var settingsResponse = indicesAdmin().getSettings(new GetSettingsRequest().indices(destIndex)).actionGet(); + assertEquals(expectedShards, Integer.parseInt(settingsResponse.getSetting(destIndex, IndexMetadata.SETTING_NUMBER_OF_SHARDS))); + assertEquals(expectedReplicas, Integer.parseInt(settingsResponse.getSetting(destIndex, IndexMetadata.SETTING_NUMBER_OF_REPLICAS))); + } + + public void testSettingsNullOverride() throws Exception { + assumeTrue("requires the migration reindex feature flag", REINDEX_DATA_STREAM_FEATURE_FLAG.isEnabled()); + + var sourceIndex = randomAlphaOfLength(20).toLowerCase(Locale.ROOT); + var sourceSettings = Settings.builder().put(IndexMetadata.SETTING_BLOCKS_WRITE, true).build(); + indicesAdmin().create(new CreateIndexRequest(sourceIndex, sourceSettings)).get(); + + Settings settingsOverride = Settings.builder().putNull(IndexMetadata.SETTING_BLOCKS_WRITE).build(); + + // create from source + var destIndex = randomAlphaOfLength(20).toLowerCase(Locale.ROOT); + assertAcked( + client().execute( + CreateIndexFromSourceAction.INSTANCE, + new CreateIndexFromSourceAction.Request(sourceIndex, destIndex, settingsOverride, Map.of()) + ) + ); + + // assert settings overridden + var settingsResponse = indicesAdmin().getSettings(new GetSettingsRequest().indices(destIndex)).actionGet(); + assertNull(settingsResponse.getSetting(destIndex, IndexMetadata.SETTING_BLOCKS_WRITE)); + } + + public void testMappingsOverridden() { + assumeTrue("requires the migration reindex feature flag", REINDEX_DATA_STREAM_FEATURE_FLAG.isEnabled()); + + var sourceIndex = randomAlphaOfLength(20).toLowerCase(Locale.ROOT); + String sourceMapping = """ + { + "_doc":{ + "dynamic":"strict", + "properties":{ + "foo1":{ + "type":"text" + }, + "foo2":{ + "type":"boolean" + } + } + } + } + """; + indicesAdmin().create(new CreateIndexRequest(sourceIndex).mapping(sourceMapping)).actionGet(); + + String mappingOverrideStr = """ + { + "_doc":{ + "dynamic":"strict", + "properties":{ + "foo1":{ + "type":"integer" + }, + "foo3": { + "type":"keyword" + } + } + } + } + """; + var mappingOverride = XContentHelper.convertToMap(JsonXContent.jsonXContent, mappingOverrideStr, false); + + // create from source + var destIndex = randomAlphaOfLength(20).toLowerCase(Locale.ROOT); + assertAcked( + client().execute( + CreateIndexFromSourceAction.INSTANCE, + new CreateIndexFromSourceAction.Request(sourceIndex, destIndex, Settings.EMPTY, mappingOverride) + ) + ); + + var mappingsResponse = indicesAdmin().getMappings(new GetMappingsRequest().indices(destIndex)).actionGet(); + Map mappings = mappingsResponse.mappings(); + var destMappings = mappings.get(destIndex).sourceAsMap(); + + String expectedMappingStr = """ + { + "dynamic":"strict", + "properties":{ + "foo1":{ + "type":"integer" + }, + "foo2": { + "type":"boolean" + }, + "foo3": { + "type":"keyword" + } + } + } + """; + var expectedMapping = XContentHelper.convertToMap(JsonXContent.jsonXContent, expectedMappingStr, false); + assertEquals(expectedMapping, destMappings); + } +} diff --git a/x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/ReindexDatastreamIndexIT.java b/x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/ReindexDatastreamIndexTransportActionIT.java similarity index 98% rename from x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/ReindexDatastreamIndexIT.java rename to x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/ReindexDatastreamIndexTransportActionIT.java index e492f035da866..0ca58ecf0f0d5 100644 --- a/x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/ReindexDatastreamIndexIT.java +++ b/x-pack/plugin/migrate/src/internalClusterTest/java/org/elasticsearch/xpack/migrate/action/ReindexDatastreamIndexTransportActionIT.java @@ -53,7 +53,7 @@ import static org.elasticsearch.xpack.migrate.action.ReindexDataStreamAction.REINDEX_DATA_STREAM_FEATURE_FLAG; import static org.hamcrest.Matchers.equalTo; -public class ReindexDatastreamIndexIT extends ESIntegTestCase { +public class ReindexDatastreamIndexTransportActionIT extends ESIntegTestCase { private static final String MAPPING = """ { @@ -126,12 +126,14 @@ public void testDestIndexContainsDocs() throws Exception { assertHitCount(prepareSearch(response.getDestIndex()).setSize(0), numDocs); } - public void testSetSourceToReadOnly() throws Exception { + public void testSetSourceToBlockWrites() throws Exception { assumeTrue("requires the migration reindex feature flag", REINDEX_DATA_STREAM_FEATURE_FLAG.isEnabled()); + var settings = randomBoolean() ? Settings.builder().put(IndexMetadata.SETTING_BLOCKS_WRITE, true).build() : Settings.EMPTY; + // empty source index var sourceIndex = randomAlphaOfLength(20).toLowerCase(Locale.ROOT); - indicesAdmin().create(new CreateIndexRequest(sourceIndex)).get(); + indicesAdmin().create(new CreateIndexRequest(sourceIndex, settings)).get(); // call reindex client().execute(ReindexDataStreamIndexAction.INSTANCE, new ReindexDataStreamIndexAction.Request(sourceIndex)).actionGet(); diff --git a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/MigratePlugin.java b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/MigratePlugin.java index f42d05727b9fd..d9dffdefafa2c 100644 --- a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/MigratePlugin.java +++ b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/MigratePlugin.java @@ -34,6 +34,8 @@ import org.elasticsearch.xcontent.ParseField; import org.elasticsearch.xpack.migrate.action.CancelReindexDataStreamAction; import org.elasticsearch.xpack.migrate.action.CancelReindexDataStreamTransportAction; +import org.elasticsearch.xpack.migrate.action.CreateIndexFromSourceAction; +import org.elasticsearch.xpack.migrate.action.CreateIndexFromSourceTransportAction; import org.elasticsearch.xpack.migrate.action.GetMigrationReindexStatusAction; import org.elasticsearch.xpack.migrate.action.GetMigrationReindexStatusTransportAction; import org.elasticsearch.xpack.migrate.action.ReindexDataStreamAction; @@ -87,6 +89,7 @@ public List getRestHandlers( actions.add(new ActionHandler<>(GetMigrationReindexStatusAction.INSTANCE, GetMigrationReindexStatusTransportAction.class)); actions.add(new ActionHandler<>(CancelReindexDataStreamAction.INSTANCE, CancelReindexDataStreamTransportAction.class)); actions.add(new ActionHandler<>(ReindexDataStreamIndexAction.INSTANCE, ReindexDataStreamIndexTransportAction.class)); + actions.add(new ActionHandler<>(CreateIndexFromSourceAction.INSTANCE, CreateIndexFromSourceTransportAction.class)); } return actions; } diff --git a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/CreateIndexFromSourceAction.java b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/CreateIndexFromSourceAction.java new file mode 100644 index 0000000000000..d67eaee3d251f --- /dev/null +++ b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/CreateIndexFromSourceAction.java @@ -0,0 +1,117 @@ +/* + * 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.migrate.action; + +import org.elasticsearch.action.ActionRequest; +import org.elasticsearch.action.ActionRequestValidationException; +import org.elasticsearch.action.ActionType; +import org.elasticsearch.action.IndicesRequest; +import org.elasticsearch.action.support.IndicesOptions; +import org.elasticsearch.action.support.master.AcknowledgedResponse; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.settings.Settings; + +import java.io.IOException; +import java.util.Map; +import java.util.Objects; + +public class CreateIndexFromSourceAction extends ActionType { + + public static final String NAME = "indices:admin/index/create_from_source"; + + public static final ActionType INSTANCE = new CreateIndexFromSourceAction(); + + private CreateIndexFromSourceAction() { + super(NAME); + } + + public static class Request extends ActionRequest implements IndicesRequest { + + private final String sourceIndex; + private final String destIndex; + private final Settings settingsOverride; + private final Map mappingsOverride; + + public Request(String sourceIndex, String destIndex) { + this(sourceIndex, destIndex, Settings.EMPTY, Map.of()); + } + + public Request(String sourceIndex, String destIndex, Settings settingsOverride, Map mappingsOverride) { + Objects.requireNonNull(mappingsOverride); + this.sourceIndex = sourceIndex; + this.destIndex = destIndex; + this.settingsOverride = settingsOverride; + this.mappingsOverride = mappingsOverride; + } + + @SuppressWarnings("unchecked") + public Request(StreamInput in) throws IOException { + super(in); + this.sourceIndex = in.readString(); + this.destIndex = in.readString(); + this.settingsOverride = Settings.readSettingsFromStream(in); + this.mappingsOverride = (Map) in.readGenericValue(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeString(sourceIndex); + out.writeString(destIndex); + settingsOverride.writeTo(out); + out.writeGenericValue(mappingsOverride); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + public String getSourceIndex() { + return sourceIndex; + } + + public String getDestIndex() { + return destIndex; + } + + public Settings getSettingsOverride() { + return settingsOverride; + } + + public Map getMappingsOverride() { + return mappingsOverride; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Request request = (Request) o; + return Objects.equals(sourceIndex, request.sourceIndex) + && Objects.equals(destIndex, request.destIndex) + && Objects.equals(settingsOverride, request.settingsOverride) + && Objects.equals(mappingsOverride, request.mappingsOverride); + } + + @Override + public int hashCode() { + return Objects.hash(sourceIndex, destIndex, settingsOverride, mappingsOverride); + } + + @Override + public String[] indices() { + return new String[] { sourceIndex }; + } + + @Override + public IndicesOptions indicesOptions() { + return IndicesOptions.strictSingleIndexNoExpandForbidClosed(); + } + } +} diff --git a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/CreateIndexFromSourceTransportAction.java b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/CreateIndexFromSourceTransportAction.java new file mode 100644 index 0000000000000..968b2220628a9 --- /dev/null +++ b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/CreateIndexFromSourceTransportAction.java @@ -0,0 +1,126 @@ +/* + * 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.migrate.action; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; +import org.elasticsearch.action.support.ActionFilters; +import org.elasticsearch.action.support.HandledTransportAction; +import org.elasticsearch.action.support.master.AcknowledgedResponse; +import org.elasticsearch.client.internal.Client; +import org.elasticsearch.cluster.metadata.IndexMetadata; +import org.elasticsearch.cluster.metadata.MappingMetadata; +import org.elasticsearch.cluster.metadata.MetadataCreateIndexService; +import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.compress.CompressedXContent; +import org.elasticsearch.common.settings.IndexScopedSettings; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentHelper; +import org.elasticsearch.core.Nullable; +import org.elasticsearch.index.IndexNotFoundException; +import org.elasticsearch.injection.guice.Inject; +import org.elasticsearch.tasks.Task; +import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.transport.TransportService; +import org.elasticsearch.xcontent.XContentType; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +public class CreateIndexFromSourceTransportAction extends HandledTransportAction< + CreateIndexFromSourceAction.Request, + AcknowledgedResponse> { + private static final Logger logger = LogManager.getLogger(CreateIndexFromSourceTransportAction.class); + + private final ClusterService clusterService; + private final Client client; + private final IndexScopedSettings indexScopedSettings; + + @Inject + public CreateIndexFromSourceTransportAction( + TransportService transportService, + ClusterService clusterService, + ActionFilters actionFilters, + Client client, + IndexScopedSettings indexScopedSettings + ) { + super( + CreateIndexFromSourceAction.NAME, + false, + transportService, + actionFilters, + CreateIndexFromSourceAction.Request::new, + transportService.getThreadPool().executor(ThreadPool.Names.GENERIC) + ); + this.clusterService = clusterService; + this.client = client; + this.indexScopedSettings = indexScopedSettings; + } + + @Override + protected void doExecute(Task task, CreateIndexFromSourceAction.Request request, ActionListener listener) { + + IndexMetadata sourceIndex = clusterService.state().getMetadata().index(request.getSourceIndex()); + + if (sourceIndex == null) { + listener.onFailure(new IndexNotFoundException(request.getSourceIndex())); + return; + } + + logger.debug("Creating destination index [{}] for source index [{}]", request.getDestIndex(), request.getSourceIndex()); + + Settings settings = Settings.builder() + // add source settings + .put(filterSettings(sourceIndex)) + // add override settings from request + .put(request.getSettingsOverride()) + .build(); + + Map mergeMappings; + try { + mergeMappings = mergeMappings(sourceIndex.mapping(), request.getMappingsOverride()); + } catch (IOException e) { + listener.onFailure(e); + return; + } + + var createIndexRequest = new CreateIndexRequest(request.getDestIndex()).settings(settings); + if (mergeMappings.isEmpty() == false) { + createIndexRequest.mapping(mergeMappings); + } + + client.admin().indices().create(createIndexRequest, listener.map(response -> response)); + } + + private static Map toMap(@Nullable MappingMetadata sourceMapping) { + return Optional.ofNullable(sourceMapping) + .map(MappingMetadata::source) + .map(CompressedXContent::uncompressed) + .map(s -> XContentHelper.convertToMap(s, true, XContentType.JSON).v2()) + .orElse(Map.of()); + } + + private static Map mergeMappings(@Nullable MappingMetadata sourceMapping, Map mappingAddition) + throws IOException { + Map combinedMappingMap = new HashMap<>(toMap(sourceMapping)); + XContentHelper.update(combinedMappingMap, mappingAddition, true); + return combinedMappingMap; + } + + // Filter source index settings to subset of settings that can be included during reindex. + // Similar to the settings filtering done when reindexing for upgrade in Kibana + // https://github.com/elastic/kibana/blob/8a8363f02cc990732eb9cbb60cd388643a336bed/x-pack + // /plugins/upgrade_assistant/server/lib/reindexing/index_settings.ts#L155 + private Settings filterSettings(IndexMetadata sourceIndex) { + return MetadataCreateIndexService.copySettingsFromSource(false, sourceIndex.getSettings(), indexScopedSettings, Settings.builder()) + .build(); + } +} diff --git a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamIndexAction.java b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamIndexAction.java index 00c81fdc9fbc6..2e3fd1b76ed32 100644 --- a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamIndexAction.java +++ b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamIndexAction.java @@ -41,10 +41,6 @@ public Request(StreamInput in) throws IOException { this.sourceIndex = in.readString(); } - public static Request readFrom(StreamInput in) throws IOException { - return new Request(in); - } - @Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); diff --git a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamIndexTransportAction.java b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamIndexTransportAction.java index 8863c45691c92..165fd61ae6599 100644 --- a/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamIndexTransportAction.java +++ b/x-pack/plugin/migrate/src/main/java/org/elasticsearch/xpack/migrate/action/ReindexDataStreamIndexTransportAction.java @@ -10,10 +10,10 @@ import org.apache.logging.log4j.Logger; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.action.ActionListener; -import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; -import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; -import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest; +import org.elasticsearch.action.admin.indices.readonly.AddIndexBlockRequest; +import org.elasticsearch.action.admin.indices.readonly.AddIndexBlockResponse; +import org.elasticsearch.action.admin.indices.readonly.TransportAddIndexBlockAction; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.action.support.HandledTransportAction; import org.elasticsearch.action.support.IndicesOptions; @@ -22,9 +22,7 @@ import org.elasticsearch.client.internal.Client; import org.elasticsearch.cluster.block.ClusterBlockException; import org.elasticsearch.cluster.metadata.IndexMetadata; -import org.elasticsearch.cluster.metadata.MetadataCreateIndexService; import org.elasticsearch.cluster.service.ClusterService; -import org.elasticsearch.common.settings.IndexScopedSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.core.TimeValue; import org.elasticsearch.index.reindex.BulkByScrollResponse; @@ -37,28 +35,25 @@ import java.util.Locale; import java.util.Map; -import java.util.Set; + +import static org.elasticsearch.cluster.metadata.IndexMetadata.APIBlock.READ_ONLY; +import static org.elasticsearch.cluster.metadata.IndexMetadata.APIBlock.WRITE; public class ReindexDataStreamIndexTransportAction extends HandledTransportAction< ReindexDataStreamIndexAction.Request, ReindexDataStreamIndexAction.Response> { private static final Logger logger = LogManager.getLogger(ReindexDataStreamIndexTransportAction.class); - - private static final Set SETTINGS_TO_ADD_BACK = Set.of(IndexMetadata.SETTING_BLOCKS_WRITE, IndexMetadata.SETTING_READ_ONLY); - private static final IndicesOptions IGNORE_MISSING_OPTIONS = IndicesOptions.fromOptions(true, true, false, false); private final ClusterService clusterService; private final Client client; - private final IndexScopedSettings indexScopedSettings; @Inject public ReindexDataStreamIndexTransportAction( TransportService transportService, ClusterService clusterService, ActionFilters actionFilters, - Client client, - IndexScopedSettings indexScopedSettings + Client client ) { super( ReindexDataStreamIndexAction.NAME, @@ -70,7 +65,6 @@ public ReindexDataStreamIndexTransportAction( ); this.clusterService = clusterService; this.client = client; - this.indexScopedSettings = indexScopedSettings; } @Override @@ -96,20 +90,19 @@ protected void doExecute( SubscribableListener.newForked(l -> setBlockWrites(sourceIndexName, l)) .andThen(l -> deleteDestIfExists(destIndexName, l)) - .andThen(l -> createIndex(sourceIndex, destIndexName, l)) + .andThen(l -> createIndex(sourceIndex, destIndexName, l)) .andThen(l -> reindex(sourceIndexName, destIndexName, l)) - .andThen(l -> updateSettings(settingsBefore, destIndexName, l)) + .andThen(l -> addBlockIfFromSource(READ_ONLY, settingsBefore, destIndexName, l)) + .andThen(l -> addBlockIfFromSource(WRITE, settingsBefore, destIndexName, l)) .andThenApply(ignored -> new ReindexDataStreamIndexAction.Response(destIndexName)) .addListener(listener); } private void setBlockWrites(String sourceIndexName, ActionListener listener) { logger.debug("Setting write block on source index [{}]", sourceIndexName); - final Settings readOnlySettings = Settings.builder().put(IndexMetadata.INDEX_BLOCKS_WRITE_SETTING.getKey(), true).build(); - var updateSettingsRequest = new UpdateSettingsRequest(readOnlySettings, sourceIndexName); - client.admin().indices().updateSettings(updateSettingsRequest, new ActionListener<>() { + addBlockToIndex(WRITE, sourceIndexName, new ActionListener<>() { @Override - public void onResponse(AcknowledgedResponse response) { + public void onResponse(AddIndexBlockResponse response) { if (response.isAcknowledged()) { listener.onResponse(null); } else { @@ -121,7 +114,7 @@ public void onResponse(AcknowledgedResponse response) { @Override public void onFailure(Exception e) { if (e instanceof ClusterBlockException || e.getCause() instanceof ClusterBlockException) { - // It's fine if read-only is already set + // It's fine if block-writes is already set listener.onResponse(null); } else { listener.onFailure(e); @@ -138,18 +131,23 @@ private void deleteDestIfExists(String destIndexName, ActionListener listener) { + private void createIndex(IndexMetadata sourceIndex, String destIndexName, ActionListener listener) { logger.debug("Creating destination index [{}] for source index [{}]", destIndexName, sourceIndex.getIndex().getName()); - // Create destination with subset of source index settings that can be added before reindex - var settings = getPreSettings(sourceIndex); - - var sourceMapping = sourceIndex.mapping(); - Map mapping = sourceMapping != null ? sourceMapping.rawSourceAsMap() : Map.of(); - var createIndexRequest = new CreateIndexRequest(destIndexName).settings(settings).mapping(mapping); - - var errorMessage = String.format(Locale.ROOT, "Could not create index [%s]", destIndexName); - client.admin().indices().create(createIndexRequest, failIfNotAcknowledged(listener, errorMessage)); + // override read-only settings if they exist + var removeReadOnlyOverride = Settings.builder() + .putNull(IndexMetadata.SETTING_READ_ONLY) + .putNull(IndexMetadata.SETTING_BLOCKS_WRITE) + .build(); + + var request = new CreateIndexFromSourceAction.Request( + sourceIndex.getIndex().getName(), + destIndexName, + removeReadOnlyOverride, + Map.of() + ); + var errorMessage = String.format(Locale.ROOT, "Could not create index [%s]", request.getDestIndex()); + client.execute(CreateIndexFromSourceAction.INSTANCE, request, failIfNotAcknowledged(listener, errorMessage)); } private void reindex(String sourceIndexName, String destIndexName, ActionListener listener) { @@ -162,35 +160,18 @@ private void reindex(String sourceIndexName, String destIndexName, ActionListene client.execute(ReindexAction.INSTANCE, reindexRequest, listener); } - private void updateSettings(Settings settingsBefore, String destIndexName, ActionListener listener) { - logger.debug("Adding settings from source index that could not be added before reindex"); - - Settings postSettings = getPostSettings(settingsBefore); - if (postSettings.isEmpty()) { + private void addBlockIfFromSource( + IndexMetadata.APIBlock block, + Settings settingsBefore, + String destIndexName, + ActionListener listener + ) { + if (settingsBefore.getAsBoolean(block.settingName(), false)) { + var errorMessage = String.format(Locale.ROOT, "Add [%s] block to index [%s] was not acknowledged", block.name(), destIndexName); + addBlockToIndex(block, destIndexName, failIfNotAcknowledged(listener, errorMessage)); + } else { listener.onResponse(null); - return; } - - var updateSettingsRequest = new UpdateSettingsRequest(postSettings, destIndexName); - var errorMessage = String.format(Locale.ROOT, "Could not update settings on index [%s]", destIndexName); - client.admin().indices().updateSettings(updateSettingsRequest, failIfNotAcknowledged(listener, errorMessage)); - } - - // Filter source index settings to subset of settings that can be included during reindex. - // Similar to the settings filtering done when reindexing for upgrade in Kibana - // https://github.com/elastic/kibana/blob/8a8363f02cc990732eb9cbb60cd388643a336bed/x-pack - // /plugins/upgrade_assistant/server/lib/reindexing/index_settings.ts#L155 - private Settings getPreSettings(IndexMetadata sourceIndex) { - // filter settings that will be added back later - var filtered = sourceIndex.getSettings().filter(settingName -> SETTINGS_TO_ADD_BACK.contains(settingName) == false); - - // filter private and non-copyable settings - var builder = MetadataCreateIndexService.copySettingsFromSource(false, filtered, indexScopedSettings, Settings.builder()); - return builder.build(); - } - - private Settings getPostSettings(Settings settingsBefore) { - return settingsBefore.filter(SETTINGS_TO_ADD_BACK::contains); } public static String generateDestIndexName(String sourceIndex) { @@ -201,11 +182,16 @@ private static ActionListener failIfNotAckno ActionListener listener, String errorMessage ) { - return listener.delegateFailureAndWrap((delegate, response) -> { + return listener.delegateFailure((delegate, response) -> { if (response.isAcknowledged()) { delegate.onResponse(null); + } else { + delegate.onFailure(new ElasticsearchException(errorMessage)); } - throw new ElasticsearchException(errorMessage); }); } + + private void addBlockToIndex(IndexMetadata.APIBlock block, String index, ActionListener listener) { + client.admin().indices().execute(TransportAddIndexBlockAction.TYPE, new AddIndexBlockRequest(block, index), listener); + } } diff --git a/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java b/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java index c07e4b2c541a2..1cb73de4646cc 100644 --- a/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java +++ b/x-pack/plugin/security/qa/operator-privileges-tests/src/javaRestTest/java/org/elasticsearch/xpack/security/operator/Constants.java @@ -641,6 +641,7 @@ public class Constants { new FeatureFlag("reindex_data_stream").isEnabled() ? "indices:admin/data_stream/index/reindex" : null, new FeatureFlag("reindex_data_stream").isEnabled() ? "indices:admin/data_stream/reindex" : null, new FeatureFlag("reindex_data_stream").isEnabled() ? "indices:admin/data_stream/reindex_cancel" : null, + new FeatureFlag("reindex_data_stream").isEnabled() ? "indices:admin/index/create_from_source" : null, "internal:admin/repository/verify", "internal:admin/repository/verify/coordinate" ).filter(Objects::nonNull).collect(Collectors.toUnmodifiableSet()); From dadf875bdf2267e50b12cc6455b3ee1fa3365023 Mon Sep 17 00:00:00 2001 From: Luca Cavanna Date: Wed, 18 Dec 2024 18:11:14 +0100 Subject: [PATCH 58/60] Push removal of search workers pool setting to v10 (#118877) The search workers thread pool has been removed in 8.16. We still support parsing its size and queue size settings, to prevent issues upon upgrade for users that may have customized them. We will provide such compatibility for the entire 9.x series. --- .../main/java/org/elasticsearch/node/NodeConstruction.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/server/src/main/java/org/elasticsearch/node/NodeConstruction.java b/server/src/main/java/org/elasticsearch/node/NodeConstruction.java index 17e56a392daff..5cfe1c104d45e 100644 --- a/server/src/main/java/org/elasticsearch/node/NodeConstruction.java +++ b/server/src/main/java/org/elasticsearch/node/NodeConstruction.java @@ -83,7 +83,7 @@ import org.elasticsearch.core.SuppressForbidden; import org.elasticsearch.core.TimeValue; import org.elasticsearch.core.Tuple; -import org.elasticsearch.core.UpdateForV9; +import org.elasticsearch.core.UpdateForV10; import org.elasticsearch.discovery.DiscoveryModule; import org.elasticsearch.env.Environment; import org.elasticsearch.env.NodeEnvironment; @@ -553,9 +553,10 @@ private SettingsModule validateSettings(Settings envSettings, Settings settings, return settingsModule; } - @UpdateForV9(owner = UpdateForV9.Owner.SEARCH_FOUNDATIONS) + @UpdateForV10(owner = UpdateForV10.Owner.SEARCH_FOUNDATIONS) private static void addBwcSearchWorkerSettings(List> additionalSettings) { - // TODO remove the below settings, they are unused and only here to enable BwC for deployments that still use them + // Search workers thread pool has been removed in Elasticsearch 8.16.0. These settings are deprecated and take no effect. + // They are here only to enable BwC for deployments that still use them additionalSettings.add( Setting.intSetting("thread_pool.search_worker.queue_size", 0, Setting.Property.NodeScope, Setting.Property.DeprecatedWarning) ); From 76b2968360dc4e71309e3b43dc18e6f41a142651 Mon Sep 17 00:00:00 2001 From: Niels Bauman <33722607+nielsbauman@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:30:58 +0100 Subject: [PATCH 59/60] Disable SLM history in docs tests (#118979) The SLM history data stream was causing issues in the docs tests because its presence was flaky and could result in the inability to remove its index template, which in turn resulted in failing tests. --- docs/build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/build.gradle b/docs/build.gradle index dec0de8ffa844..93b7277327280 100644 --- a/docs/build.gradle +++ b/docs/build.gradle @@ -130,8 +130,9 @@ testClusters.matching { it.name == "yamlRestTest"}.configureEach { setting 'xpack.security.enabled', 'true' setting 'xpack.security.authc.api_key.enabled', 'true' setting 'xpack.security.authc.token.enabled', 'true' - // disable the ILM history for doc tests to avoid potential lingering tasks that'd cause test flakiness + // disable the ILM and SLM history for doc tests to avoid potential lingering tasks that'd cause test flakiness setting 'indices.lifecycle.history_index_enabled', 'false' + setting 'slm.history_index_enabled', 'false' setting 'xpack.license.self_generated.type', 'trial' setting 'xpack.security.authc.realms.file.file.order', '0' setting 'xpack.security.authc.realms.native.native.order', '1' From 5663efa5e344397d423eefd52d6a06e4fda9b70e Mon Sep 17 00:00:00 2001 From: Martijn van Groningen Date: Wed, 18 Dec 2024 18:38:54 +0100 Subject: [PATCH 60/60] Just mute the bad apple (#118989) --- muted-tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/muted-tests.yml b/muted-tests.yml index f534f24718f52..a06334146ed7b 100644 --- a/muted-tests.yml +++ b/muted-tests.yml @@ -289,6 +289,7 @@ tests: method: testThreadContext issue: https://github.com/elastic/elasticsearch/issues/118914 - class: org.elasticsearch.smoketest.SmokeTestMultiNodeClientYamlTestSuiteIT + method: test {yaml=indices.create/20_synthetic_source/create index with use_synthetic_source} issue: https://github.com/elastic/elasticsearch/issues/118955 - class: org.elasticsearch.repositories.blobstore.testkit.analyze.SecureHdfsRepositoryAnalysisRestIT issue: https://github.com/elastic/elasticsearch/issues/118970

    -TwGoV8w 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 %C|c?Yz9+ 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%0Dk$33i672kD0l-!J8OF;K!Y*GrGyD3q2lS;Kiu1 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