Fix remove of azure files
Probably when we updated Azure SDK, we introduced a regression. Actually, we are not able to remove files anymore. For example, if you register a new azure repository, the snapshot service tries to create a temp file and then remove it. Removing does not work and you can see in logs: ``` [2016-05-18 11:03:24,914][WARN ][org.elasticsearch.cloud.azure.blobstore] [azure] can not remove [tests-ilmRPJ8URU-sh18yj38O6g/] in container {elasticsearch-snapshots}: The specified blob does not exist. ``` This fix deals with that. It now list all the files in a flatten mode, remove in the full URL the server and the container name. As an example, when you are removing a blob which full name is `https://dpi24329.blob.core.windows.net/elasticsearch-snapshots/bar/test` you need to actually call Azure SDK with `bar/test` as the path, `elasticsearch-snapshots` is the container. To run the test, you need to pass some parameters: `-Dtests.thirdparty=true -Dtests.config=/path/to/elasticsearch.yml` Where `elasticsearch.yml` contains something like: ``` cloud.azure.storage.default.account: account cloud.azure.storage.default.key: key ``` Related to #16472 Closes #18436.
This commit is contained in:
parent
d85dac7a9a
commit
9b247f9828
|
@ -182,13 +182,20 @@ public class AzureStorageServiceImpl extends AbstractLifecycleComponent<AzureSto
|
||||||
CloudBlobClient client = this.getSelectedClient(account, mode);
|
CloudBlobClient client = this.getSelectedClient(account, mode);
|
||||||
CloudBlobContainer blob_container = client.getContainerReference(container);
|
CloudBlobContainer blob_container = client.getContainerReference(container);
|
||||||
if (blob_container.exists()) {
|
if (blob_container.exists()) {
|
||||||
for (ListBlobItem blobItem : blob_container.listBlobs(path)) {
|
for (ListBlobItem blobItem : blob_container.listBlobs(path, true)) {
|
||||||
logger.trace("removing blob [{}]", blobItem.getUri());
|
String blobName = blobNameFromUri(container, blobItem.getUri());
|
||||||
deleteBlob(account, mode, container, blobItem.getUri().toString());
|
logger.trace("removing blob [{}] full URI was [{}]", blobName, blobItem.getUri());
|
||||||
|
deleteBlob(account, mode, container, blobName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String blobNameFromUri(String container, URI uri) {
|
||||||
|
String path = uri.getPath();
|
||||||
|
// We remove the container name from the path
|
||||||
|
return path.replaceFirst("/" + container + "/", "");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean blobExists(String account, LocationMode mode, String container, String blob) throws URISyntaxException, StorageException {
|
public boolean blobExists(String account, LocationMode mode, String container, String blob) throws URISyntaxException, StorageException {
|
||||||
// Container name must be lower case.
|
// Container name must be lower case.
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.repositories.azure;
|
||||||
|
|
||||||
|
import com.microsoft.azure.storage.StorageException;
|
||||||
|
import org.elasticsearch.cloud.azure.blobstore.AzureBlobStore;
|
||||||
|
import org.elasticsearch.cloud.azure.storage.AzureStorageService;
|
||||||
|
import org.elasticsearch.cloud.azure.storage.AzureStorageServiceImpl;
|
||||||
|
import org.elasticsearch.common.Strings;
|
||||||
|
import org.elasticsearch.common.blobstore.BlobStore;
|
||||||
|
import org.elasticsearch.common.io.PathUtils;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.settings.SettingsException;
|
||||||
|
import org.elasticsearch.repositories.RepositoryName;
|
||||||
|
import org.elasticsearch.repositories.RepositorySettings;
|
||||||
|
import org.elasticsearch.test.ESBlobStoreTestCase;
|
||||||
|
import org.elasticsearch.test.ESIntegTestCase;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* You must specify {@code -Dtests.thirdparty=true -Dtests.config=/path/to/elasticsearch.yml}
|
||||||
|
* in order to run these tests.
|
||||||
|
*/
|
||||||
|
@ESIntegTestCase.ThirdParty
|
||||||
|
public class AzureBlobStoreTests extends ESBlobStoreTestCase {
|
||||||
|
@Override
|
||||||
|
protected BlobStore newBlobStore() throws IOException {
|
||||||
|
try {
|
||||||
|
RepositoryName repositoryName = new RepositoryName("azure", "ittest");
|
||||||
|
Settings settings = readSettingsFromFile();
|
||||||
|
RepositorySettings repositorySettings = new RepositorySettings(settings, Settings.builder().build());
|
||||||
|
AzureStorageService storageService = new AzureStorageServiceImpl(settings);
|
||||||
|
AzureBlobStore blobStore = new AzureBlobStore(repositoryName, settings, repositorySettings, storageService);
|
||||||
|
blobStore.createContainer(blobStore.container());
|
||||||
|
return blobStore;
|
||||||
|
} catch (URISyntaxException | StorageException e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Settings readSettingsFromFile() {
|
||||||
|
Settings.Builder settings = Settings.builder();
|
||||||
|
|
||||||
|
// if explicit, just load it and don't load from env
|
||||||
|
try {
|
||||||
|
if (Strings.hasText(System.getProperty("tests.config"))) {
|
||||||
|
settings.loadFromPath(PathUtils.get((System.getProperty("tests.config"))));
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("to run integration tests, you need to set -Dtests.thirdparty=true and -Dtests.config=/path/to/elasticsearch.yml");
|
||||||
|
}
|
||||||
|
} catch (SettingsException exception) {
|
||||||
|
throw new IllegalStateException("your test configuration file is incorrect: " + System.getProperty("tests.config"), exception);
|
||||||
|
}
|
||||||
|
return settings.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue