Skip to content

Commit 8294191

Browse files
authored
Merge branch 'main' into markjhoy/add_sparse_vector_token_pruning_index_options
2 parents 6307f93 + 5adce8e commit 8294191

File tree

20 files changed

+334
-11
lines changed

20 files changed

+334
-11
lines changed

docs/changelog/128635.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 128635
2+
summary: Add `state` query param to Get snapshots API
3+
area: Snapshot/Restore
4+
type: enhancement
5+
issues:
6+
- 97446

docs/changelog/129455.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 129455
2+
summary: Prevent ILM from processing shrunken index before its execution state is copied over
3+
area: ILM+SLM
4+
type: bug
5+
issues:
6+
- 109206

muted-tests.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,12 @@ tests:
562562
- class: org.elasticsearch.xpack.security.PermissionsIT
563563
method: testWhenUserLimitedByOnlyAliasOfIndexCanWriteToIndexWhichWasRolledoverByILMPolicy
564564
issue: https://github.com/elastic/elasticsearch/issues/129481
565+
- class: org.elasticsearch.xpack.ilm.TimeSeriesLifecycleActionsIT
566+
method: testFullPolicy
567+
issue: https://github.com/elastic/elasticsearch/issues/129510
568+
- class: org.elasticsearch.xpack.esql.qa.multi_node.EsqlSpecIT
569+
method: test {knn-function.KnnSearchWithKOption SYNC}
570+
issue: https://github.com/elastic/elasticsearch/issues/129512
565571

566572
# Examples:
567573
#

qa/vector/build.gradle

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,12 @@ tasks.register("checkVec", JavaExec) {
4242
systemProperty "es.logger.out", "console"
4343
systemProperty "es.logger.level", "INFO" // Change to DEBUG if needed
4444
systemProperty 'es.nativelibs.path', TestUtil.getTestLibraryPath(file("../../libs/native/libraries/build/platform/").toString())
45-
45+
jvmArgs '-Xms4g', '-Xmx4g', '-Djava.util.concurrent.ForkJoinPool.common.parallelism=8', '-XX:+UnlockDiagnosticVMOptions', '-XX:+DebugNonSafepoints', '-XX:+HeapDumpOnOutOfMemoryError'
4646
if (buildParams.getRuntimeJavaVersion().map { it.majorVersion.toInteger() }.get() >= 21) {
47-
jvmArgs '-Xms4g', '-Xmx4g', '--add-modules=jdk.incubator.vector', '--enable-native-access=ALL-UNNAMED', '-Djava.util.concurrent.ForkJoinPool.common.parallelism=8', '-XX:+UnlockDiagnosticVMOptions', '-XX:+DebugNonSafepoints', '-XX:+HeapDumpOnOutOfMemoryError'
47+
jvmArgs '--add-modules=jdk.incubator.vector', '--enable-native-access=ALL-UNNAMED'
48+
}
49+
if (System.getenv("DO_PROFILING") != null) {
50+
jvmArgs '-XX:StartFlightRecording=dumponexit=true,maxsize=250M,filename=knn.jfr,settings=profile.jfc'
4851
}
4952
}
5053

rest-api-spec/src/main/resources/rest-api-spec/api/snapshot.get.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@
8585
"verbose":{
8686
"type":"boolean",
8787
"description":"Whether to show verbose snapshot info or only show the basic info found in the repository index blob"
88+
},
89+
"state": {
90+
"type": "list",
91+
"description": "Filter snapshots by a comma-separated list of states. Valid state values are 'SUCCESS', 'IN_PROGRESS', 'FAILED', 'PARTIAL', or 'INCOMPATIBLE'."
8892
}
8993
}
9094
}

rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/snapshot.get/10_basic.yml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,3 +303,72 @@ setup:
303303
snapshot.delete:
304304
repository: test_repo_get_1
305305
snapshot: test_snapshot_no_repo_name
306+
307+
---
308+
"Get snapshot using state parameter":
309+
- requires:
310+
cluster_features: "snapshots.get.state_parameter"
311+
test_runner_features: capabilities
312+
capabilities:
313+
- method: GET
314+
path: /_snapshot/{repository}/{snapshot}
315+
parameters: [ state ]
316+
reason: "state parameter was introduced in 9.1"
317+
318+
- do:
319+
indices.create:
320+
index: test_index
321+
body:
322+
settings:
323+
number_of_shards: 1
324+
number_of_replicas: 0
325+
326+
- do:
327+
snapshot.create:
328+
repository: test_repo_get_1
329+
snapshot: test_snapshot_with_state_param
330+
wait_for_completion: true
331+
332+
- do:
333+
snapshot.get:
334+
repository: test_repo_get_1
335+
snapshot: test_snapshot_with_state_param
336+
state: SUCCESS
337+
338+
- is_true: snapshots
339+
- match: { snapshots.0.snapshot: test_snapshot_with_state_param }
340+
- match: { snapshots.0.state: SUCCESS }
341+
342+
- do:
343+
snapshot.get:
344+
repository: test_repo_get_1
345+
snapshot: test_snapshot_with_state_param
346+
state: SUCCESS,PARTIAL
347+
348+
- is_true: snapshots
349+
- match: { snapshots.0.snapshot: test_snapshot_with_state_param }
350+
- match: { snapshots.0.state: SUCCESS }
351+
352+
- do:
353+
snapshot.get:
354+
repository: test_repo_get_1
355+
snapshot: test_snapshot_with_state_param
356+
state: FAILED
357+
358+
- is_true: snapshots
359+
- length: { snapshots: 0 }
360+
361+
- do:
362+
catch: bad_request
363+
snapshot.get:
364+
repository: test_repo_get_1
365+
snapshot: test_snapshot_with_state_param
366+
state: FOO
367+
368+
- match: { error.type: "illegal_argument_exception" }
369+
- match: { error.reason: "No enum constant org.elasticsearch.snapshots.SnapshotState.FOO" }
370+
371+
- do:
372+
snapshot.delete:
373+
repository: test_repo_get_1
374+
snapshot: test_snapshot_with_state_param

