Skip to content

Commit fc870fd

Browse files
authored
Use simpler write-once semantics for HDFS repository (#30439)
There's no need for an extra `blobExists()` call when writing a blob to the HDFS service. The writeBlob implementation for the HDFS repository already uses the `CreateFlag.CREATE` option on the file creation, which ensures that the blob that's uploaded does not already exist. This saves one network roundtrip.
1 parent 2594c1f commit fc870fd

File tree

2 files changed

+4
-6
lines changed

2 files changed

+4
-6
lines changed

plugins/repository-hdfs/src/main/java/org/elasticsearch/repositories/hdfs/HdfsBlobContainer.java

+2-5
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,9 @@ public InputStream readBlob(String blobName) throws IOException {
100100

101101
@Override
102102
public void writeBlob(String blobName, InputStream inputStream, long blobSize) throws IOException {
103-
if (blobExists(blobName)) {
104-
throw new FileAlreadyExistsException("blob [" + blobName + "] already exists, cannot overwrite");
105-
}
106103
store.execute((Operation<Void>) fileContext -> {
107104
Path blob = new Path(path, blobName);
108105
// we pass CREATE, which means it fails if a blob already exists.
109-
// NOTE: this behavior differs from FSBlobContainer, which passes TRUNCATE_EXISTING
110-
// that should be fixed there, no need to bring truncation into this, give the user an error.
111106
EnumSet<CreateFlag> flags = EnumSet.of(CreateFlag.CREATE, CreateFlag.SYNC_BLOCK);
112107
CreateOpts[] opts = {CreateOpts.bufferSize(bufferSize)};
113108
try (FSDataOutputStream stream = fileContext.create(blob, flags, opts)) {
@@ -121,6 +116,8 @@ public void writeBlob(String blobName, InputStream inputStream, long blobSize) t
121116
// if true synchronous behavior is required"
122117
stream.hsync();
123118
}
119+
} catch (org.apache.hadoop.fs.FileAlreadyExistsException faee) {
120+
throw new FileAlreadyExistsException(blob.toString(), null, faee.getMessage());
124121
}
125122
return null;
126123
});

test/framework/src/main/java/org/elasticsearch/repositories/ESBlobStoreContainerTestCase.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import java.io.IOException;
3131
import java.io.InputStream;
32+
import java.nio.file.FileAlreadyExistsException;
3233
import java.nio.file.NoSuchFileException;
3334
import java.util.Arrays;
3435
import java.util.HashMap;
@@ -149,7 +150,7 @@ public void testVerifyOverwriteFails() throws IOException {
149150
final BytesArray bytesArray = new BytesArray(data);
150151
writeBlob(container, blobName, bytesArray);
151152
// should not be able to overwrite existing blob
152-
expectThrows(IOException.class, () -> writeBlob(container, blobName, bytesArray));
153+
expectThrows(FileAlreadyExistsException.class, () -> writeBlob(container, blobName, bytesArray));
153154
container.deleteBlob(blobName);
154155
writeBlob(container, blobName, bytesArray); // after deleting the previous blob, we should be able to write to it again
155156
}

0 commit comments

Comments
 (0)