Skip to content

Commit 93b43f4

Browse files
authored
Adding Index Settings validation before starting replication (#461)
* Adding Index Settings validation before starting replication Signed-off-by: Gaurav Bafna <gbbafna@amazon.com> * Retrieving default index settings before starting replication Signed-off-by: Gaurav Bafna <gbbafna@amazon.com>
1 parent db5029a commit 93b43f4

File tree

3 files changed

+52
-4
lines changed

3 files changed

+52
-4
lines changed

src/main/kotlin/org/opensearch/replication/action/index/TransportReplicateIndexAction.kt

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import org.opensearch.action.support.HandledTransportAction
3333
import org.opensearch.action.support.IndicesOptions
3434
import org.opensearch.client.Client
3535
import org.opensearch.cluster.ClusterState
36-
import org.opensearch.cluster.metadata.IndexMetadata
36+
import org.opensearch.cluster.metadata.MetadataCreateIndexService
3737
import org.opensearch.common.inject.Inject
3838
import org.opensearch.common.settings.Settings
3939
import org.opensearch.env.Environment
@@ -48,7 +48,8 @@ class TransportReplicateIndexAction @Inject constructor(transportService: Transp
4848
val threadPool: ThreadPool,
4949
actionFilters: ActionFilters,
5050
private val client : Client,
51-
private val environment: Environment) :
51+
private val environment: Environment,
52+
private val metadataCreateIndexService: MetadataCreateIndexService) :
5253
HandledTransportAction<ReplicateIndexRequest, ReplicateIndexResponse>(ReplicateIndexAction.NAME,
5354
transportService, actionFilters, ::ReplicateIndexRequest),
5455
CoroutineScope by GlobalScope {
@@ -102,7 +103,13 @@ class TransportReplicateIndexAction @Inject constructor(transportService: Transp
102103
throw IllegalArgumentException("Cannot replicate k-NN index - ${request.leaderIndex}")
103104
}
104105

105-
ValidationUtil.validateAnalyzerSettings(environment, leaderSettings, request.settings)
106+
ValidationUtil.validateIndexSettings(
107+
environment,
108+
request.followerIndex,
109+
leaderSettings,
110+
request.settings,
111+
metadataCreateIndexService
112+
)
106113

107114
// Setup checks are successful and trigger replication for the index
108115
// permissions evaluation to trigger replication is based on the current security context set
@@ -128,7 +135,7 @@ class TransportReplicateIndexAction @Inject constructor(transportService: Transp
128135

129136
private suspend fun getLeaderIndexSettings(leaderAlias: String, leaderIndex: String): Settings {
130137
val remoteClient = client.getRemoteClusterClient(leaderAlias)
131-
val getSettingsRequest = GetSettingsRequest().includeDefaults(false).indices(leaderIndex)
138+
val getSettingsRequest = GetSettingsRequest().includeDefaults(true).indices(leaderIndex)
132139
val settingsResponse = remoteClient.suspending(remoteClient.admin().indices()::getSettings,
133140
injectSecurityContext = true)(getSettingsRequest)
134141
return settingsResponse.indexToSettings.get(leaderIndex) ?: throw IndexNotFoundException("${leaderAlias}:${leaderIndex}")

src/main/kotlin/org/opensearch/replication/util/ValidationUtil.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,27 @@ object ValidationUtil {
3131

3232
private val log = LogManager.getLogger(ValidationUtil::class.java)
3333

34+
fun validateIndexSettings(
35+
environment: Environment,
36+
followerIndex: String,
37+
leaderSettings: Settings,
38+
overriddenSettings: Settings,
39+
metadataCreateIndexService: MetadataCreateIndexService
40+
) {
41+
val settingsList = arrayOf(leaderSettings, overriddenSettings)
42+
val desiredSettingsBuilder = Settings.builder()
43+
// Desired settings are taking leader Settings and then overriding them with desired settings
44+
for (settings in settingsList) {
45+
for (key in settings.keySet()) {
46+
desiredSettingsBuilder.copy(key, settings);
47+
}
48+
}
49+
val desiredSettings = desiredSettingsBuilder.build()
50+
51+
metadataCreateIndexService.validateIndexSettings(followerIndex,desiredSettings, false)
52+
validateAnalyzerSettings(environment, leaderSettings, overriddenSettings)
53+
}
54+
3455
fun validateAnalyzerSettings(environment: Environment, leaderSettings: Settings, overriddenSettings: Settings) {
3556
val analyserSettings = leaderSettings.filter { k: String? -> k!!.matches(Regex("index.analysis.*path")) }
3657
for (analyserSetting in analyserSettings.keySet()) {

src/test/kotlin/org/opensearch/replication/integ/rest/StartReplicationIT.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,6 +1169,26 @@ class StartReplicationIT: MultiClusterRestTestCase() {
11691169
}
11701170
}
11711171

1172+
fun `test start replication invalid settings`() {
1173+
val followerClient = getClientForCluster(FOLLOWER)
1174+
val leaderClient = getClientForCluster(LEADER)
1175+
1176+
createConnectionBetweenClusters(FOLLOWER, LEADER)
1177+
1178+
val createIndexResponse = leaderClient.indices().create(CreateIndexRequest(leaderIndexName), RequestOptions.DEFAULT)
1179+
assertThat(createIndexResponse.isAcknowledged).isTrue()
1180+
val settings = Settings.builder()
1181+
.put("index.data_path", "/random-path/invalid-setting")
1182+
.build()
1183+
1184+
try {
1185+
followerClient.startReplication(StartReplicationRequest("source", leaderIndexName, followerIndexName, settings = settings))
1186+
} catch (e: ResponseException) {
1187+
Assert.assertEquals(400, e.response.statusLine.statusCode)
1188+
Assert.assertTrue(e.message!!.contains("Validation Failed: 1: custom path [/random-path/invalid-setting] is not a sub-path of path.shared_data"))
1189+
}
1190+
}
1191+
11721192
fun `test that replication is not started when all primary shards are not in active state`() {
11731193
val followerClient = getClientForCluster(FOLLOWER)
11741194
val leaderClient = getClientForCluster(LEADER)

0 commit comments

Comments
 (0)