|
8 | 8 |
|
9 | 9 | import org.elasticsearch.action.ActionFuture;
|
10 | 10 | import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse;
|
| 11 | +import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotAction; |
| 12 | +import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; |
| 13 | +import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse; |
11 | 14 | import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotStatus;
|
12 | 15 | import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusResponse;
|
13 | 16 | import org.elasticsearch.action.index.IndexRequestBuilder;
|
|
22 | 25 | import org.elasticsearch.plugins.Plugin;
|
23 | 26 | import org.elasticsearch.repositories.RepositoriesService;
|
24 | 27 | import org.elasticsearch.repositories.RepositoryException;
|
| 28 | +import org.elasticsearch.rest.RestStatus; |
25 | 29 | import org.elasticsearch.snapshots.ConcurrentSnapshotExecutionException;
|
26 | 30 | import org.elasticsearch.snapshots.SnapshotInfo;
|
27 | 31 | import org.elasticsearch.snapshots.SnapshotMissingException;
|
|
31 | 35 | import org.elasticsearch.xpack.core.LocalStateCompositeXPackPlugin;
|
32 | 36 | import org.elasticsearch.xpack.core.XPackSettings;
|
33 | 37 | import org.elasticsearch.xpack.core.ilm.LifecycleSettings;
|
| 38 | +import org.elasticsearch.xpack.core.slm.SnapshotInvocationRecord; |
34 | 39 | import org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicy;
|
35 | 40 | import org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicyItem;
|
36 | 41 | import org.elasticsearch.xpack.core.slm.SnapshotRetentionConfiguration;
|
@@ -415,6 +420,74 @@ private void testUnsuccessfulSnapshotRetention(boolean partialSuccess) throws Ex
|
415 | 420 | }
|
416 | 421 | }
|
417 | 422 |
|
| 423 | + public void testSLMRetentionAfterRestore() throws Exception { |
| 424 | + final String indexName = "test"; |
| 425 | + final String policyName = "test-policy"; |
| 426 | + int docCount = 20; |
| 427 | + for (int i = 0; i < docCount; i++) { |
| 428 | + index(indexName, "_doc", i + "", Collections.singletonMap("foo", "bar")); |
| 429 | + } |
| 430 | + |
| 431 | + // Create a snapshot repo |
| 432 | + initializeRepo(REPO); |
| 433 | + |
| 434 | + logger.info("--> creating policy {}", policyName); |
| 435 | + createSnapshotPolicy(policyName, "snap", NEVER_EXECUTE_CRON_SCHEDULE, REPO, indexName, true, false, |
| 436 | + new SnapshotRetentionConfiguration(TimeValue.ZERO, null, null)); |
| 437 | + |
| 438 | + logger.info("--> executing snapshot lifecycle"); |
| 439 | + final String snapshotName = executePolicy(policyName); |
| 440 | + |
| 441 | + // Check that the executed snapshot shows up in the SLM output |
| 442 | + assertBusy(() -> { |
| 443 | + GetSnapshotLifecycleAction.Response getResp = |
| 444 | + client().execute(GetSnapshotLifecycleAction.INSTANCE, new GetSnapshotLifecycleAction.Request(policyName)).get(); |
| 445 | + logger.info("--> checking for in progress snapshot..."); |
| 446 | + |
| 447 | + assertThat(getResp.getPolicies().size(), greaterThan(0)); |
| 448 | + SnapshotLifecyclePolicyItem item = getResp.getPolicies().get(0); |
| 449 | + SnapshotInvocationRecord lastSuccess = item.getLastSuccess(); |
| 450 | + assertNotNull(lastSuccess); |
| 451 | + assertThat(lastSuccess.getSnapshotName(), equalTo(snapshotName)); |
| 452 | + }); |
| 453 | + |
| 454 | + logger.info("--> restoring index"); |
| 455 | + RestoreSnapshotRequest restoreReq = new RestoreSnapshotRequest(REPO, snapshotName); |
| 456 | + restoreReq.indices(indexName); |
| 457 | + restoreReq.renamePattern("(.+)"); |
| 458 | + restoreReq.renameReplacement("restored_$1"); |
| 459 | + restoreReq.waitForCompletion(true); |
| 460 | + RestoreSnapshotResponse resp = client().execute(RestoreSnapshotAction.INSTANCE, restoreReq).get(); |
| 461 | + assertThat(resp.status(), equalTo(RestStatus.OK)); |
| 462 | + |
| 463 | + logger.info("--> executing SLM retention"); |
| 464 | + assertAcked(client().execute(ExecuteSnapshotRetentionAction.INSTANCE, new ExecuteSnapshotRetentionAction.Request()).get()); |
| 465 | + logger.info("--> waiting for {} snapshot to be deleted", snapshotName); |
| 466 | + assertBusy(() -> { |
| 467 | + try { |
| 468 | + try { |
| 469 | + GetSnapshotsResponse snapshotsStatusResponse = client().admin().cluster() |
| 470 | + .prepareGetSnapshots(REPO).setSnapshots(snapshotName).get(); |
| 471 | + assertThat(snapshotsStatusResponse.getSnapshots(), empty()); |
| 472 | + } catch (SnapshotMissingException e) { |
| 473 | + // This is what we want to happen |
| 474 | + } |
| 475 | + logger.info("--> snapshot [{}] has been deleted", snapshotName); |
| 476 | + } catch (RepositoryException re) { |
| 477 | + // Concurrent status calls and write operations may lead to failures in determining the current repository generation |
| 478 | + // TODO: Remove this hack once tracking the current repository generation has been made consistent |
| 479 | + throw new AssertionError(re); |
| 480 | + } |
| 481 | + }); |
| 482 | + |
| 483 | + // Cancel/delete the snapshot |
| 484 | + try { |
| 485 | + client().admin().cluster().prepareDeleteSnapshot(REPO, snapshotName).get(); |
| 486 | + } catch (SnapshotMissingException e) { |
| 487 | + // ignore |
| 488 | + } |
| 489 | + } |
| 490 | + |
418 | 491 | private SnapshotsStatusResponse getSnapshotStatus(String snapshotName) {
|
419 | 492 | try {
|
420 | 493 | return client().admin().cluster().prepareSnapshotStatus(REPO).setSnapshots(snapshotName).get();
|
|
0 commit comments