Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/plugins/repository-azure.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ before retrying after a first timeout or failure. The maximum backoff period is

[source,yaml]
----
cloud.azure.storage.timeout: 10s
azure.client.default.timeout: 10s
azure.client.default.max_retries: 7
azure.client.secondary.timeout: 30s
----
Expand Down
2 changes: 2 additions & 0 deletions docs/reference/migration/migrate_7_0.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ way to reindex old indices is to use the `reindex` API.
* <<breaking_70_indices_changes>>
* <<breaking_70_mappings_changes>>
* <<breaking_70_search_changes>>
* <<breaking_70_plugins_changes>>

include::migrate_7_0/aggregations.asciidoc[]
include::migrate_7_0/cluster.asciidoc[]
include::migrate_7_0/indices.asciidoc[]
include::migrate_7_0/mappings.asciidoc[]
include::migrate_7_0/search.asciidoc[]
include::migrate_7_0/plugins.asciidoc[]
14 changes: 14 additions & 0 deletions docs/reference/migration/migrate_7_0/plugins.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[[breaking_70_plugins_changes]]
=== Plugins changes

==== Azure Repository plugin

* The legacy azure settings which where starting with `cloud.azure.storage.` prefix have been removed.
This includes `account`, `key`, `default` and `timeout`.
You need to use settings which are starting with `azure.client.` prefix instead.

* Global timeout setting `cloud.azure.storage.timeout` has been removed.
You must set it per azure client instead. Like `azure.client.default.timeout: 10s` for example.

See {plugins}/repository-azure-usage.html#repository-azure-repository-settings[Azure Repository settings].

2 changes: 0 additions & 2 deletions plugins/repository-azure/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ thirdPartyAudit.excludes = [
]

