Skip to content

Commit

Permalink
Adding translog durability validation in index templates (opensearch-…
Browse files Browse the repository at this point in the history
…project#15494)

---------

Signed-off-by: Shourya Dutta Biswas <[email protected]>
  • Loading branch information
shourya035 authored and akolarkunnu committed Sep 10, 2024
1 parent 33e8fe4 commit 9a85793
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Add runAs to Subject interface and introduce IdentityAwarePlugin extension point ([#14630](https://github.com/opensearch-project/OpenSearch/pull/14630))
- Optimize NodeIndicesStats output behind flag ([#14454](https://github.com/opensearch-project/OpenSearch/pull/14454))
- [Workload Management] Add rejection logic for co-ordinator and shard level requests ([#15428](https://github.com/opensearch-project/OpenSearch/pull/15428)))
- Adding translog durability validation in index templates ([#15494](https://github.com/opensearch-project/OpenSearch/pull/15494))

### Dependencies
- Bump `netty` from 4.1.111.Final to 4.1.112.Final ([#15081](https://github.com/opensearch-project/OpenSearch/pull/15081))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -932,4 +933,38 @@ public void testFlushOnTooManyRemoteTranslogFiles() throws Exception {
assertEquals(totalFiles, 501L);
}
}

public void testAsyncTranslogDurabilityRestrictionsThroughIdxTemplates() throws Exception {
logger.info("Starting up cluster manager with cluster.remote_store.index.restrict.async-durability set to true");
String cm1 = internalCluster().startClusterManagerOnlyNode(
Settings.builder().put(IndicesService.CLUSTER_REMOTE_INDEX_RESTRICT_ASYNC_DURABILITY_SETTING.getKey(), true).build()
);
internalCluster().startDataOnlyNode();
ensureStableCluster(2);
assertThrows(
IllegalArgumentException.class,
() -> internalCluster().client()
.admin()
.indices()
.preparePutTemplate("test")
.setPatterns(Arrays.asList("test*"))
.setSettings(Settings.builder().put(IndexSettings.INDEX_TRANSLOG_DURABILITY_SETTING.getKey(), "async"))
.get()
);
logger.info("Starting up another cluster manager with cluster.remote_store.index.restrict.async-durability set to false");
internalCluster().startClusterManagerOnlyNode(
Settings.builder().put(IndicesService.CLUSTER_REMOTE_INDEX_RESTRICT_ASYNC_DURABILITY_SETTING.getKey(), false).build()
);
internalCluster().stopRandomNode(InternalTestCluster.nameFilter(cm1));
ensureStableCluster(2);
assertAcked(
internalCluster().client()
.admin()
.indices()
.preparePutTemplate("test")
.setPatterns(Arrays.asList("test*"))
.setSettings(Settings.builder().put(IndexSettings.INDEX_TRANSLOG_DURABILITY_SETTING.getKey(), "async"))
.get()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,11 @@
import org.opensearch.core.xcontent.NamedXContentRegistry;
import org.opensearch.core.xcontent.XContentBuilder;
import org.opensearch.index.IndexService;
import org.opensearch.index.IndexSettings;
import org.opensearch.index.mapper.MapperParsingException;
import org.opensearch.index.mapper.MapperService;
import org.opensearch.index.mapper.MapperService.MergeReason;
import org.opensearch.index.translog.Translog;
import org.opensearch.indices.IndexTemplateMissingException;
import org.opensearch.indices.IndicesService;
import org.opensearch.indices.InvalidIndexTemplateException;
Expand Down Expand Up @@ -1632,8 +1634,9 @@ private void validate(String name, @Nullable Settings settings, List<String> ind
);
validationErrors.addAll(indexSettingsValidation);

// validate index refresh interval settings
// validate index refresh interval and translog durability settings
validateRefreshIntervalSettings(settings, clusterService.getClusterSettings());
validateTranslogDurabilitySettingsInTemplate(settings, clusterService.getClusterSettings());
}

if (indexPatterns.stream().anyMatch(Regex::isMatchAllPattern)) {
Expand All @@ -1659,6 +1662,29 @@ private void validate(String name, @Nullable Settings settings, List<String> ind
}
}

/**
* Validates {@code index.translog.durability} is not async with the incoming index template
* if the {@code cluster.remote_store.index.restrict.async-durability} is set to true.
*
* @param requestSettings settings passed during template creation
* @param clusterSettings current cluster settings
*/
private void validateTranslogDurabilitySettingsInTemplate(Settings requestSettings, ClusterSettings clusterSettings) {
if (IndexSettings.INDEX_TRANSLOG_DURABILITY_SETTING.exists(requestSettings) == false
|| clusterSettings.get(IndicesService.CLUSTER_REMOTE_INDEX_RESTRICT_ASYNC_DURABILITY_SETTING) == false) {
return;
}
Translog.Durability durability = IndexSettings.INDEX_TRANSLOG_DURABILITY_SETTING.get(requestSettings);
if (durability.equals(Translog.Durability.ASYNC)) {
throw new IllegalArgumentException(
"index setting [index.translog.durability=async] is not allowed as cluster setting ["
+ IndicesService.CLUSTER_REMOTE_INDEX_RESTRICT_ASYNC_DURABILITY_SETTING.getKey()
+ "=true]"
);
}

}

/**
* Listener for putting metadata in the template
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import org.opensearch.core.xcontent.NamedXContentRegistry;
import org.opensearch.core.xcontent.XContentParser;
import org.opensearch.env.Environment;
import org.opensearch.index.IndexSettings;
import org.opensearch.index.codec.CodecService;
import org.opensearch.index.engine.EngineConfig;
import org.opensearch.index.mapper.MapperParsingException;
Expand Down Expand Up @@ -2410,9 +2411,31 @@ public void testLegacyNoopUpdate() {
assertThat(MetadataIndexTemplateService.innerPutTemplate(state, pr, new IndexTemplateMetadata.Builder("id")), equalTo(state));
}

public void testAsyncTranslogDurabilityBlocked() {
Settings clusterSettings = Settings.builder()
.put(IndicesService.CLUSTER_REMOTE_INDEX_RESTRICT_ASYNC_DURABILITY_SETTING.getKey(), true)
.build();
PutRequest request = new PutRequest("test", "test_replicas");
request.patterns(singletonList("test_shards_wait*"));
Settings.Builder settingsBuilder = builder().put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, "1")
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, "1")
.put(IndexSettings.INDEX_TRANSLOG_DURABILITY_SETTING.getKey(), "async");
request.settings(settingsBuilder.build());
List<Throwable> throwables = putTemplate(xContentRegistry(), request, clusterSettings);
assertThat(throwables.get(0), instanceOf(IllegalArgumentException.class));
}

private static List<Throwable> putTemplate(NamedXContentRegistry xContentRegistry, PutRequest request) {
return putTemplate(xContentRegistry, request, Settings.EMPTY);
}

private static List<Throwable> putTemplate(
NamedXContentRegistry xContentRegistry,
PutRequest request,
Settings incomingNodeScopedSettings
) {
ClusterService clusterService = mock(ClusterService.class);
Settings settings = Settings.builder().put(PATH_HOME_SETTING.getKey(), "dummy").build();
Settings settings = Settings.builder().put(incomingNodeScopedSettings).put(PATH_HOME_SETTING.getKey(), "dummy").build();
ClusterSettings clusterSettings = new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
Metadata metadata = Metadata.builder().build();
ClusterState clusterState = ClusterState.builder(org.opensearch.cluster.ClusterName.CLUSTER_NAME_SETTING.getDefault(Settings.EMPTY))
Expand Down

0 comments on commit 9a85793

Please sign in to comment.