diff --git a/docs/plugins/repository-azure.asciidoc b/docs/plugins/repository-azure.asciidoc index ea413719f2446..583217324edda 100644 --- a/docs/plugins/repository-azure.asciidoc +++ b/docs/plugins/repository-azure.asciidoc @@ -44,15 +44,18 @@ The initial backoff period is defined by Azure SDK as `30s`. Which means `30s` o before retrying after a first timeout or failure. The maximum backoff period is defined by Azure SDK as `90s`. +`endpoint_suffix` can be used to specify Azure endpoint suffix explicitly. Defaults to `core.windows.net`. + [source,yaml] ---- azure.client.default.timeout: 10s azure.client.default.max_retries: 7 +azure.client.default.endpoint_suffix: core.chinacloudapi.cn azure.client.secondary.timeout: 30s ---- In this example, timeout will be `10s` per try for `default` with `7` retries before failing -and `30s` per try for `secondary` with `3` retries. +and endpoint suffix will be `core.chinacloudapi.cn` and `30s` per try for `secondary` with `3` retries. [IMPORTANT] .Supported Azure Storage Account types diff --git a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepositoryPlugin.java b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepositoryPlugin.java index 3fd09962aedcb..c0126cb8df065 100644 --- a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepositoryPlugin.java +++ b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepositoryPlugin.java @@ -60,6 +60,7 @@ public List> getSettings() { return Arrays.asList( AzureStorageSettings.ACCOUNT_SETTING, AzureStorageSettings.KEY_SETTING, + AzureStorageSettings.ENDPOINT_SUFFIX_SETTING, AzureStorageSettings.TIMEOUT_SETTING, AzureStorageSettings.PROXY_TYPE_SETTING, AzureStorageSettings.PROXY_HOST_SETTING, diff --git a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureStorageServiceImpl.java b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureStorageServiceImpl.java index 03a590867a7ed..a4b415351b76e 100644 --- a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureStorageServiceImpl.java +++ b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureStorageServiceImpl.java @@ -79,14 +79,18 @@ public AzureStorageServiceImpl(Settings settings, Map Setting.intSetting(key, RetryPolicy.DEFAULT_CLIENT_RETRY_COUNT, Setting.Property.NodeScope)); + /** + * Azure endpoint suffix. Default to core.windows.net (CloudStorageAccount.DEFAULT_DNS). + */ + public static final Setting ENDPOINT_SUFFIX_SETTING = Setting.affixKeySetting(PREFIX, "endpoint_suffix", + key -> Setting.simpleString(key, Property.NodeScope)); /** Azure key */ public static final AffixSetting KEY_SETTING = Setting.affixKeySetting(PREFIX, "key", @@ -74,15 +79,17 @@ public final class AzureStorageSettings { private final String account; private final String key; + private final String endpointSuffix; private final TimeValue timeout; private final int maxRetries; private final Proxy proxy; - public AzureStorageSettings(String account, String key, TimeValue timeout, int maxRetries, Proxy.Type proxyType, String proxyHost, - Integer proxyPort) { + public AzureStorageSettings(String account, String key, String endpointSuffix, TimeValue timeout, int maxRetries, + Proxy.Type proxyType, String proxyHost, Integer proxyPort) { this.account = account; this.key = key; + this.endpointSuffix = endpointSuffix; this.timeout = timeout; this.maxRetries = maxRetries; @@ -114,6 +121,10 @@ public String getAccount() { return account; } + public String getEndpointSuffix() { + return endpointSuffix; + } + public TimeValue getTimeout() { return timeout; } @@ -132,6 +143,7 @@ public String toString() { sb.append(", account='").append(account).append('\''); sb.append(", key='").append(key).append('\''); sb.append(", timeout=").append(timeout); + sb.append(", endpointSuffix='").append(endpointSuffix).append('\''); sb.append(", maxRetries=").append(maxRetries); sb.append(", proxy=").append(proxy); sb.append('}'); @@ -166,6 +178,7 @@ static AzureStorageSettings getClientSettings(Settings settings, String clientNa try (SecureString account = getConfigValue(settings, clientName, ACCOUNT_SETTING); SecureString key = getConfigValue(settings, clientName, KEY_SETTING)) { return new AzureStorageSettings(account.toString(), key.toString(), + getValue(settings, clientName, ENDPOINT_SUFFIX_SETTING), getValue(settings, clientName, TIMEOUT_SETTING), getValue(settings, clientName, MAX_RETRIES_SETTING), getValue(settings, clientName, PROXY_TYPE_SETTING), diff --git a/plugins/repository-azure/src/test/java/org/elasticsearch/repositories/azure/AzureStorageServiceTests.java b/plugins/repository-azure/src/test/java/org/elasticsearch/repositories/azure/AzureStorageServiceTests.java index 76a99fc174c58..72cd015f14847 100644 --- a/plugins/repository-azure/src/test/java/org/elasticsearch/repositories/azure/AzureStorageServiceTests.java +++ b/plugins/repository-azure/src/test/java/org/elasticsearch/repositories/azure/AzureStorageServiceTests.java @@ -22,6 +22,8 @@ import com.microsoft.azure.storage.LocationMode; import com.microsoft.azure.storage.RetryExponentialRetry; import com.microsoft.azure.storage.blob.CloudBlobClient; +import com.microsoft.azure.storage.core.Base64; + import org.elasticsearch.common.settings.MockSecureSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsException; @@ -33,12 +35,15 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.UnknownHostException; +import java.nio.charset.StandardCharsets; import java.util.Map; import static org.elasticsearch.repositories.azure.AzureStorageServiceImpl.blobNameFromUri; import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isEmptyString; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; @@ -69,10 +74,31 @@ public void testReadSecuredSettings() { secureSettings.setString("azure.client.azure2.key", "mykey2"); secureSettings.setString("azure.client.azure3.account", "myaccount3"); secureSettings.setString("azure.client.azure3.key", "mykey3"); - Settings settings = Settings.builder().setSecureSettings(secureSettings).build(); + Settings settings = Settings.builder().setSecureSettings(secureSettings) + .put("azure.client.azure3.endpoint_suffix", "my_endpoint_suffix").build(); Map loadedSettings = AzureStorageSettings.load(settings); assertThat(loadedSettings.keySet(), containsInAnyOrder("azure1","azure2","azure3","default")); + + assertThat(loadedSettings.get("azure1").getEndpointSuffix(), isEmptyString()); + assertThat(loadedSettings.get("azure2").getEndpointSuffix(), isEmptyString()); + assertThat(loadedSettings.get("azure3").getEndpointSuffix(), equalTo("my_endpoint_suffix")); + } + + public void testCreateClientWithEndpointSuffix() { + MockSecureSettings secureSettings = new MockSecureSettings(); + secureSettings.setString("azure.client.azure1.account", "myaccount1"); + secureSettings.setString("azure.client.azure1.key", Base64.encode("mykey1".getBytes(StandardCharsets.UTF_8))); + secureSettings.setString("azure.client.azure2.account", "myaccount2"); + secureSettings.setString("azure.client.azure2.key", Base64.encode("mykey2".getBytes(StandardCharsets.UTF_8))); + Settings settings = Settings.builder().setSecureSettings(secureSettings) + .put("azure.client.azure1.endpoint_suffix", "my_endpoint_suffix").build(); + AzureStorageServiceImpl azureStorageService = new AzureStorageServiceImpl(settings, AzureStorageSettings.load(settings)); + CloudBlobClient client1 = azureStorageService.getSelectedClient("azure1", LocationMode.PRIMARY_ONLY); + assertThat(client1.getEndpoint().toString(), equalTo("https://myaccount1.blob.my_endpoint_suffix")); + + CloudBlobClient client2 = azureStorageService.getSelectedClient("azure2", LocationMode.PRIMARY_ONLY); + assertThat(client2.getEndpoint().toString(), equalTo("https://myaccount2.blob.core.windows.net")); } public void testGetSelectedClientWithNoPrimaryAndSecondary() {