integTestCluster {
setting 'cloud.azure.storage.my_account_test.account', 'cloudazureresource'
setting 'cloud.azure.storage.my_account_test.key', 'abcdefgh'
keystoreSetting 'azure.client.default.account', 'cloudazureresource'
keystoreSetting 'azure.client.default.key', 'abcdefgh'
keystoreSetting 'azure.client.secondary.account', 'cloudazureresource'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,8 @@
import com.microsoft.azure.storage.LocationMode;
import com.microsoft.azure.storage.StorageException;
import org.elasticsearch.common.blobstore.BlobMetaData;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.ByteSizeUnit;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;

import java.io.IOException;
import java.io.InputStream;
Expand All @@ -44,22 +40,6 @@ public interface AzureStorageService {
ByteSizeValue MIN_CHUNK_SIZE = new ByteSizeValue(1, ByteSizeUnit.BYTES);
ByteSizeValue MAX_CHUNK_SIZE = new ByteSizeValue(64, ByteSizeUnit.MB);

final class Storage {
@Deprecated
public static final String PREFIX = "cloud.azure.storage.";

@Deprecated
public static final Setting<Settings> STORAGE_ACCOUNTS = Setting.groupSetting(Storage.PREFIX, Setting.Property.NodeScope);

/**
* Azure timeout (defaults to -1 minute)
* @deprecated We don't want to support global timeout settings anymore
*/
@Deprecated
static final Setting<TimeValue> TIMEOUT_SETTING =
Setting.timeSetting("cloud.azure.storage.timeout", TimeValue.timeValueMinutes(-1), Property.NodeScope, Property.Deprecated);
}

boolean doesContainerExist(String account, LocationMode mode, String container);

void removeContainer(String account, LocationMode mode, String container) throws URISyntaxException, StorageException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,9 @@
import org.apache.logging.log4j.message.ParameterizedMessage;
import org.apache.logging.log4j.util.Supplier;
import org.elasticsearch.cloud.azure.blobstore.util.SocketAccess;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.blobstore.BlobMetaData;
import org.elasticsearch.common.blobstore.support.PlainBlobMetaData;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.repositories.RepositoryException;
Expand All @@ -53,53 +51,26 @@
public class AzureStorageServiceImpl extends AbstractComponent implements AzureStorageService {

final Map<String, AzureStorageSettings> storageSettings;
final Map<String, AzureStorageSettings> deprecatedStorageSettings;

final Map<String, CloudBlobClient> clients;
final Map<String, CloudBlobClient> clients = new HashMap<>();

public AzureStorageServiceImpl(Settings settings, Map<String, AzureStorageSettings> regularStorageSettings) {
public AzureStorageServiceImpl(Settings settings, Map<String, AzureStorageSettings> storageSettings) {
super(settings);

if (regularStorageSettings.isEmpty()) {
this.storageSettings = new HashMap<>();
// We have deprecated settings so we need to migrate them to the new implementation
Tuple<AzureStorageSettings, Map<String, AzureStorageSettings>> storageSettingsMapTuple = AzureStorageSettings.loadLegacy(settings);
deprecatedStorageSettings = storageSettingsMapTuple.v2();
if (storageSettingsMapTuple.v1() != null) {
if (storageSettingsMapTuple.v1().getName().equals("default") == false) {
// We add the primary configuration to the list of all settings with its deprecated name in case someone is
// forcing a specific configuration name when creating the repository instance
deprecatedStorageSettings.put(storageSettingsMapTuple.v1().getName(), storageSettingsMapTuple.v1());
}
// We add the primary configuration to the list of all settings as the "default" one
deprecatedStorageSettings.put("default", storageSettingsMapTuple.v1());
} else {
// If someone did not register any settings or deprecated settings, they
// basically can't use the plugin
throw new IllegalArgumentException("If you want to use an azure repository, you need to define a client configuration.");
}

this.storageSettings = storageSettings;

} else {
this.storageSettings = regularStorageSettings;
this.deprecatedStorageSettings = new HashMap<>();
if (storageSettings.isEmpty()) {
// If someone did not register any settings, they basically can't use the plugin
throw new IllegalArgumentException("If you want to use an azure repository, you need to define a client configuration.");
}

this.clients = new HashMap<>();

logger.debug("starting azure storage client instance");

// We register all regular azure clients
for (Map.Entry<String, AzureStorageSettings> azureStorageSettingsEntry : this.storageSettings.entrySet()) {
logger.debug("registering regular client for account [{}]", azureStorageSettingsEntry.getKey());
createClient(azureStorageSettingsEntry.getValue());
}

// We register all deprecated azure clients
for (Map.Entry<String, AzureStorageSettings> azureStorageSettingsEntry : this.deprecatedStorageSettings.entrySet()) {
logger.debug("registering deprecated client for account [{}]", azureStorageSettingsEntry.getKey());
createClient(azureStorageSettingsEntry.getValue());
}
}

void createClient(AzureStorageSettings azureStorageSettings) {
Expand All @@ -125,31 +96,21 @@ void createClient(AzureStorageSettings azureStorageSettings) {
}
}

CloudBlobClient getSelectedClient(String account, LocationMode mode) {
logger.trace("selecting a client for account [{}], mode [{}]", account, mode.name());
AzureStorageSettings azureStorageSettings = this.storageSettings.get(account);
CloudBlobClient getSelectedClient(String clientName, LocationMode mode) {
logger.trace("selecting a client named [{}], mode [{}]", clientName, mode.name());
AzureStorageSettings azureStorageSettings = this.storageSettings.get(clientName);
if (azureStorageSettings == null) {
// We can't find a client that has been registered using regular settings so we try deprecated client
azureStorageSettings = this.deprecatedStorageSettings.get(account);
if (azureStorageSettings == null) {
// We did not get an account. That's bad.
if (Strings.hasLength(account)) {
throw new IllegalArgumentException("Can not find named azure client [" + account +
"]. Check your elasticsearch.yml.");
}
throw new IllegalArgumentException("Can not find primary/secondary client using deprecated settings. " +
"Check your elasticsearch.yml.");
}
throw new IllegalArgumentException("Can not find named azure client [" + clientName + "]. Check your settings.");
}

CloudBlobClient client = this.clients.get(azureStorageSettings.getAccount());

if (client == null) {
throw new IllegalArgumentException("Can not find an azure client for account [" + azureStorageSettings.getAccount() + "]");
throw new IllegalArgumentException("Can not find an azure client named [" + azureStorageSettings.getAccount() + "]");
}

// NOTE: for now, just set the location mode in case it is different;
// only one mode per storage account can be active at a time
// only one mode per storage clientName can be active at a time
client.getDefaultRequestOptions().setLocationMode(mode);

// Set timeout option if the user sets cloud.azure.storage.timeout or cloud.azure.storage.xxx.timeout (it's negative by default)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,19 @@
package org.elasticsearch.cloud.azure.storage;

import com.microsoft.azure.storage.RetryPolicy;
import org.elasticsearch.cloud.azure.storage.AzureStorageService.Storage;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.settings.SecureSetting;
import org.elasticsearch.common.settings.SecureString;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.AffixSetting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsException;
import org.elasticsearch.common.unit.TimeValue;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static org.elasticsearch.cloud.azure.storage.AzureStorageService.Storage.STORAGE_ACCOUNTS;

public final class AzureStorageSettings {
// prefix for azure client settings
private static final String PREFIX = "azure.client.";
Expand All @@ -64,56 +57,20 @@ public final class AzureStorageSettings {
key -> SecureSetting.secureString(key, null));

public static final AffixSetting<TimeValue> TIMEOUT_SETTING = Setting.affixKeySetting(PREFIX, "timeout",
(key) -> Setting.timeSetting(key, Storage.TIMEOUT_SETTING, Property.NodeScope));


@Deprecated
public static final Setting<TimeValue> DEPRECATED_TIMEOUT_SETTING = Setting.affixKeySetting(Storage.PREFIX, "timeout",
(key) -> Setting.timeSetting(key, Storage.TIMEOUT_SETTING, Property.NodeScope, Property.Deprecated));
@Deprecated
public static final Setting<String> DEPRECATED_ACCOUNT_SETTING = Setting.affixKeySetting(Storage.PREFIX, "account",
(key) -> Setting.simpleString(key, Property.NodeScope, Property.Deprecated));
@Deprecated
public static final Setting<String> DEPRECATED_KEY_SETTING = Setting.affixKeySetting(Storage.PREFIX, "key",
(key) -> Setting.simpleString(key, Property.NodeScope, Property.Deprecated));
@Deprecated
public static final Setting<Boolean> DEPRECATED_DEFAULT_SETTING = Setting.affixKeySetting(Storage.PREFIX, "default",
(key) -> Setting.boolSetting(key, false, Property.NodeScope, Property.Deprecated));

(key) -> Setting.timeSetting(key, TimeValue.timeValueMinutes(-1), Property.NodeScope));

@Deprecated
private final String name;
private final String account;
private final String key;
private final TimeValue timeout;
@Deprecated
private final boolean activeByDefault;
private final int maxRetries;

public AzureStorageSettings(String account, String key, TimeValue timeout, int maxRetries) {
this.name = null;
this.account = account;
this.key = key;
this.timeout = timeout;
this.activeByDefault = false;
this.maxRetries = maxRetries;
}

@Deprecated
public AzureStorageSettings(String name, String account, String key, TimeValue timeout, boolean activeByDefault, int maxRetries) {
this.name = name;
this.account = account;
this.key = key;
this.timeout = timeout;
this.activeByDefault = activeByDefault;
this.maxRetries = maxRetries;
}

@Deprecated
public String getName() {
return name;
}

public String getKey() {
return key;
}
Expand All @@ -126,39 +83,21 @@ public TimeValue getTimeout() {
return timeout;
}

@Deprecated
public Boolean isActiveByDefault() {
return activeByDefault;
}

public int getMaxRetries() {
return maxRetries;
}

@Override
public String toString() {
final StringBuilder sb = new StringBuilder("AzureStorageSettings{");
sb.append("name='").append(name).append('\'');
sb.append(", account='").append(account).append('\'');
sb.append(", key='").append(key).append('\'');
sb.append(", activeByDefault='").append(activeByDefault).append('\'');
sb.append(", timeout=").append(timeout);
sb.append(", maxRetries=").append(maxRetries);
sb.append('}');
return sb.toString();
}

/**
* Parses settings and read all legacy settings available under cloud.azure.storage.*
* @param settings settings to parse
* @return A tuple with v1 = primary storage and v2 = secondary storage
*/
@Deprecated
public static Tuple<AzureStorageSettings, Map<String, AzureStorageSettings>> loadLegacy(Settings settings) {
List<AzureStorageSettings> storageSettings = createStorageSettingsDeprecated(settings);
return Tuple.tuple(getPrimary(storageSettings), getSecondaries(storageSettings));
}

/**
* Parses settings and read all settings available under azure.client.*
* @param settings settings to parse
Expand Down Expand Up @@ -192,25 +131,6 @@ static AzureStorageSettings getClientSettings(Settings settings, String clientNa
}
}

@Deprecated
private static List<AzureStorageSettings> createStorageSettingsDeprecated(Settings settings) {
// ignore global timeout which has the same prefix but does not belong to any group
Settings groups = STORAGE_ACCOUNTS.get(settings.filter((k) -> k.equals(Storage.TIMEOUT_SETTING.getKey()) == false));
List<AzureStorageSettings> storageSettings = new ArrayList<>();
for (String groupName : groups.getAsGroups().keySet()) {
storageSettings.add(
new AzureStorageSettings(
groupName,
getValue(settings, groupName, DEPRECATED_ACCOUNT_SETTING),
getValue(settings, groupName, DEPRECATED_KEY_SETTING),
getValue(settings, groupName, DEPRECATED_TIMEOUT_SETTING),
getValue(settings, groupName, DEPRECATED_DEFAULT_SETTING),
getValue(settings, groupName, MAX_RETRIES_SETTING))
);
}
return storageSettings;
}

private static <T> T getConfigValue(Settings settings, String clientName,
Setting.AffixSetting<T> clientSetting) {
Setting<T> concreteSetting = clientSetting.getConcreteSettingForNamespace(clientName);
Expand All @@ -222,45 +142,4 @@ public static <T> T getValue(Settings settings, String groupName, Setting<T> set
String fullKey = k.toConcreteKey(groupName).toString();
return setting.getConcreteSetting(fullKey).get(settings);
}

@Deprecated
private static AzureStorageSettings getPrimary(List<AzureStorageSettings> settings) {
if (settings.isEmpty()) {
return null;
} else if (settings.size() == 1) {
// the only storage settings belong (implicitly) to the default primary storage
AzureStorageSettings storage = settings.get(0);
return new AzureStorageSettings(storage.getName(), storage.getAccount(), storage.getKey(), storage.getTimeout(), true,
storage.getMaxRetries());
} else {
AzureStorageSettings primary = null;
for (AzureStorageSettings setting : settings) {
if (setting.isActiveByDefault()) {
if (primary == null) {
primary = setting;
} else {
throw new SettingsException("Multiple default Azure data stores configured: [" + primary.getName() + "] and [" + setting.getName() + "]");
}
}
}
if (primary == null) {
throw new SettingsException("No default Azure data store configured");
}
return primary;
}
}

@Deprecated
private static Map<String, AzureStorageSettings> getSecondaries(List<AzureStorageSettings> settings) {
Map<String, AzureStorageSettings> secondaries = new HashMap<>();
// when only one setting is defined, we don't have secondaries
if (settings.size() > 1) {
for (AzureStorageSettings setting : settings) {
if (setting.isActiveByDefault() == false) {
secondaries.put(setting.getName(), setting);
}
}
}
return secondaries;
}
}
Loading