|
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;
|
|
30 | 34 | import org.elasticsearch.test.ESIntegTestCase;
|
31 | 35 | import org.elasticsearch.xpack.core.LocalStateCompositeXPackPlugin;
|
32 | 36 | import org.elasticsearch.xpack.core.ilm.LifecycleSettings;
|
| 37 | +import org.elasticsearch.xpack.core.slm.SnapshotInvocationRecord; |
33 | 38 | import org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicy;
|
34 | 39 | import org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicyItem;
|
35 | 40 | import org.elasticsearch.xpack.core.slm.SnapshotRetentionConfiguration;
|
@@ -385,6 +390,74 @@ private void testUnsuccessfulSnapshotRetention(boolean partialSuccess) throws Ex
|
385 | 390 | }
|
386 | 391 | }
|
387 | 392 |
|
| 393 | + public void testSLMRetentionAfterRestore() throws Exception { |
| 394 | + final String indexName = "test"; |
| 395 | + final String policyName = "test-policy"; |
| 396 | + int docCount = 20; |
| 397 | + for (int i = 0; i < docCount; i++) { |
| 398 | + index(indexName, i + "", Collections.singletonMap("foo", "bar")); |
| 399 | + } |
| 400 | + |
| 401 | + // Create a snapshot repo |
| 402 | + initializeRepo(REPO); |
| 403 | + |
| 404 | + logger.info("--> creating policy {}", policyName); |
| 405 | + createSnapshotPolicy(policyName, "snap", NEVER_EXECUTE_CRON_SCHEDULE, REPO, indexName, true, false, |
| 406 | + new SnapshotRetentionConfiguration(TimeValue.ZERO, null, null)); |
| 407 | + |
| 408 | + logger.info("--> executing snapshot lifecycle"); |
| 409 | + final String snapshotName = executePolicy(policyName); |
| 410 | + |
| 411 | + // Check that the executed snapshot shows up in the SLM output |
| 412 | + assertBusy(() -> { |
| 413 | + GetSnapshotLifecycleAction.Response getResp = |
| 414 | + client().execute(GetSnapshotLifecycleAction.INSTANCE, new GetSnapshotLifecycleAction.Request(policyName)).get(); |
| 415 | + logger.info("--> checking for in progress snapshot..."); |
| 416 | + |
| 417 | + assertThat(getResp.getPolicies().size(), greaterThan(0)); |
| 418 | + SnapshotLifecyclePolicyItem item = getResp.getPolicies().get(0); |
| 419 | + SnapshotInvocationRecord lastSuccess = item.getLastSuccess(); |
| 420 | + assertNotNull(lastSuccess); |
| 421 | + assertThat(lastSuccess.getSnapshotName(), equalTo(snapshotName)); |
| 422 | + }); |
| 423 | + |
| 424 | + logger.info("--> restoring index"); |
| 425 | + RestoreSnapshotRequest restoreReq = new RestoreSnapshotRequest(REPO, snapshotName); |
| 426 | + restoreReq.indices(indexName); |
| 427 | + restoreReq.renamePattern("(.+)"); |
| 428 | + restoreReq.renameReplacement("restored_$1"); |
| 429 | + restoreReq.waitForCompletion(true); |
| 430 | + RestoreSnapshotResponse resp = client().execute(RestoreSnapshotAction.INSTANCE, restoreReq).get(); |
| 431 | + assertThat(resp.status(), equalTo(RestStatus.OK)); |
| 432 | + |
| 433 | + logger.info("--> executing SLM retention"); |
| 434 | + assertAcked(client().execute(ExecuteSnapshotRetentionAction.INSTANCE, new ExecuteSnapshotRetentionAction.Request()).get()); |
| 435 | + logger.info("--> waiting for {} snapshot to be deleted", snapshotName); |
| 436 | + assertBusy(() -> { |
| 437 | + try { |
| 438 | + try { |
| 439 | + GetSnapshotsResponse snapshotsStatusResponse = client().admin().cluster() |
| 440 | + .prepareGetSnapshots(REPO).setSnapshots(snapshotName).get(); |
| 441 | + assertThat(snapshotsStatusResponse.getSnapshots(REPO), empty()); |
| 442 | + } catch (SnapshotMissingException e) { |
| 443 | + // This is what we want to happen |
| 444 | + } |
| 445 | + logger.info("--> snapshot [{}] has been deleted", snapshotName); |
| 446 | + } catch (RepositoryException re) { |
| 447 | + // Concurrent status calls and write operations may lead to failures in determining the current repository generation |
| 448 | + // TODO: Remove this hack once tracking the current repository generation has been made consistent |
| 449 | + throw new AssertionError(re); |
| 450 | + } |
| 451 | + }); |
| 452 | + |
| 453 | + // Cancel/delete the snapshot |
| 454 | + try { |
| 455 | + client().admin().cluster().prepareDeleteSnapshot(REPO, snapshotName).get(); |
| 456 | + } catch (SnapshotMissingException e) { |
| 457 | + // ignore |
| 458 | + } |
| 459 | + } |
| 460 | + |
388 | 461 | private SnapshotsStatusResponse getSnapshotStatus(String snapshotName) {
|
389 | 462 | try {
|
390 | 463 | return client().admin().cluster().prepareSnapshotStatus(REPO).setSnapshots(snapshotName).get();
|
|
0 commit comments