From 6a14f13ba0fc54038e367b59779d534197214373 Mon Sep 17 00:00:00 2001 From: Drew Baugher Date: Wed, 16 Feb 2022 22:12:04 +0000 Subject: [PATCH] Use the keyword subfield instead of the tokenized text field for querying managed indices and policies Signed-off-by: Drew Baugher --- .../action/explain/TransportExplainAction.kt | 2 +- .../getpolicy/TransportGetPoliciesAction.kt | 2 +- .../IndexStateManagementRestTestCase.kt | 26 ++++- .../IndexStateManagementRestApiIT.kt | 38 ++++++ .../resthandler/RestExplainActionIT.kt | 108 ++++++++++++++++++ 5 files changed, 173 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/org/opensearch/indexmanagement/indexstatemanagement/transport/action/explain/TransportExplainAction.kt b/src/main/kotlin/org/opensearch/indexmanagement/indexstatemanagement/transport/action/explain/TransportExplainAction.kt index f6f189278..17ba9d595 100644 --- a/src/main/kotlin/org/opensearch/indexmanagement/indexstatemanagement/transport/action/explain/TransportExplainAction.kt +++ b/src/main/kotlin/org/opensearch/indexmanagement/indexstatemanagement/transport/action/explain/TransportExplainAction.kt @@ -110,7 +110,7 @@ class TransportExplainAction @Inject constructor( .must( QueryBuilders .queryStringQuery(params.queryString) - .defaultField("managed_index.name") + .defaultField("managed_index.name.keyword") .defaultOperator(Operator.AND) ) diff --git a/src/main/kotlin/org/opensearch/indexmanagement/indexstatemanagement/transport/action/getpolicy/TransportGetPoliciesAction.kt b/src/main/kotlin/org/opensearch/indexmanagement/indexstatemanagement/transport/action/getpolicy/TransportGetPoliciesAction.kt index 10c0f7c10..1fa0f1130 100644 --- a/src/main/kotlin/org/opensearch/indexmanagement/indexstatemanagement/transport/action/getpolicy/TransportGetPoliciesAction.kt +++ b/src/main/kotlin/org/opensearch/indexmanagement/indexstatemanagement/transport/action/getpolicy/TransportGetPoliciesAction.kt @@ -81,7 +81,7 @@ class TransportGetPoliciesAction @Inject constructor( QueryBuilders .queryStringQuery(params.queryString) .defaultOperator(Operator.AND) - .field("policy.policy_id") + .field("policy.policy_id.keyword") ) val searchSourceBuilder = SearchSourceBuilder() diff --git a/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/IndexStateManagementRestTestCase.kt b/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/IndexStateManagementRestTestCase.kt index 0625a61c5..08b016a40 100644 --- a/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/IndexStateManagementRestTestCase.kt +++ b/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/IndexStateManagementRestTestCase.kt @@ -190,6 +190,29 @@ abstract class IndexStateManagementRestTestCase : IndexManagementRestTestCase() return index to policyID } + protected fun createDataStream( + dataStream: String, + template: StringEntity? = null + ) { + val dataStreamTemplate = template ?: StringEntity( + """ + { + "data_stream": {}, + "index_patterns": ["$dataStream"] + } + """.trimIndent(), + APPLICATION_JSON + ) + val res = client().makeRequest( + "PUT", + "/_index_template/transform-data-stream-template", + dataStreamTemplate + ) + assertEquals("Unexpected RestStatus", RestStatus.OK, res.restStatus()) + val response = client().makeRequest("PUT", "/_data_stream/$dataStream") + assertEquals("Unexpected RestStatus", RestStatus.OK, response.restStatus()) + } + protected fun changeAlias( index: String, alias: String, @@ -532,9 +555,10 @@ abstract class IndexStateManagementRestTestCase : IndexManagementRestTestCase() protected fun getFlatSettings(indexName: String) = (getIndexSettings(indexName) as Map>>)[indexName]!!["settings"] as Map - protected fun getExplainMap(indexName: String?): Map { + protected fun getExplainMap(indexName: String?, queryParams: String = ""): Map { var endpoint = RestExplainAction.EXPLAIN_BASE_URI if (indexName != null) endpoint += "/$indexName" + if (queryParams.isNotEmpty()) endpoint += "?$queryParams" val response = client().makeRequest(RestRequest.Method.GET.toString(), endpoint) assertEquals("Unexpected RestStatus", RestStatus.OK, response.restStatus()) return response.asMap() diff --git a/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/resthandler/IndexStateManagementRestApiIT.kt b/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/resthandler/IndexStateManagementRestApiIT.kt index 435961b9b..30c1c3263 100644 --- a/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/resthandler/IndexStateManagementRestApiIT.kt +++ b/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/resthandler/IndexStateManagementRestApiIT.kt @@ -316,4 +316,42 @@ class IndexStateManagementRestApiIT : IndexStateManagementRestTestCase() { assertEquals(expectedMessage.toString(), actualMessage.toString()) } + + fun `test get policies with hyphen`() { + val randomPolicy = randomPolicy(id = "testing-hyphens-01") + createPolicy(randomPolicy, policyId = randomPolicy.id, refresh = true) + val policy = getPolicy(randomPolicy.id) + + val response = client().makeRequest(RestRequest.Method.GET.toString(), "$POLICY_BASE_URI?queryString=*testing-hyphens*") + + val actualMessage = response.asMap() + val expectedMessage = mapOf( + "total_policies" to 1, + "policies" to listOf( + mapOf( + _SEQ_NO to policy.seqNo, + _ID to policy.id, + _PRIMARY_TERM to policy.primaryTerm, + Policy.POLICY_TYPE to mapOf( + "schema_version" to policy.schemaVersion, + "policy_id" to policy.id, + "last_updated_time" to policy.lastUpdatedTime.toEpochMilli(), + "default_state" to policy.defaultState, + "ism_template" to null, + "description" to policy.description, + "error_notification" to policy.errorNotification, + "states" to policy.states.map { + mapOf( + "name" to it.name, + "transitions" to it.transitions, + "actions" to it.actions + ) + } + ) + ) + ) + ) + + assertEquals(expectedMessage.toString(), actualMessage.toString()) + } } diff --git a/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/resthandler/RestExplainActionIT.kt b/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/resthandler/RestExplainActionIT.kt index 729b3ed5b..51129c2a6 100644 --- a/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/resthandler/RestExplainActionIT.kt +++ b/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/resthandler/RestExplainActionIT.kt @@ -126,6 +126,114 @@ class RestExplainActionIT : IndexStateManagementRestTestCase() { } } + fun `test search query string`() { + val indexName1 = "$testIndexName-search-query-string" + val indexName2 = "$indexName1-testing-2" + val indexName3 = "$indexName1-testing-3" + val indexName4 = "$indexName1-testing-4-2022-02-15" + val indexName5 = "$indexName1-testing-5-15-02-2022" + val dataStreamName = "$indexName1-data-stream" + createDataStream(dataStreamName) + + val policy = createRandomPolicy() + createIndex(indexName1, policyID = policy.id) + createIndex(indexName2, policyID = policy.id) + createIndex(indexName3, null) + createIndex(indexName4, policyID = policy.id) + createIndex(indexName5, policyID = policy.id) + addPolicyToIndex(dataStreamName, policy.id) + val indexName1Map = indexName1 to mapOf( + explainResponseOpendistroPolicyIdSetting to policy.id, + explainResponseOpenSearchPolicyIdSetting to policy.id, + "index" to indexName1, + "index_uuid" to getUuid(indexName1), + "policy_id" to policy.id, + "enabled" to true + ) + val indexName2Map = indexName2 to mapOf( + explainResponseOpendistroPolicyIdSetting to policy.id, + explainResponseOpenSearchPolicyIdSetting to policy.id, + "index" to indexName2, + "index_uuid" to getUuid(indexName2), + "policy_id" to policy.id, + "enabled" to true + ) + val indexName4Map = indexName4 to mapOf( + explainResponseOpendistroPolicyIdSetting to policy.id, + explainResponseOpenSearchPolicyIdSetting to policy.id, + "index" to indexName4, + "index_uuid" to getUuid(indexName4), + "policy_id" to policy.id, + "enabled" to true + ) + val indexName5Map = indexName5 to mapOf( + explainResponseOpendistroPolicyIdSetting to policy.id, + explainResponseOpenSearchPolicyIdSetting to policy.id, + "index" to indexName5, + "index_uuid" to getUuid(indexName5), + "policy_id" to policy.id, + "enabled" to true + ) + val datastreamMap = ".ds-$dataStreamName-000001" to mapOf( + explainResponseOpendistroPolicyIdSetting to policy.id, + explainResponseOpenSearchPolicyIdSetting to policy.id, + "index" to ".ds-$dataStreamName-000001", + "index_uuid" to getUuid(".ds-$dataStreamName-000001"), + "policy_id" to policy.id, + "enabled" to true + ) + + waitFor { + val expected = mapOf( + indexName1Map, + indexName2Map, + indexName4Map, + indexName5Map, + "total_managed_indices" to 4 + ) + // These should match all non datastream managed indices + assertResponseMap(expected, getExplainMap(indexName = null, queryParams = "queryString=$testIndexName*")) + assertResponseMap(expected, getExplainMap(indexName = null, queryParams = "queryString=$testIndexName-*")) + assertResponseMap(expected, getExplainMap(indexName = null, queryParams = "queryString=$testIndexName-search-*")) + } + + waitFor { + val expected = mapOf( + indexName1Map, + indexName2Map, + indexName4Map, + indexName5Map, + datastreamMap, + "total_managed_indices" to 5 + ) + // These should match all managed indices including datastreams + assertResponseMap(expected, getExplainMap(indexName = null, queryParams = "queryString=*$testIndexName-*")) + assertResponseMap(expected, getExplainMap(indexName = null, queryParams = "queryString=*search*")) + assertResponseMap(expected, getExplainMap(indexName = null, queryParams = "queryString=*search-query*")) + } + + waitFor { + val expected = mapOf( + datastreamMap, + "total_managed_indices" to 1 + ) + // These should match all datastream managed indices (and system/hidden indices) + assertResponseMap(expected, getExplainMap(indexName = null, queryParams = "queryString=.*")) + assertResponseMap(expected, getExplainMap(indexName = null, queryParams = "queryString=.ds-$testIndexName-*")) + } + + waitFor { + val expected = mapOf( + indexName4Map, + "total_managed_indices" to 1 + ) + // These should match all just the single index, and validates that it does not match the 15-02-2022 index + // i.e. if it was still matching on tokens then ["2022", "02", "15"] would match both which we don't want + assertResponseMap(expected, getExplainMap(indexName = null, queryParams = "queryString=*2022-02-15")) + assertResponseMap(expected, getExplainMap(indexName = null, queryParams = "queryString=*2022-02-15*")) + } + } + fun `test attached policy`() { val indexName = "${testIndexName}_watermelon" val policy = createRandomPolicy()