Change the BlobContainer interface to throw a NoSuchFileFoundException
for reads and deletes if the blob does not exist.
This commit is contained in:
parent
abaf8443e5
commit
630218a16f
|
@ -23,6 +23,7 @@ import org.elasticsearch.common.bytes.BytesReference;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.NoSuchFileException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -53,7 +54,8 @@ public interface BlobContainer {
|
||||||
* @param blobName
|
* @param blobName
|
||||||
* The name of the blob to get an {@link InputStream} for.
|
* The name of the blob to get an {@link InputStream} for.
|
||||||
* @return The {@code InputStream} to read the blob.
|
* @return The {@code InputStream} to read the blob.
|
||||||
* @throws IOException if the blob does not exist or can not be read.
|
* @throws NoSuchFileException if the blob does not exist
|
||||||
|
* @throws IOException if the blob can not be read.
|
||||||
*/
|
*/
|
||||||
InputStream readBlob(String blobName) throws IOException;
|
InputStream readBlob(String blobName) throws IOException;
|
||||||
|
|
||||||
|
@ -95,7 +97,8 @@ public interface BlobContainer {
|
||||||
*
|
*
|
||||||
* @param blobName
|
* @param blobName
|
||||||
* The name of the blob to delete.
|
* The name of the blob to delete.
|
||||||
* @throws IOException if the blob does not exist, or if the blob exists but could not be deleted.
|
* @throws NoSuchFileException if the blob does not exist
|
||||||
|
* @throws IOException if the blob exists but could not be deleted.
|
||||||
*/
|
*/
|
||||||
void deleteBlob(String blobName) throws IOException;
|
void deleteBlob(String blobName) throws IOException;
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ 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.Files;
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.NoSuchFileException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
@ -95,7 +96,11 @@ public class FsBlobContainer extends AbstractBlobContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream readBlob(String name) throws IOException {
|
public InputStream readBlob(String name) throws IOException {
|
||||||
return new BufferedInputStream(Files.newInputStream(path.resolve(name)), blobStore.bufferSizeInBytes());
|
final Path resolvedPath = path.resolve(name);
|
||||||
|
if (!Files.exists(resolvedPath)) {
|
||||||
|
throw new NoSuchFileException("[" + resolvedPath + "] file not found");
|
||||||
|
}
|
||||||
|
return new BufferedInputStream(Files.newInputStream(resolvedPath), blobStore.bufferSizeInBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -30,12 +30,12 @@ import org.elasticsearch.common.logging.ESLogger;
|
||||||
import org.elasticsearch.common.logging.Loggers;
|
import org.elasticsearch.common.logging.Loggers;
|
||||||
import org.elasticsearch.repositories.RepositoryException;
|
import org.elasticsearch.repositories.RepositoryException;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
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.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.file.NoSuchFileException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,14 +72,14 @@ public class AzureBlobContainer extends AbstractBlobContainer {
|
||||||
logger.trace("readBlob({})", blobName);
|
logger.trace("readBlob({})", blobName);
|
||||||
|
|
||||||
if (!blobExists(blobName)) {
|
if (!blobExists(blobName)) {
|
||||||
throw new IOException("Blob [" + blobName + "] does not exist");
|
throw new NoSuchFileException("Blob [" + blobName + "] does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return blobStore.getInputStream(blobStore.container(), buildKey(blobName));
|
return blobStore.getInputStream(blobStore.container(), buildKey(blobName));
|
||||||
} catch (StorageException e) {
|
} catch (StorageException e) {
|
||||||
if (e.getHttpStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) {
|
if (e.getHttpStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) {
|
||||||
throw new FileNotFoundException(e.getMessage());
|
throw new NoSuchFileException(e.getMessage());
|
||||||
}
|
}
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
} catch (URISyntaxException e) {
|
} catch (URISyntaxException e) {
|
||||||
|
@ -108,7 +108,7 @@ public class AzureBlobContainer extends AbstractBlobContainer {
|
||||||
return new AzureOutputStream(blobStore.getOutputStream(blobStore.container(), buildKey(blobName)));
|
return new AzureOutputStream(blobStore.getOutputStream(blobStore.container(), buildKey(blobName)));
|
||||||
} catch (StorageException e) {
|
} catch (StorageException e) {
|
||||||
if (e.getHttpStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) {
|
if (e.getHttpStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) {
|
||||||
throw new FileNotFoundException(e.getMessage());
|
throw new NoSuchFileException(e.getMessage());
|
||||||
}
|
}
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
} catch (URISyntaxException e) {
|
} catch (URISyntaxException e) {
|
||||||
|
|
|
@ -41,9 +41,9 @@ import org.elasticsearch.common.component.AbstractComponent;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.CountDown;
|
import org.elasticsearch.common.util.concurrent.CountDown;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.NoSuchFileException;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedActionException;
|
import java.security.PrivilegedActionException;
|
||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
|
@ -189,6 +189,9 @@ public class GoogleCloudStorageBlobStore extends AbstractComponent implements Bl
|
||||||
* @return an InputStream
|
* @return an InputStream
|
||||||
*/
|
*/
|
||||||
InputStream readBlob(String blobName) throws IOException {
|
InputStream readBlob(String blobName) throws IOException {
|
||||||
|
if (!blobExists(blobName)) {
|
||||||
|
throw new NoSuchFileException("Blob [" + blobName + "] does not exist");
|
||||||
|
}
|
||||||
return doPrivileged(() -> {
|
return doPrivileged(() -> {
|
||||||
try {
|
try {
|
||||||
Storage.Objects.Get object = client.objects().get(bucket, blobName);
|
Storage.Objects.Get object = client.objects().get(bucket, blobName);
|
||||||
|
@ -196,7 +199,7 @@ public class GoogleCloudStorageBlobStore extends AbstractComponent implements Bl
|
||||||
} catch (GoogleJsonResponseException e) {
|
} catch (GoogleJsonResponseException e) {
|
||||||
GoogleJsonError error = e.getDetails();
|
GoogleJsonError error = e.getDetails();
|
||||||
if ((e.getStatusCode() == HTTP_NOT_FOUND) || ((error != null) && (error.getCode() == HTTP_NOT_FOUND))) {
|
if ((e.getStatusCode() == HTTP_NOT_FOUND) || ((error != null) && (error.getCode() == HTTP_NOT_FOUND))) {
|
||||||
throw new FileNotFoundException(e.getMessage());
|
throw new NoSuchFileException(e.getMessage());
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
@ -227,6 +230,9 @@ public class GoogleCloudStorageBlobStore extends AbstractComponent implements Bl
|
||||||
* @param blobName name of the blob
|
* @param blobName name of the blob
|
||||||
*/
|
*/
|
||||||
void deleteBlob(String blobName) throws IOException {
|
void deleteBlob(String blobName) throws IOException {
|
||||||
|
if (!blobExists(blobName)) {
|
||||||
|
throw new NoSuchFileException("Blob [" + blobName + "] does not exist");
|
||||||
|
}
|
||||||
doPrivileged(() -> client.objects().delete(bucket, blobName).execute());
|
doPrivileged(() -> client.objects().delete(bucket, blobName).execute());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,9 @@ import org.elasticsearch.common.blobstore.support.AbstractBlobContainer;
|
||||||
import org.elasticsearch.common.blobstore.support.PlainBlobMetaData;
|
import org.elasticsearch.common.blobstore.support.PlainBlobMetaData;
|
||||||
import org.elasticsearch.repositories.hdfs.HdfsBlobStore.Operation;
|
import org.elasticsearch.repositories.hdfs.HdfsBlobStore.Operation;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.NoSuchFileException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
@ -69,7 +69,7 @@ final class HdfsBlobContainer extends AbstractBlobContainer {
|
||||||
@Override
|
@Override
|
||||||
public void deleteBlob(String blobName) throws IOException {
|
public void deleteBlob(String blobName) throws IOException {
|
||||||
if (!blobExists(blobName)) {
|
if (!blobExists(blobName)) {
|
||||||
throw new IOException("Blob [" + blobName + "] does not exist");
|
throw new NoSuchFileException("Blob [" + blobName + "] does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
store.execute(new Operation<Boolean>() {
|
store.execute(new Operation<Boolean>() {
|
||||||
|
@ -93,6 +93,9 @@ final class HdfsBlobContainer extends AbstractBlobContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream readBlob(String blobName) throws IOException {
|
public InputStream readBlob(String blobName) throws IOException {
|
||||||
|
if (!blobExists(blobName)) {
|
||||||
|
throw new NoSuchFileException("Blob [" + blobName + "] does not exist");
|
||||||
|
}
|
||||||
// FSDataInputStream does buffering internally
|
// FSDataInputStream does buffering internally
|
||||||
return store.execute(new Operation<InputStream>() {
|
return store.execute(new Operation<InputStream>() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.fs.AbstractFileSystem;
|
import org.apache.hadoop.fs.AbstractFileSystem;
|
||||||
import org.apache.hadoop.fs.FileContext;
|
import org.apache.hadoop.fs.FileContext;
|
||||||
import org.apache.hadoop.fs.UnsupportedFileSystemException;
|
import org.apache.hadoop.fs.UnsupportedFileSystemException;
|
||||||
|
import org.elasticsearch.common.SuppressForbidden;
|
||||||
import org.elasticsearch.common.blobstore.BlobStore;
|
import org.elasticsearch.common.blobstore.BlobStore;
|
||||||
import org.elasticsearch.repositories.ESBlobStoreContainerTestCase;
|
import org.elasticsearch.repositories.ESBlobStoreContainerTestCase;
|
||||||
|
|
||||||
|
@ -55,7 +56,8 @@ public class HdfsBlobStoreContainerTests extends ESBlobStoreContainerTestCase {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileContext createContext(URI uri) {
|
@SuppressForbidden(reason = "lesser of two evils (the other being a bunch of JNI/classloader nightmares)")
|
||||||
|
private FileContext createContext(URI uri) {
|
||||||
// mirrors HdfsRepository.java behaviour
|
// mirrors HdfsRepository.java behaviour
|
||||||
Configuration cfg = new Configuration(true);
|
Configuration cfg = new Configuration(true);
|
||||||
cfg.setClassLoader(HdfsRepository.class.getClassLoader());
|
cfg.setClassLoader(HdfsRepository.class.getClassLoader());
|
||||||
|
@ -85,8 +87,7 @@ public class HdfsBlobStoreContainerTests extends ESBlobStoreContainerTestCase {
|
||||||
|
|
||||||
// set file system to TestingFs to avoid a bunch of security
|
// set file system to TestingFs to avoid a bunch of security
|
||||||
// checks, similar to what is done in HdfsTests.java
|
// checks, similar to what is done in HdfsTests.java
|
||||||
cfg.set(String.format("fs.AbstractFileSystem.%s.impl", uri.getScheme()),
|
cfg.set("fs.AbstractFileSystem." + uri.getScheme() + ".impl", TestingFs.class.getName());
|
||||||
TestingFs.class.getName());
|
|
||||||
|
|
||||||
// create the FileContext with our user
|
// create the FileContext with our user
|
||||||
return Subject.doAs(subject, new PrivilegedAction<FileContext>() {
|
return Subject.doAs(subject, new PrivilegedAction<FileContext>() {
|
||||||
|
|
|
@ -37,10 +37,10 @@ import org.elasticsearch.common.bytes.BytesReference;
|
||||||
import org.elasticsearch.common.collect.MapBuilder;
|
import org.elasticsearch.common.collect.MapBuilder;
|
||||||
import org.elasticsearch.common.io.Streams;
|
import org.elasticsearch.common.io.Streams;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
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.NoSuchFileException;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedActionException;
|
import java.security.PrivilegedActionException;
|
||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
|
@ -89,7 +89,7 @@ public class S3BlobContainer extends AbstractBlobContainer {
|
||||||
} else {
|
} else {
|
||||||
if (e instanceof AmazonS3Exception) {
|
if (e instanceof AmazonS3Exception) {
|
||||||
if (404 == ((AmazonS3Exception) e).getStatusCode()) {
|
if (404 == ((AmazonS3Exception) e).getStatusCode()) {
|
||||||
throw new FileNotFoundException("Blob object [" + blobName + "] not found: " + e.getMessage());
|
throw new NoSuchFileException("Blob object [" + blobName + "] not found: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -116,7 +116,7 @@ public class S3BlobContainer extends AbstractBlobContainer {
|
||||||
@Override
|
@Override
|
||||||
public void deleteBlob(String blobName) throws IOException {
|
public void deleteBlob(String blobName) throws IOException {
|
||||||
if (!blobExists(blobName)) {
|
if (!blobExists(blobName)) {
|
||||||
throw new IOException("Blob [" + blobName + "] does not exist");
|
throw new NoSuchFileException("Blob [" + blobName + "] does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Reference in New Issue