Skip to content

Commit 783b495

Browse files
committed
Persist snapshot validation markers to S3.
1 parent 4c25e6d commit 783b495

8 files changed

Lines changed: 86 additions & 8 deletions

File tree

priam/src/main/java/com/netflix/priam/aws/RemoteBackupPath.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ private ImmutableList.Builder<String> getPrefix() {
5050
/* This will ensure that there is some randomness in the path at the start so that remote file systems
5151
can hash the contents better when we have lot of clusters backing up at the same remote location.
5252
*/
53-
private String prependHash(String appName) {
53+
public static String prependHash(String appName) {
5454
return String.format("%d_%s", appName.hashCode() % 10000, appName);
5555
}
5656

priam/src/main/java/com/netflix/priam/aws/S3FileSystem.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ protected void downloadFileImpl(AbstractBackupPath path, String suffix)
104104
}
105105
}
106106

107+
@Override
108+
public void putObject(String bucket, String key, String value) {
109+
s3Client.putObject(bucket, key, value);
110+
}
111+
107112
private ObjectMetadata getObjectMetadata(File file) {
108113
ObjectMetadata ret = new ObjectMetadata();
109114
long lastModified = file.lastModified();

priam/src/main/java/com/netflix/priam/backup/IBackupFileSystem.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,4 +175,7 @@ default boolean checkObjectExists(Path remotePath) {
175175

176176
/** Add remote backup path to the object cache*/
177177
void addObjectCache(Path remotePath);
178+
179+
/** Synchronously put the contents of an in-memory String to the blob store. **/
180+
void putObject(String bucket, String key, String value);
178181
}

priam/src/main/java/com/netflix/priam/backupv2/BackupVerificationTask.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,12 @@ public class BackupVerificationTask extends Task {
4444
private static final Logger logger = LoggerFactory.getLogger(BackupVerificationTask.class);
4545
public static final String JOBNAME = "BackupVerificationService";
4646

47-
private IBackupRestoreConfig backupRestoreConfig;
48-
private BackupVerification backupVerification;
49-
private BackupMetrics backupMetrics;
50-
private InstanceState instanceState;
51-
private BackupNotificationMgr backupNotificationMgr;
47+
private final IBackupRestoreConfig backupRestoreConfig;
48+
private final BackupVerification backupVerification;
49+
private final BackupMetrics backupMetrics;
50+
private final InstanceState instanceState;
51+
private final BackupNotificationMgr backupNotificationMgr;
52+
private final SnapshotValidationMarkerWriter snapshotValidationMarkerWriter;
5253

5354
@Inject
5455
public BackupVerificationTask(
@@ -57,13 +58,15 @@ public BackupVerificationTask(
5758
BackupVerification backupVerification,
5859
BackupMetrics backupMetrics,
5960
InstanceState instanceState,
60-
BackupNotificationMgr backupNotificationMgr) {
61+
BackupNotificationMgr backupNotificationMgr,
62+
SnapshotValidationMarkerWriter snapshotValidationMarkerWriter) {
6163
super(configuration);
6264
this.backupRestoreConfig = backupRestoreConfig;
6365
this.backupVerification = backupVerification;
6466
this.backupMetrics = backupMetrics;
6567
this.instanceState = instanceState;
6668
this.backupNotificationMgr = backupNotificationMgr;
69+
this.snapshotValidationMarkerWriter = snapshotValidationMarkerWriter;
6770
}
6871

6972
@Override
@@ -104,6 +107,7 @@ public void execute() throws Exception {
104107
snapshotKey);
105108
backupNotificationMgr.notify(
106109
snapshotKey, result.getStart().toInstant());
110+
snapshotValidationMarkerWriter.write(snapshotKey);
107111
});
108112

109113
if (verifiedBackups.isEmpty()) {
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.netflix.priam.backupv2;
2+
3+
import com.netflix.priam.aws.RemoteBackupPath;
4+
import com.netflix.priam.backup.AbstractBackupPath;
5+
import com.netflix.priam.backup.IBackupFileSystem;
6+
import com.netflix.priam.config.IConfiguration;
7+
import com.netflix.priam.identity.config.InstanceInfo;
8+
import org.slf4j.Logger;
9+
import org.slf4j.LoggerFactory;
10+
11+
import javax.inject.Inject;
12+
import javax.inject.Provider;
13+
14+
public class SnapshotValidationMarkerWriter {
15+
private static final Logger logger = LoggerFactory.getLogger(SnapshotValidationMarkerWriter.class);
16+
private static final String METADATA_PREFIX = "metadata";
17+
private final IConfiguration config;
18+
private final InstanceInfo instanceInfo;
19+
private final Provider<AbstractBackupPath> pathProvider;
20+
private final IBackupFileSystem fs;
21+
22+
@Inject
23+
public SnapshotValidationMarkerWriter(
24+
IConfiguration config,
25+
InstanceInfo instanceInfo,
26+
Provider<AbstractBackupPath> pathProvider,
27+
IBackupFileSystem fs) {
28+
this.config = config;
29+
this.instanceInfo = instanceInfo;
30+
this.pathProvider = pathProvider;
31+
this.fs = fs;
32+
}
33+
34+
public void write(String remotePath) {
35+
AbstractBackupPath path = pathProvider.get();
36+
path.parseRemote(remotePath);
37+
String key = AbstractBackupPath.PATH_JOINER.join(
38+
METADATA_PREFIX,
39+
RemoteBackupPath.prependHash(path.getClusterName()),
40+
path.getLastModified().toEpochMilli(),
41+
instanceInfo.getRac(),
42+
path.getToken());
43+
try {
44+
fs.putObject(config.getBackupPrefix(), key, remotePath);
45+
} catch (Exception e) {
46+
logger.error("Failed to put snapshot verification marker. bucket: {}, key: {}, value: {}, message: {}",
47+
config.getBackupPrefix(),
48+
key,
49+
remotePath,
50+
e.getLocalizedMessage());
51+
}
52+
}
53+
}

priam/src/main/java/com/netflix/priam/resources/BackupServletV2.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.netflix.priam.backupv2.BackupV2Service;
2525
import com.netflix.priam.backupv2.IMetaProxy;
2626
import com.netflix.priam.backupv2.SnapshotMetaTask;
27+
import com.netflix.priam.backupv2.*;
2728
import com.netflix.priam.config.IConfiguration;
2829
import com.netflix.priam.notification.BackupNotificationMgr;
2930
import com.netflix.priam.utils.DateUtil;
@@ -63,6 +64,7 @@ public class BackupServletV2 {
6364
private final BackupNotificationMgr backupNotificationMgr;
6465
private final IConfiguration config;
6566
private final DirectorySize directorySize;
67+
private final SnapshotValidationMarkerWriter snapshotValidationMarkerWriter;
6668

6769
private static final String REST_SUCCESS = "[\"ok\"]";
6870

@@ -78,7 +80,8 @@ public BackupServletV2(
7880
BackupV2Service backupService,
7981
BackupNotificationMgr backupNotificationMgr,
8082
IConfiguration config,
81-
DirectorySize directorySize) {
83+
DirectorySize directorySize,
84+
SnapshotValidationMarkerWriter snapshotValidationMarkerWriter) {
8285
this.backupStatusMgr = backupStatusMgr;
8386
this.backupVerification = backupVerification;
8487
this.snapshotMetaService = snapshotMetaService;
@@ -90,6 +93,7 @@ public BackupServletV2(
9093
this.backupNotificationMgr = backupNotificationMgr;
9194
this.config = config;
9295
this.directorySize = directorySize;
96+
this.snapshotValidationMarkerWriter = snapshotValidationMarkerWriter;
9397
}
9498

9599
@GET
@@ -164,6 +168,7 @@ public Response validateV2SnapshotByDate(
164168
result.get().remotePath);
165169

166170
backupNotificationMgr.notify(result.get().remotePath, result.get().snapshotInstant);
171+
snapshotValidationMarkerWriter.write(result.get().remotePath);
167172

168173
return Response.ok(result.get().toString()).build();
169174
}

priam/src/test/java/com/netflix/priam/backup/FakeBackupFileSystem.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,9 @@ protected long uploadFileImpl(AbstractBackupPath path, Instant target)
141141
addFile(path.getRemotePath());
142142
return path.getBackupFile().length();
143143
}
144+
145+
@Override
146+
public void putObject(String bucket, String key, String value) {
147+
throw new UnsupportedOperationException();
148+
}
144149
}

priam/src/test/java/com/netflix/priam/backup/NullBackupFileSystem.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,7 @@ protected long uploadFileImpl(AbstractBackupPath path, Instant target)
7272
throws BackupRestoreException {
7373
return 0;
7474
}
75+
76+
@Override
77+
public void putObject(String bucket, String key, String value) {}
7578
}

0 commit comments

Comments
 (0)