Skip to content

Commit 0f0d13e

Browse files
authored
Do not check for Azure container existence (#31617)
The current AzureStorageServiceImpl always checks if the Azure container exists before reading or writing an object to the Azure container. This commit removes this behavior, reducing the number of overhall requests executed for all snapshots operations.
1 parent 9d523d0 commit 0f0d13e

File tree

3 files changed

+41
-47
lines changed

3 files changed

+41
-47
lines changed

plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureBlobContainer.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,14 @@ public void writeBlob(String blobName, InputStream inputStream, long blobSize) t
100100
public void deleteBlob(String blobName) throws IOException {
101101
logger.trace("deleteBlob({})", blobName);
102102

103-
if (!blobExists(blobName)) {
104-
throw new NoSuchFileException("Blob [" + blobName + "] does not exist");
105-
}
106-
107103
try {
108104
blobStore.deleteBlob(buildKey(blobName));
109-
} catch (URISyntaxException | StorageException e) {
110-
logger.warn("can not access [{}] in container {{}}: {}", blobName, blobStore, e.getMessage());
105+
} catch (StorageException e) {
106+
if (e.getHttpStatusCode() == HttpURLConnection.HTTP_NOT_FOUND) {
107+
throw new NoSuchFileException(e.getMessage());
108+
}
109+
throw new IOException(e);
110+
} catch (URISyntaxException e) {
111111
throw new IOException(e);
112112
}
113113
}

plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureStorageServiceImpl.java

+27-36
Original file line numberDiff line numberDiff line change
@@ -150,19 +150,17 @@ public void createContainer(String account, String container) throws URISyntaxEx
150150
public void deleteFiles(String account, String container, String path) throws URISyntaxException, StorageException {
151151
final Tuple<CloudBlobClient, Supplier<OperationContext>> client = client(account);
152152
// container name must be lower case.
153-
final CloudBlobContainer blobContainer = client.v1().getContainerReference(container);
154153
logger.trace(() -> new ParameterizedMessage("delete files container [{}], path [{}]", container, path));
155154
SocketAccess.doPrivilegedVoidException(() -> {
156-
if (blobContainer.exists()) {
157-
// list the blobs using a flat blob listing mode
158-
for (final ListBlobItem blobItem : blobContainer.listBlobs(path, true, EnumSet.noneOf(BlobListingDetails.class), null,
159-
client.v2().get())) {
160-
final String blobName = blobNameFromUri(blobItem.getUri());
161-
logger.trace(() -> new ParameterizedMessage("removing blob [{}] full URI was [{}]", blobName, blobItem.getUri()));
162-
// don't call {@code #deleteBlob}, use the same client
163-
final CloudBlockBlob azureBlob = blobContainer.getBlockBlobReference(blobName);
164-
azureBlob.delete(DeleteSnapshotsOption.NONE, null, null, client.v2().get());
165-
}
155+
// list the blobs using a flat blob listing mode
156+
final CloudBlobContainer blobContainer = client.v1().getContainerReference(container);
157+
for (final ListBlobItem blobItem : blobContainer.listBlobs(path, true, EnumSet.noneOf(BlobListingDetails.class), null,
158+
client.v2().get())) {
159+
final String blobName = blobNameFromUri(blobItem.getUri());
160+
logger.trace(() -> new ParameterizedMessage("removing blob [{}] full URI was [{}]", blobName, blobItem.getUri()));
161+
// don't call {@code #deleteBlob}, use the same client
162+
final CloudBlockBlob azureBlob = blobContainer.getBlockBlobReference(blobName);
163+
azureBlob.delete(DeleteSnapshotsOption.NONE, null, null, client.v2().get());
166164
}
167165
});
168166
}
@@ -192,11 +190,8 @@ public boolean blobExists(String account, String container, String blob)
192190
final Tuple<CloudBlobClient, Supplier<OperationContext>> client = client(account);
193191
final CloudBlobContainer blobContainer = client.v1().getContainerReference(container);
194192
return SocketAccess.doPrivilegedException(() -> {
195-
if (blobContainer.exists(null, null, client.v2().get())) {
196-
final CloudBlockBlob azureBlob = blobContainer.getBlockBlobReference(blob);
197-
return azureBlob.exists(null, null, client.v2().get());
198-
}
199-
return false;
193+
final CloudBlockBlob azureBlob = blobContainer.getBlockBlobReference(blob);
194+
return azureBlob.exists(null, null, client.v2().get());
200195
});
201196
}
202197

@@ -207,11 +202,9 @@ public void deleteBlob(String account, String container, String blob) throws URI
207202
final CloudBlobContainer blobContainer = client.v1().getContainerReference(container);
208203
logger.trace(() -> new ParameterizedMessage("delete blob for container [{}], blob [{}]", container, blob));
209204
SocketAccess.doPrivilegedVoidException(() -> {
210-
if (blobContainer.exists(null, null, client.v2().get())) {
211-
final CloudBlockBlob azureBlob = blobContainer.getBlockBlobReference(blob);
212-
logger.trace(() -> new ParameterizedMessage("container [{}]: blob [{}] found. removing.", container, blob));
213-
azureBlob.delete(DeleteSnapshotsOption.NONE, null, null, client.v2().get());
214-
}
205+
final CloudBlockBlob azureBlob = blobContainer.getBlockBlobReference(blob);
206+
logger.trace(() -> new ParameterizedMessage("container [{}]: blob [{}] found. removing.", container, blob));
207+
azureBlob.delete(DeleteSnapshotsOption.NONE, null, null, client.v2().get());
215208
});
216209
}
217210

