package com.netflix.raigad.backup;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.netflix.raigad.configuration.IConfiguration;
import com.netflix.raigad.configuration.UnitTestModule;
import com.netflix.raigad.utils.ElasticsearchTransportClient;
import mockit.Mock;
import mockit.MockUp;
import mockit.Mocked;
import org.apache.commons.io.FileUtils;
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryResponse;
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse;
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.repositories.RepositoryMissingException;
import org.elasticsearch.snapshots.SnapshotState;
import org.elasticsearch.test.ESIntegTestCase;
import org.junit.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
/**
* Reference:https://github.com/elasticsearch/elasticsearch-cloud-aws/blob/es-1.1/src/test/java/org/elasticsearch/repositories/s3/S3SnapshotRestoreTest.java
* <p>
* Following tests do not test S3 cloud functionality but uses fs (file system) locally to run Snapshot and Backup
* TODO: Need to fix for S3 functionality
*/
/*
{
"20140331": {
"type": "s3",
"settings": {
"region": "us-east-1",
"base_path": "es_test/20140331",
"bucket": "es-backup-test"
}
},
"20140410": {
"type": "s3",
"settings": {
"region": "us-east-1",
"base_path": "es_test/20140410",
"bucket": "es-backup-test"
}
}
}
*/
@Ignore
@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 2)
public class TestBackupRestore extends ESIntegTestCase {
private static final char PATH_SEP = File.separatorChar;
public static String repositoryName = "";
public static String repositoryLocation = "";
public static String LOCAL_DIR = "data";
private static Injector injector;
public static Client client0;
@Mocked
private static ElasticsearchTransportClient esTransportClient;
private static IConfiguration configuration;
private static S3RepositorySettingsParams s3RepositorySettingsParams;
private static S3Repository s3Repository;
@Mocked
private static SnapshotBackupManager snapshotBackupManager;
@Mocked
private static RestoreBackupManager restoreBackupManager;
@Before
public final void setup() throws IOException {
System.out.println("Running setup now...");
injector = Guice.createInjector(new UnitTestModule());
configuration = injector.getInstance(IConfiguration.class);
s3RepositorySettingsParams = injector.getInstance(S3RepositorySettingsParams.class);
esTransportClient = injector.getInstance(ElasticsearchTransportClient.class);
s3Repository = injector.getInstance(S3Repository.class);
if (snapshotBackupManager == null) {
snapshotBackupManager = injector.getInstance(SnapshotBackupManager.class);
}
if (restoreBackupManager == null) {
restoreBackupManager = injector.getInstance(RestoreBackupManager.class);
}
wipeRepositories();
cleanupDir(LOCAL_DIR, null);
}
@After
public final void wipeAfter() throws IOException {
System.out.println("Running wipeAfter ...");
wipeRepositories();
injector = null;
configuration = null;
s3RepositorySettingsParams = null;
s3Repository = null;
esTransportClient = null;
client0 = null;
cleanupDir(LOCAL_DIR, null);
}
@Test
public void testSimpleWorkflow() throws Exception {
client0 = client();
repositoryName = s3Repository.getRemoteRepositoryName();
//Create S3 Repository
Assert.assertFalse(s3Repository.createOrGetSnapshotRepository() == null);
createIndex("test-idx-1", "test-idx-3");
ensureGreen();
logger.info("--> indexing some data");
for (int i = 0; i < 100; i++) {
index("test-idx-1", "doc", Integer.toString(i), "foo", "bar" + i);
index("test-idx-3", "doc", Integer.toString(i), "foo", "baz" + i);
}
refresh();
Assert.assertEquals(client0.prepareSearch("test-idx-1").setSize(0).get().getHits().getTotalHits(), 100L);
Assert.assertEquals(client0.prepareSearch("test-idx-3").setSize(0).get().getHits().getTotalHits(), 100L);
//Run backup
snapshotBackupManager.runSnapshotBackup();
Assert.assertEquals(
client0.admin().cluster().prepareGetSnapshots(repositoryName).setSnapshots(
snapshotBackupManager.getSnapshotName("_all", false))
.get().getSnapshots().get(0).state(), SnapshotState.SUCCESS);
logger.info("--> delete some data");
for (int i = 0; i < 50; i++) {
client0.prepareDelete("test-idx-1", "doc", Integer.toString(i)).get();
}
for (int i = 0; i < 100; i += 2) {
client0.prepareDelete("test-idx-3", "doc", Integer.toString(i)).get();
}
refresh();
Assert.assertEquals(client0.prepareSearch("test-idx-1").setSize(0).get().getHits().getTotalHits(), 50L);
Assert.assertEquals(client0.prepareSearch("test-idx-3").setSize(0).get().getHits().getTotalHits(), 50L);
logger.info("--> close indices");
client0.admin().indices().prepareClose("test-idx-1", "test-idx-3").get();
logger.info("--> restore all indices from the snapshot");
restoreBackupManager.runRestore(repositoryName, "fs", snapshotBackupManager.getSnapshotName("_all", false), null, null, null);
ensureGreen();
Assert.assertEquals(client0.prepareSearch("test-idx-1").setSize(0).get().getHits().getTotalHits(), 100L);
Assert.assertEquals(client0.prepareSearch("test-idx-3").setSize(0).get().getHits().getTotalHits(), 100L);
}
@Ignore
public static class MockElasticsearchTransportClient extends MockUp<ElasticsearchTransportClient>{
@Mock
public static ElasticsearchTransportClient instance(IConfiguration config) {
return esTransportClient;
}
@Mock
public Client getTransportClient() {
return client0;
}
}
@Ignore
public static class MockS3Repository extends MockUp<S3Repository> {
@Mock
public PutRepositoryResponse getPutRepositoryResponse(Client esTransportClient, String s3RepoName) {
String localRepositoryLocation = LOCAL_DIR + PATH_SEP + s3RepositorySettingsParams.getBase_path();
PutRepositoryResponse putRepositoryResponse =
client0.admin().cluster()
.preparePutRepository(repositoryName)
.setType(AbstractRepository.RepositoryType.fs.name())
.setSettings(Settings.builder().put("location", localRepositoryLocation))
.get();
//Setting local repository location
repositoryLocation = localRepositoryLocation;
return putRepositoryResponse;
}
}
@Ignore
public static class MockSnapshotBackupManager extends MockUp<SnapshotBackupManager> {
@Mock
public CreateSnapshotResponse getCreateSnapshotResponse(Client esTransportClient, String repositoryName, String snapshotName) {
return client0.admin().cluster().prepareCreateSnapshot(repositoryName, snapshotName)
.setWaitForCompletion(configuration.waitForCompletionOfBackup())
.setIndices(configuration.getCommaSeparatedIndicesToBackup())
.setIncludeGlobalState(configuration.includeGlobalStateDuringBackup())
.setPartial(configuration.partiallyBackupIndices()).get();
}
}
@Ignore
public static class MockRestoreBackupManager extends MockUp<RestoreBackupManager> {
@Mock
public RestoreSnapshotResponse getRestoreSnapshotResponse(
Client esTransportClient, String commaSeparatedIndices, String restoreRepositoryName, String snapshotN) {
snapshotN = snapshotBackupManager.getSnapshotName("_all", false);
return client0.admin().cluster().prepareRestoreSnapshot(repositoryName, snapshotN)
.setIndices("test-idx-*")
.setWaitForCompletion(true)
.execute()
.actionGet();
}
}
public static void cleanupDir(String dirPath, List<String> childDirs) throws IOException {
if (childDirs == null || childDirs.size() == 0) {
FileUtils.cleanDirectory(new File(dirPath));
} else {
for (String childDir : childDirs) {
FileUtils.cleanDirectory(new File(dirPath + "/" + childDir));
}
}
}
/**
* Deletes repositories, supports wildcard notation.
*/
public static void wipeRepositories(String... repositories) {
// if nothing is provided, delete all
if (repositories.length == 0) {
repositories = new String[]{"*"};
}
for (String repository : repositories) {
try {
client().admin().cluster().prepareDeleteRepository(repository).execute().actionGet();
} catch (RepositoryMissingException ex) {
// ignore
}
}
}
}