this.service = service;
this.parameters = parameters;
}
public OperationResult invoke() {
OperationResult result = new OperationResult();
StringBuilder sbResult = new StringBuilder();
String snapshotName = parameters.getSimpleValue("snapshotName", "" + System.currentTimeMillis()).trim();
if (snapshotName.isEmpty()) {
result.setErrorMessage("Snapshot Name parameter cannot be an empty string");
return result;
}
String retentionStrategy = parameters.getSimpleValue("retentionStrategy", R_STRATEGY_KEEP_ALL);
Integer count = parameters.getSimple("count").getIntegerValue();
String deletionStrategy = parameters.getSimpleValue("deletionStrategy", D_STRATEGY_DEL);
String location = parameters.getSimpleValue("location");
// validate parameters
if (R_STRATEGY_KEEP_LASTN.equals(retentionStrategy) || R_STRATEGY_DEL_OLDERN.equals(retentionStrategy)) {
if (count == null) {
result.setErrorMessage("Invalid input parameters. Selected Retention Strategy [" + retentionStrategy
+ "] but 'count' parameter was null");
return result;
}
}
if (D_STRATEGY_MOVE.equals(deletionStrategy)) {
if (location == null) {
result.setErrorMessage("Invalid input parameters. Selected Deletion Strategy [" + deletionStrategy
+ "] but 'location' parameter was null");
return result;
}
}
String[] keyspaces = service.getKeyspaces().toArray(new String[] {});
log.info("Taking snapshot of keyspaces " + Arrays.toString(keyspaces));
long startTime = System.currentTimeMillis();
service.takeSnapshot(keyspaces, snapshotName);
log.info("Snapshot taken in " + (System.currentTimeMillis() - startTime) + "ms");
sbResult.append("Snapshot [" + snapshotName + "] was successfully created.");
if (R_STRATEGY_KEEP_ALL.equals(retentionStrategy)) { // do nothing
result.setSimpleResult(sbResult.toString());
return result;
}
// verify if we can write to location to move older snapshots
if (D_STRATEGY_MOVE.equals(deletionStrategy)) {
File locationDir = new File(location);
if (!locationDir.exists()) {
try {
if (!locationDir.mkdirs()) {
result.setErrorMessage("Location [" + locationDir.getAbsolutePath()
+ "] did not exist and failed to be created");
result.setSimpleResult(sbResult.toString());
return result;
}
} catch (Exception e) {
result.setErrorMessage("Location [" + locationDir.getAbsolutePath()
+ "] did not exist and failed to be created - " + e.getMessage());
result.setSimpleResult(sbResult.toString());
return result;
}
}
if (!locationDir.isDirectory()) {
result.setErrorMessage("Location [" + locationDir.getAbsolutePath() + "] must be directory");
result.setSimpleResult(sbResult.toString());
return result;
}
if (!locationDir.canWrite()) {
result.setErrorMessage("Location [" + locationDir.getAbsolutePath() + "] must be writable");
result.setSimpleResult(sbResult.toString());
return result;
}
}
List<String> columnFamilyDirs = service.getColumnFamilyDirs();
// obtain list of snapshot dirs to be moved or deleted
List<String[]> eligibleSnapshots = findEligibleSnapshots(service.getKeySpaceDataFileLocations(),
columnFamilyDirs, retentionStrategy, count);
if (eligibleSnapshots.isEmpty()) {
return result;
}
StringBuilder sbMoveOrDeleteErrors = new StringBuilder();
if (D_STRATEGY_DEL.equals(deletionStrategy)) {
log.info("Strategy [" + deletionStrategy + "] is set, deleting " + eligibleSnapshots.size() + " snapshots");
sbResult.append("\nDeleting " + eligibleSnapshots.size() + " directories.");
int deleted = 0;
for (String[] snapPath : eligibleSnapshots) {
File snapDir = new File(snapPath[0], snapPath[1]);
log.info("Deleting " + snapDir);
if (!FileUtils.deleteQuietly(snapDir)) {
log.warn("Failed to delete " + snapDir.getAbsolutePath());
sbMoveOrDeleteErrors.append("Failed to delete [" + snapDir.getAbsolutePath() + "]\n ");
} else {
deleted++;
}
}
sbResult.append("\nSuccessfully deleted " + deleted + " directories");
}
if (D_STRATEGY_MOVE.equals(deletionStrategy)) {
log.info("Strategy [" + deletionStrategy + "] is set, moving " + eligibleSnapshots.size() + " snapshots");
sbResult.append("\nMoving " + eligibleSnapshots.size() + " directories to [" + location + "].");
int moved = 0;
for (String[] snapPath : eligibleSnapshots) {
File snapDir = new File(snapPath[0], snapPath[1]);
File snapTargetDir = new File(location, snapPath[1]);
log.info("Moving " + snapDir + " to " + snapTargetDir);
try {
FileUtils.moveDirectoryToDirectory(snapDir, snapTargetDir.getParentFile(), true);
moved++;
} catch (IOException e) {
log.warn("Failed to move directory : " + e.getMessage());
sbMoveOrDeleteErrors.append("Failed to move [" + snapDir.getAbsolutePath() + "] to ["
+ snapTargetDir.getAbsolutePath() + "]\n ");
}
}
sbResult.append("\nSuccessfully moved " + moved + " directories.");
}
if (sbMoveOrDeleteErrors.length() > 0) {
result.setErrorMessage(sbMoveOrDeleteErrors.toString());
}
result.setSimpleResult(sbResult.toString());
return result;
}