Skip to content

Commit

Permalink
Adding translog durability validation in index templates
Browse files Browse the repository at this point in the history
Signed-off-by: Shourya Dutta Biswas <114977491+shourya035@users.noreply.github.com>
  • Loading branch information
shourya035 committed Aug 29, 2024
1 parent 8629279 commit 82b2fa3
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 2 deletions.
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,27 @@ 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 incomingSettings) {
ClusterService clusterService = mock(ClusterService.class);
Settings settings = Settings.builder().put(PATH_HOME_SETTING.getKey(), "dummy").build();
Settings settings = Settings.builder().put(incomingSettings).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 82b2fa3

Please sign in to comment.