Enables implementations of the BlobContainer interface to (#19749)
conform with the requirements of the writeBlob method by throwing a FileAlreadyExistsException if attempting to write to a blob that already exists. This change means implementations of BlobContainer should never overwrite blobs - to overwrite a blob, it must first be deleted and then can be written again. Closes #15579
This commit is contained in:
parent
c0b71d26cf
commit
c4ae23f5d8
|
@ -21,6 +21,7 @@ package org.elasticsearch.common.blobstore;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.FileAlreadyExistsException;
|
||||||
import java.nio.file.NoSuchFileException;
|
import java.nio.file.NoSuchFileException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -68,8 +69,8 @@ public interface BlobContainer {
|
||||||
* @param blobSize
|
* @param blobSize
|
||||||
* The size of the blob to be written, in bytes. It is implementation dependent whether
|
* The size of the blob to be written, in bytes. It is implementation dependent whether
|
||||||
* this value is used in writing the blob to the repository.
|
* this value is used in writing the blob to the repository.
|
||||||
* @throws IOException if the input stream could not be read, a blob by the same name already exists,
|
* @throws FileAlreadyExistsException if a blob by the same name already exists
|
||||||
* or the target blob could not be written to.
|
* @throws IOException if the input stream could not be read, or the target blob could not be written to.
|
||||||
*/
|
*/
|
||||||
void writeBlob(String blobName, InputStream inputStream, long blobSize) throws IOException;
|
void writeBlob(String blobName, InputStream inputStream, long blobSize) throws IOException;
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.file.DirectoryStream;
|
import java.nio.file.DirectoryStream;
|
||||||
|
import java.nio.file.FileAlreadyExistsException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.NoSuchFileException;
|
import java.nio.file.NoSuchFileException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
@ -108,6 +109,9 @@ public class FsBlobContainer extends AbstractBlobContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeBlob(String blobName, InputStream inputStream, long blobSize) throws IOException {
|
public void writeBlob(String blobName, InputStream inputStream, long blobSize) throws IOException {
|
||||||
|
if (blobExists(blobName)) {
|
||||||
|
throw new FileAlreadyExistsException("blob [" + blobName + "] already exists, cannot overwrite");
|
||||||
|
}
|
||||||
final Path file = path.resolve(blobName);
|
final Path file = path.resolve(blobName);
|
||||||
try (OutputStream outputStream = Files.newOutputStream(file, StandardOpenOption.CREATE_NEW)) {
|
try (OutputStream outputStream = Files.newOutputStream(file, StandardOpenOption.CREATE_NEW)) {
|
||||||
Streams.copy(inputStream, outputStream, new byte[blobStore.bufferSizeInBytes()]);
|
Streams.copy(inputStream, outputStream, new byte[blobStore.bufferSizeInBytes()]);
|
||||||
|
|
|
@ -34,6 +34,7 @@ import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.file.FileAlreadyExistsException;
|
||||||
import java.nio.file.NoSuchFileException;
|
import java.nio.file.NoSuchFileException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -84,6 +85,9 @@ public class AzureBlobContainer extends AbstractBlobContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeBlob(String blobName, InputStream inputStream, long blobSize) throws IOException {
|
public void writeBlob(String blobName, InputStream inputStream, long blobSize) throws IOException {
|
||||||
|
if (blobExists(blobName)) {
|
||||||
|
throw new FileAlreadyExistsException("blob [" + blobName + "] already exists, cannot overwrite");
|
||||||
|
}
|
||||||
logger.trace("writeBlob({}, stream, {})", blobName, blobSize);
|
logger.trace("writeBlob({}, stream, {})", blobName, blobSize);
|
||||||
try (OutputStream stream = createOutput(blobName)) {
|
try (OutputStream stream = createOutput(blobName)) {
|
||||||
Streams.copy(inputStream, stream);
|
Streams.copy(inputStream, stream);
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.elasticsearch.common.blobstore.support.AbstractBlobContainer;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.FileAlreadyExistsException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class GoogleCloudStorageBlobContainer extends AbstractBlobContainer {
|
public class GoogleCloudStorageBlobContainer extends AbstractBlobContainer {
|
||||||
|
@ -65,6 +66,9 @@ public class GoogleCloudStorageBlobContainer extends AbstractBlobContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeBlob(String blobName, InputStream inputStream, long blobSize) throws IOException {
|
public void writeBlob(String blobName, InputStream inputStream, long blobSize) throws IOException {
|
||||||
|
if (blobExists(blobName)) {
|
||||||
|
throw new FileAlreadyExistsException("blob [" + blobName + "] already exists, cannot overwrite");
|
||||||
|
}
|
||||||
blobStore.writeBlob(buildKey(blobName), inputStream, blobSize);
|
blobStore.writeBlob(buildKey(blobName), inputStream, blobSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.elasticsearch.repositories.hdfs.HdfsBlobStore.Operation;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.FileAlreadyExistsException;
|
||||||
import java.nio.file.NoSuchFileException;
|
import java.nio.file.NoSuchFileException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
@ -107,6 +108,9 @@ final class HdfsBlobContainer extends AbstractBlobContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeBlob(String blobName, InputStream inputStream, long blobSize) throws IOException {
|
public void writeBlob(String blobName, InputStream inputStream, long blobSize) throws IOException {
|
||||||
|
if (blobExists(blobName)) {
|
||||||
|
throw new FileAlreadyExistsException("blob [" + blobName + "] already exists, cannot overwrite");
|
||||||
|
}
|
||||||
store.execute(new Operation<Void>() {
|
store.execute(new Operation<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void run(FileContext fileContext) throws IOException {
|
public Void run(FileContext fileContext) throws IOException {
|
||||||
|
|
|
@ -39,6 +39,7 @@ import org.elasticsearch.common.io.Streams;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.nio.file.FileAlreadyExistsException;
|
||||||
import java.nio.file.NoSuchFileException;
|
import java.nio.file.NoSuchFileException;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedActionException;
|
import java.security.PrivilegedActionException;
|
||||||
|
@ -100,6 +101,9 @@ public class S3BlobContainer extends AbstractBlobContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeBlob(String blobName, InputStream inputStream, long blobSize) throws IOException {
|
public void writeBlob(String blobName, InputStream inputStream, long blobSize) throws IOException {
|
||||||
|
if (blobExists(blobName)) {
|
||||||
|
throw new FileAlreadyExistsException("blob [" + blobName + "] already exists, cannot overwrite");
|
||||||
|
}
|
||||||
try (OutputStream stream = createOutput(blobName)) {
|
try (OutputStream stream = createOutput(blobName)) {
|
||||||
Streams.copy(inputStream, stream);
|
Streams.copy(inputStream, stream);
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,6 @@ public abstract class ESBlobStoreContainerTestCase extends ESTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/15579")
|
|
||||||
public void testVerifyOverwriteFails() throws IOException {
|
public void testVerifyOverwriteFails() throws IOException {
|
||||||
try (final BlobStore store = newBlobStore()) {
|
try (final BlobStore store = newBlobStore()) {
|
||||||
final String blobName = "foobar";
|
final String blobName = "foobar";
|
||||||
|
|
Loading…
Reference in New Issue