|
|
@@ -8,6 +8,9 @@ package org.elasticsearch.xpack.slm;
|
|
|
|
|
|
import org.elasticsearch.action.ActionFuture;
|
|
|
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse;
|
|
|
+import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotAction;
|
|
|
+import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest;
|
|
|
+import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse;
|
|
|
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotStatus;
|
|
|
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusResponse;
|
|
|
import org.elasticsearch.action.index.IndexRequestBuilder;
|
|
|
@@ -22,6 +25,7 @@ import org.elasticsearch.index.query.QueryBuilders;
|
|
|
import org.elasticsearch.plugins.Plugin;
|
|
|
import org.elasticsearch.repositories.RepositoriesService;
|
|
|
import org.elasticsearch.repositories.RepositoryException;
|
|
|
+import org.elasticsearch.rest.RestStatus;
|
|
|
import org.elasticsearch.snapshots.ConcurrentSnapshotExecutionException;
|
|
|
import org.elasticsearch.snapshots.SnapshotInfo;
|
|
|
import org.elasticsearch.snapshots.SnapshotMissingException;
|
|
|
@@ -30,6 +34,7 @@ import org.elasticsearch.snapshots.mockstore.MockRepository;
|
|
|
import org.elasticsearch.test.ESIntegTestCase;
|
|
|
import org.elasticsearch.xpack.core.LocalStateCompositeXPackPlugin;
|
|
|
import org.elasticsearch.xpack.core.ilm.LifecycleSettings;
|
|
|
+import org.elasticsearch.xpack.core.slm.SnapshotInvocationRecord;
|
|
|
import org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicy;
|
|
|
import org.elasticsearch.xpack.core.slm.SnapshotLifecyclePolicyItem;
|
|
|
import org.elasticsearch.xpack.core.slm.SnapshotRetentionConfiguration;
|
|
|
@@ -385,6 +390,74 @@ public class SLMSnapshotBlockingIntegTests extends ESIntegTestCase {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ public void testSLMRetentionAfterRestore() throws Exception {
|
|
|
+ final String indexName = "test";
|
|
|
+ final String policyName = "test-policy";
|
|
|
+ int docCount = 20;
|
|
|
+ for (int i = 0; i < docCount; i++) {
|
|
|
+ index(indexName, i + "", Collections.singletonMap("foo", "bar"));
|
|
|
+ }
|
|
|
+
|
|
|
+ // Create a snapshot repo
|
|
|
+ initializeRepo(REPO);
|
|
|
+
|
|
|
+ logger.info("--> creating policy {}", policyName);
|
|
|
+ createSnapshotPolicy(policyName, "snap", NEVER_EXECUTE_CRON_SCHEDULE, REPO, indexName, true, false,
|
|
|
+ new SnapshotRetentionConfiguration(TimeValue.ZERO, null, null));
|
|
|
+
|
|
|
+ logger.info("--> executing snapshot lifecycle");
|
|
|
+ final String snapshotName = executePolicy(policyName);
|
|
|
+
|
|
|
+ // Check that the executed snapshot shows up in the SLM output
|
|
|
+ assertBusy(() -> {
|
|
|
+ GetSnapshotLifecycleAction.Response getResp =
|
|
|
+ client().execute(GetSnapshotLifecycleAction.INSTANCE, new GetSnapshotLifecycleAction.Request(policyName)).get();
|
|
|
+ logger.info("--> checking for in progress snapshot...");
|
|
|
+
|
|
|
+ assertThat(getResp.getPolicies().size(), greaterThan(0));
|
|
|
+ SnapshotLifecyclePolicyItem item = getResp.getPolicies().get(0);
|
|
|
+ SnapshotInvocationRecord lastSuccess = item.getLastSuccess();
|
|
|
+ assertNotNull(lastSuccess);
|
|
|
+ assertThat(lastSuccess.getSnapshotName(), equalTo(snapshotName));
|
|
|
+ });
|
|
|
+
|
|
|
+ logger.info("--> restoring index");
|
|
|
+ RestoreSnapshotRequest restoreReq = new RestoreSnapshotRequest(REPO, snapshotName);
|
|
|
+ restoreReq.indices(indexName);
|
|
|
+ restoreReq.renamePattern("(.+)");
|
|
|
+ restoreReq.renameReplacement("restored_$1");
|
|
|
+ restoreReq.waitForCompletion(true);
|
|
|
+ RestoreSnapshotResponse resp = client().execute(RestoreSnapshotAction.INSTANCE, restoreReq).get();
|
|
|
+ assertThat(resp.status(), equalTo(RestStatus.OK));
|
|
|
+
|
|
|
+ logger.info("--> executing SLM retention");
|
|
|
+ assertAcked(client().execute(ExecuteSnapshotRetentionAction.INSTANCE, new ExecuteSnapshotRetentionAction.Request()).get());
|
|
|
+ logger.info("--> waiting for {} snapshot to be deleted", snapshotName);
|
|
|
+ assertBusy(() -> {
|
|
|
+ try {
|
|
|
+ try {
|
|
|
+ GetSnapshotsResponse snapshotsStatusResponse = client().admin().cluster()
|
|
|
+ .prepareGetSnapshots(REPO).setSnapshots(snapshotName).get();
|
|
|
+ assertThat(snapshotsStatusResponse.getSnapshots(REPO), empty());
|
|
|
+ } catch (SnapshotMissingException e) {
|
|
|
+ // This is what we want to happen
|
|
|
+ }
|
|
|
+ logger.info("--> snapshot [{}] has been deleted", snapshotName);
|
|
|
+ } catch (RepositoryException re) {
|
|
|
+ // Concurrent status calls and write operations may lead to failures in determining the current repository generation
|
|
|
+ // TODO: Remove this hack once tracking the current repository generation has been made consistent
|
|
|
+ throw new AssertionError(re);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // Cancel/delete the snapshot
|
|
|
+ try {
|
|
|
+ client().admin().cluster().prepareDeleteSnapshot(REPO, snapshotName).get();
|
|
|
+ } catch (SnapshotMissingException e) {
|
|
|
+ // ignore
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private SnapshotsStatusResponse getSnapshotStatus(String snapshotName) {
|
|
|
try {
|
|
|
return client().admin().cluster().prepareSnapshotStatus(REPO).setSnapshots(snapshotName).get();
|