diff --git a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java index 1cf75780ce1..2ae5fbe8493 100644 --- a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java +++ b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java @@ -100,11 +100,18 @@ public class AzureRepository extends BlobStoreRepository { this.compress = getValue(metadata.settings(), settings, Repository.COMPRESS_SETTING, Storage.COMPRESS_SETTING); String modeStr = getValue(metadata.settings(), settings, Repository.LOCATION_MODE_SETTING, Storage.LOCATION_MODE_SETTING); - if (Strings.hasLength(modeStr)) { - LocationMode locationMode = LocationMode.valueOf(modeStr.toUpperCase(Locale.ROOT)); - readonly = locationMode == LocationMode.SECONDARY_ONLY; + Boolean forcedReadonly = metadata.settings().getAsBoolean("readonly", null); + // If the user explicitly did not define a readonly value, we set it by ourselves depending on the location mode setting. + // For secondary_only setting, the repository should be read only + if (forcedReadonly == null) { + if (Strings.hasLength(modeStr)) { + LocationMode locationMode = LocationMode.valueOf(modeStr.toUpperCase(Locale.ROOT)); + this.readonly = locationMode == LocationMode.SECONDARY_ONLY; + } else { + this.readonly = false; + } } else { - readonly = false; + readonly = forcedReadonly; } String basePath = getValue(metadata.settings(), settings, Repository.BASE_PATH_SETTING, Storage.BASE_PATH_SETTING); diff --git a/plugins/repository-azure/src/test/java/org/elasticsearch/repositories/azure/AzureRepositorySettingsTests.java b/plugins/repository-azure/src/test/java/org/elasticsearch/repositories/azure/AzureRepositorySettingsTests.java new file mode 100644 index 00000000000..68b3783b03a --- /dev/null +++ b/plugins/repository-azure/src/test/java/org/elasticsearch/repositories/azure/AzureRepositorySettingsTests.java @@ -0,0 +1,104 @@ +/* + * 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.LocationMode; +import com.microsoft.azure.storage.StorageException; +import com.microsoft.azure.storage.blob.CloudBlobClient; +import org.elasticsearch.cloud.azure.storage.AzureStorageService; +import org.elasticsearch.cloud.azure.storage.AzureStorageServiceImpl; +import org.elasticsearch.cloud.azure.storage.AzureStorageSettings; +import org.elasticsearch.cluster.metadata.RepositoryMetaData; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.env.Environment; +import org.elasticsearch.env.NodeEnvironment; +import org.elasticsearch.test.ESTestCase; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +import static org.elasticsearch.cloud.azure.storage.AzureStorageServiceImpl.blobNameFromUri; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.nullValue; + +public class AzureRepositorySettingsTests extends ESTestCase { + + private AzureRepository azureRepository(Settings settings) throws StorageException, IOException, URISyntaxException { + Settings internalSettings = Settings.builder() + .put(Environment.PATH_HOME_SETTING.getKey(), createTempDir().toAbsolutePath()) + .putArray(Environment.PATH_DATA_SETTING.getKey(), tmpPaths()) + .put(settings) + .build(); + return new AzureRepository(new RepositoryMetaData("foo", "azure", internalSettings), new Environment(internalSettings), null); + } + + + public void testReadonlyDefault() throws StorageException, IOException, URISyntaxException { + assertThat(azureRepository(Settings.EMPTY).isReadOnly(), is(false)); + } + + public void testReadonlyDefaultAndReadonlyOn() throws StorageException, IOException, URISyntaxException { + assertThat(azureRepository(Settings.builder() + .put("readonly", true) + .build()).isReadOnly(), is(true)); + } + + public void testReadonlyWithPrimaryOnly() throws StorageException, IOException, URISyntaxException { + assertThat(azureRepository(Settings.builder() + .put(AzureRepository.Repository.LOCATION_MODE_SETTING.getKey(), LocationMode.PRIMARY_ONLY.name()) + .build()).isReadOnly(), is(false)); + } + + public void testReadonlyWithPrimaryOnlyAndReadonlyOn() throws StorageException, IOException, URISyntaxException { + assertThat(azureRepository(Settings.builder() + .put(AzureRepository.Repository.LOCATION_MODE_SETTING.getKey(), LocationMode.PRIMARY_ONLY.name()) + .put("readonly", true) + .build()).isReadOnly(), is(true)); + } + + public void testReadonlyWithSecondaryOnlyAndReadonlyOn() throws StorageException, IOException, URISyntaxException { + assertThat(azureRepository(Settings.builder() + .put(AzureRepository.Repository.LOCATION_MODE_SETTING.getKey(), LocationMode.SECONDARY_ONLY.name()) + .put("readonly", true) + .build()).isReadOnly(), is(true)); + } + + public void testReadonlyWithSecondaryOnlyAndReadonlyOff() throws StorageException, IOException, URISyntaxException { + assertThat(azureRepository(Settings.builder() + .put(AzureRepository.Repository.LOCATION_MODE_SETTING.getKey(), LocationMode.SECONDARY_ONLY.name()) + .put("readonly", false) + .build()).isReadOnly(), is(false)); + } + + public void testReadonlyWithPrimaryAndSecondaryOnlyAndReadonlyOn() throws StorageException, IOException, URISyntaxException { + assertThat(azureRepository(Settings.builder() + .put(AzureRepository.Repository.LOCATION_MODE_SETTING.getKey(), LocationMode.PRIMARY_THEN_SECONDARY.name()) + .put("readonly", true) + .build()).isReadOnly(), is(true)); + } + + public void testReadonlyWithPrimaryAndSecondaryOnlyAndReadonlyOff() throws StorageException, IOException, URISyntaxException { + assertThat(azureRepository(Settings.builder() + .put(AzureRepository.Repository.LOCATION_MODE_SETTING.getKey(), LocationMode.PRIMARY_THEN_SECONDARY.name()) + .put("readonly", false) + .build()).isReadOnly(), is(false)); + } +}