@@ -238,19 +231,17 @@ public Map<String, BlobMetaData> listBlobsByPrefix(String account, String contai
238231
final CloudBlobContainer blobContainer = client.v1().getContainerReference(container);
239232
logger.trace(() -> new ParameterizedMessage("listing container [{}], keyPath [{}], prefix [{}]", container, keyPath, prefix));
240233
SocketAccess.doPrivilegedVoidException(() -> {
241-
if (blobContainer.exists()) {
242-
for (final ListBlobItem blobItem : blobContainer.listBlobs(keyPath + (prefix == null ? "" : prefix), false,
243-
enumBlobListingDetails, null, client.v2().get())) {
244-
final URI uri = blobItem.getUri();
245-
logger.trace(() -> new ParameterizedMessage("blob url [{}]", uri));
246-
// uri.getPath is of the form /container/keyPath.* and we want to strip off the /container/
247-
// this requires 1 + container.length() + 1, with each 1 corresponding to one of the /
248-
final String blobPath = uri.getPath().substring(1 + container.length() + 1);
249-
final BlobProperties properties = ((CloudBlockBlob) blobItem).getProperties();
250-
final String name = blobPath.substring(keyPath.length());
251-
logger.trace(() -> new ParameterizedMessage("blob url [{}], name [{}], size [{}]", uri, name, properties.getLength()));
252-
blobsBuilder.put(name, new PlainBlobMetaData(name, properties.getLength()));
253-
}
234+
for (final ListBlobItem blobItem : blobContainer.listBlobs(keyPath + (prefix == null ? "" : prefix), false,
235+
enumBlobListingDetails, null, client.v2().get())) {
236+
final URI uri = blobItem.getUri();
237+
logger.trace(() -> new ParameterizedMessage("blob url [{}]", uri));
238+
// uri.getPath is of the form /container/keyPath.* and we want to strip off the /container/
239+
// this requires 1 + container.length() + 1, with each 1 corresponding to one of the /
240+
final String blobPath = uri.getPath().substring(1 + container.length() + 1);
241+
final BlobProperties properties = ((CloudBlockBlob) blobItem).getProperties();
242+
final String name = blobPath.substring(keyPath.length());
243+
logger.trace(() -> new ParameterizedMessage("blob url [{}], name [{}], size [{}]", uri, name, properties.getLength()));
244+
blobsBuilder.put(name, new PlainBlobMetaData(name, properties.getLength()));
254245
}
255246
});
256247
return blobsBuilder.immutableMap();
@@ -264,8 +255,8 @@ public void writeBlob(String account, String container, String blobName, InputSt
264255
final CloudBlobContainer blobContainer = client.v1().getContainerReference(container);
265256
final CloudBlockBlob blob = blobContainer.getBlockBlobReference(blobName);
266257
try {
267-
SocketAccess.doPrivilegedVoidException(() -> blob.upload(inputStream, blobSize, AccessCondition.generateIfNotExistsCondition(),
268-
null, client.v2().get()));
258+
SocketAccess.doPrivilegedVoidException(() ->
259+
blob.upload(inputStream, blobSize, AccessCondition.generateIfNotExistsCondition(), null, client.v2().get()));
269260
} catch (final StorageException se) {
270261
if (se.getHttpStatusCode() == HttpURLConnection.HTTP_CONFLICT &&
271262
StorageErrorCodeStrings.BLOB_ALREADY_EXISTS.equals(se.getErrorCode())) {

plugins/repository-azure/src/test/java/org/elasticsearch/repositories/azure/AzureStorageServiceMock.java

+8-5
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import com.microsoft.azure.storage.OperationContext;
2323
import com.microsoft.azure.storage.StorageException;
2424
import com.microsoft.azure.storage.blob.CloudBlobClient;
25-
2625
import org.elasticsearch.common.blobstore.BlobMetaData;
2726
import org.elasticsearch.common.blobstore.support.PlainBlobMetaData;
2827
import org.elasticsearch.common.collect.MapBuilder;
@@ -72,9 +71,11 @@ public void createContainer(String account, String container) {
7271
}
7372

7473
@Override
75-
public void deleteFiles(String account, String container, String path) {
74+
public void deleteFiles(String account, String container, String path) throws URISyntaxException, StorageException {
7675
final Map<String, BlobMetaData> blobs = listBlobsByPrefix(account, container, path, null);
77-
blobs.keySet().forEach(key -> deleteBlob(account, container, key));
76+
for (String key : blobs.keySet()) {
77+
deleteBlob(account, container, key);
78+
}
7879
}
7980

8081
@Override
@@ -83,8 +84,10 @@ public boolean blobExists(String account, String container, String blob) {
8384
}
8485

8586
@Override
86-
public void deleteBlob(String account, String container, String blob) {
87-
blobs.remove(blob);
87+
public void deleteBlob(String account, String container, String blob) throws URISyntaxException, StorageException {
88+
if (blobs.remove(blob) == null) {
89+
throw new StorageException("BlobNotFound", "[" + blob + "] does not exist.", 404, null, null);
90+
}
8891
}
8992

9093
@Override

0 commit comments

Comments
 (0)