server/src/internalClusterTest/java/org/elasticsearch/snapshots/GetSnapshotsIT.java

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,16 @@
5555
import java.nio.file.Files;
5656
import java.nio.file.Path;
5757
import java.util.ArrayList;
58+
import java.util.Arrays;
5859
import java.util.Collection;
5960
import java.util.Collections;
61+
import java.util.EnumSet;
6062
import java.util.HashSet;
6163
import java.util.List;
6264
import java.util.Map;
6365
import java.util.Objects;
6466
import java.util.Set;
67+
import java.util.function.Function;
6568
import java.util.function.Predicate;
6669
import java.util.stream.Collectors;
6770

@@ -635,6 +638,63 @@ public void testRetrievingSnapshotsWhenRepositoryIsMissing() throws Exception {
635638
expectThrows(RepositoryMissingException.class, multiRepoFuture::actionGet);
636639
}
637640

641+
public void testFilterByState() throws Exception {
642+
final String repoName = "test-repo";
643+
final Path repoPath = randomRepoPath();
644+
createRepository(repoName, "mock", repoPath);
645+
646+
// Create a successful snapshot
647+
createFullSnapshot(repoName, "snapshot-success");
648+
649+
final Function<EnumSet<SnapshotState>, List<SnapshotInfo>> getSnapshotsForStates = (states) -> {
650+
return clusterAdmin().prepareGetSnapshots(TEST_REQUEST_TIMEOUT, repoName).setStates(states).get().getSnapshots();
651+
};
652+
653+
// Fetch snapshots with state=SUCCESS
654+
var snapshots = getSnapshotsForStates.apply(EnumSet.of(SnapshotState.SUCCESS));
655+
assertThat(snapshots, hasSize(1));
656+
assertThat(snapshots.getFirst().state(), is(SnapshotState.SUCCESS));
657+
658+
// Create a snapshot in progress
659+
blockAllDataNodes(repoName);
660+
startFullSnapshot(repoName, "snapshot-in-progress");
661+
awaitNumberOfSnapshotsInProgress(1);
662+
663+
// Fetch snapshots with state=IN_PROGRESS
664+
snapshots = getSnapshotsForStates.apply(EnumSet.of(SnapshotState.IN_PROGRESS));
665+
assertThat(snapshots, hasSize(1));
666+
assertThat(snapshots.getFirst().state(), is(SnapshotState.IN_PROGRESS));
667+
668+
// Fetch snapshots with multiple states (SUCCESS, IN_PROGRESS)
669+
snapshots = getSnapshotsForStates.apply(EnumSet.of(SnapshotState.SUCCESS, SnapshotState.IN_PROGRESS));
670+
assertThat(snapshots, hasSize(2));
671+
var states = snapshots.stream().map(SnapshotInfo::state).collect(Collectors.toSet());
672+
assertTrue(states.contains(SnapshotState.SUCCESS));
673+
assertTrue(states.contains(SnapshotState.IN_PROGRESS));
674+
675+
// Fetch all snapshots (without state)
676+
snapshots = clusterAdmin().prepareGetSnapshots(TEST_REQUEST_TIMEOUT, repoName).get().getSnapshots();
677+
assertThat(snapshots, hasSize(2));
678+
679+
// Fetch snapshots with an invalid state
680+
IllegalArgumentException e = expectThrows(
681+
IllegalArgumentException.class,
682+
() -> getSnapshotsForStates.apply(EnumSet.of(SnapshotState.valueOf("FOO")))
683+
);
684+
assertThat(e.getMessage(), is("No enum constant org.elasticsearch.snapshots.SnapshotState.FOO"));
685+
686+
// Allow the IN_PROGRESS snapshot to finish, then verify GET using SUCCESS has results and IN_PROGRESS does not.
687+
unblockAllDataNodes(repoName);
688+
awaitNumberOfSnapshotsInProgress(0);
689+
snapshots = clusterAdmin().prepareGetSnapshots(TEST_REQUEST_TIMEOUT, repoName).get().getSnapshots();
690+
assertThat(snapshots, hasSize(2));
691+
states = snapshots.stream().map(SnapshotInfo::state).collect(Collectors.toSet());
692+
assertThat(states, hasSize(1));
693+
assertTrue(states.contains(SnapshotState.SUCCESS));
694+
snapshots = getSnapshotsForStates.apply(EnumSet.of(SnapshotState.IN_PROGRESS));
695+
assertThat(snapshots, hasSize(0));
696+
}
697+
638698
public void testRetrievingSnapshotsWhenRepositoryIsUnreadable() throws Exception {
639699
final String repoName = randomIdentifier();
640700
final Path repoPath = randomRepoPath();
@@ -956,6 +1016,12 @@ public void testAllFeatures() {
9561016
// INDICES and by SHARDS. The actual sorting behaviour for these cases is tested elsewhere, here we're just checking that sorting
9571017
// interacts correctly with the other parameters to the API.
9581018

1019+
final EnumSet<SnapshotState> states = EnumSet.copyOf(randomNonEmptySubsetOf(Arrays.asList(SnapshotState.values())));
1020+
// Note: The selected state(s) may not match any existing snapshots.
1021+
// The actual filtering behaviour for such cases is tested in the dedicated test.
1022+
// Here we're just checking that states interacts correctly with the other parameters to the API.
1023+
snapshotInfoPredicate = snapshotInfoPredicate.and(si -> states.contains(si.state()));
1024+
9591025
// compute the ordered sequence of snapshots which match the repository/snapshot name filters and SLM policy filter
9601026
final var selectedSnapshots = snapshotInfos.stream()
9611027
.filter(snapshotInfoPredicate)
@@ -967,7 +1033,8 @@ public void testAllFeatures() {
9671033
)
9681034
// apply sorting params
9691035
.sort(sortKey)
970-
.order(order);
1036+
.order(order)
1037+
.states(states);
9711038

9721039
// sometimes use ?from_sort_value to skip some items; note that snapshots skipped in this way are subtracted from
9731040
// GetSnapshotsResponse.totalCount whereas snapshots skipped by ?after and ?offset are not
@@ -1054,7 +1121,8 @@ public void testAllFeatures() {
10541121
.sort(sortKey)
10551122
.order(order)
10561123
.size(nextSize)
1057-
.after(SnapshotSortKey.decodeAfterQueryParam(nextRequestAfter));
1124+
.after(SnapshotSortKey.decodeAfterQueryParam(nextRequestAfter))
1125+
.states(states);
10581126
final GetSnapshotsResponse nextResponse = safeAwait(l -> client().execute(TransportGetSnapshotsAction.TYPE, nextRequest, l));
10591127

10601128
assertEquals(

server/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@
425425
org.elasticsearch.action.bulk.BulkFeatures,
426426
org.elasticsearch.features.InfrastructureFeatures,
427427
org.elasticsearch.rest.action.admin.cluster.ClusterRerouteFeatures,
428+
org.elasticsearch.rest.action.admin.cluster.GetSnapshotsFeatures,
428429
org.elasticsearch.index.mapper.MapperFeatures,
429430
org.elasticsearch.index.IndexFeatures,
430431
org.elasticsearch.search.SearchFeatures,

server/src/main/java/org/elasticsearch/TransportVersions.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,11 @@ static TransportVersion def(int id) {
300300
public static final TransportVersion NONE_CHUNKING_STRATEGY = def(9_097_0_00);
301301
public static final TransportVersion PROJECT_DELETION_GLOBAL_BLOCK = def(9_098_0_00);
302302
public static final TransportVersion SECURITY_CLOUD_API_KEY_REALM_AND_TYPE = def(9_099_0_00);
303+
<<<<<<< markjhoy/add_sparse_vector_token_pruning_index_options
303304
public static final TransportVersion SPARSE_VECTOR_FIELD_PRUNING_OPTIONS = def(9_100_0_00);
305+
=======
306+
public static final TransportVersion STATE_PARAM_GET_SNAPSHOT = def(9_100_0_00);
307+
>>>>>>> main
304308

305309
/*
306310
* STOP! READ THIS FIRST! No, really,

server/src/main/java/org/elasticsearch/action/ActionModule.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,7 @@ public void initRestHandlers(Supplier<DiscoveryNodes> nodesInCluster, Predicate<
864864
registerHandler.accept(new RestDeleteRepositoryAction());
865865
registerHandler.accept(new RestVerifyRepositoryAction());
866866
registerHandler.accept(new RestCleanupRepositoryAction());
867-
registerHandler.accept(new RestGetSnapshotsAction());
867+
registerHandler.accept(new RestGetSnapshotsAction(clusterSupportsFeature));
868868
registerHandler.accept(new RestCreateSnapshotAction());
869869
registerHandler.accept(new RestCloneSnapshotAction());
870870
registerHandler.accept(new RestRestoreSnapshotAction());

0 commit comments

Comments
 (0)