From 5aeed27cf1707cb1149be7d29be0e447e8db6b3e Mon Sep 17 00:00:00 2001 From: Joshua152 <59714582+Joshua152@users.noreply.github.com> Date: Tue, 19 Dec 2023 12:50:50 -0500 Subject: [PATCH] Issue651 tests (#1046) * Implemented filtering on the ISM eplain API Signed-off-by: Joshua Au * Fixed tests for ExplainRequest Signed-off-by: Joshua Au * Added filtering on query and metadata map Signed-off-by: Joshua Au * Filtered on indexNames in metadata Signed-off-by: Joshua Au * Fixed github workflow check errors Signed-off-by: Joshua Au * Removed debugging comments Signed-off-by: Joshua Au * Updated code styling to make more clear Signed-off-by: Joshua Au * Refactored code to match suggestions Signed-off-by: Joshua Au * Added test case for the ExplainFilter.byMetaData and parse methods Signed-off-by: Joshua Au * Started implementation of explain filter IT Signed-off-by: Joshua Au * Implemented test explain filter method Signed-off-by: Joshua Au * Implemented explain filter test on failure Signed-off-by: Joshua Au * Cleaned up log statements Signed-off-by: Joshua Au * Added explain filter test for success Signed-off-by: Joshua Au * Fixed lint errors Signed-off-by: Joshua Au * Removed policy from index to fix flaky tests Signed-off-by: Joshua Au --------- Signed-off-by: Joshua Au Signed-off-by: bowenlan-amzn Co-authored-by: bowenlan-amzn --- .../model/ExplainFilter.kt | 18 +- .../IndexStateManagementRestTestCase.kt | 13 +- .../indexstatemanagement/TestHelpers.kt | 15 + .../model/ExplainFilterTests.kt | 35 +++ .../model/XContentTests.kt | 9 + .../resthandler/RestExplainActionIT.kt | 268 +++++++++++++++++- .../RestRetryFailedManagedIndexActionIT.kt | 19 +- 7 files changed, 356 insertions(+), 21 deletions(-) create mode 100644 src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/model/ExplainFilterTests.kt diff --git a/src/main/kotlin/org/opensearch/indexmanagement/indexstatemanagement/model/ExplainFilter.kt b/src/main/kotlin/org/opensearch/indexmanagement/indexstatemanagement/model/ExplainFilter.kt index 5749becb6..7a2f7c1ca 100644 --- a/src/main/kotlin/org/opensearch/indexmanagement/indexstatemanagement/model/ExplainFilter.kt +++ b/src/main/kotlin/org/opensearch/indexmanagement/indexstatemanagement/model/ExplainFilter.kt @@ -8,6 +8,9 @@ package org.opensearch.indexmanagement.indexstatemanagement.model import org.opensearch.core.common.io.stream.StreamInput import org.opensearch.core.common.io.stream.StreamOutput import org.opensearch.core.common.io.stream.Writeable +import org.opensearch.core.xcontent.ToXContent +import org.opensearch.core.xcontent.ToXContentObject +import org.opensearch.core.xcontent.XContentBuilder import org.opensearch.core.xcontent.XContentParser import org.opensearch.core.xcontent.XContentParser.Token import org.opensearch.core.xcontent.XContentParserUtils.ensureExpectedToken @@ -22,7 +25,7 @@ data class ExplainFilter( val state: String? = null, val actionType: String? = null, val failed: Boolean? = null -) : Writeable { +) : ToXContentObject, Writeable { @Throws(IOException::class) constructor(sin: StreamInput) : this( @@ -32,6 +35,19 @@ data class ExplainFilter( failed = sin.readOptionalBoolean() ) + override fun toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder { + builder.startObject() + builder.startObject(FILTER_FIELD) + + if (policyID != null) builder.field(POLICY_ID_FIELD, policyID) + if (state != null) builder.field(STATE_FIELD, state) + if (actionType != null) builder.field(ACTION_FIELD, actionType) + if (failed != null) builder.field(FAILED_FIELD, failed) + + builder.endObject() + return builder.endObject() + } + @Throws(IOException::class) override fun writeTo(out: StreamOutput) { out.writeOptionalString(policyID) diff --git a/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/IndexStateManagementRestTestCase.kt b/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/IndexStateManagementRestTestCase.kt index 8f65fd46b..ba61a2769 100644 --- a/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/IndexStateManagementRestTestCase.kt +++ b/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/IndexStateManagementRestTestCase.kt @@ -38,12 +38,7 @@ import org.opensearch.indexmanagement.IndexManagementPlugin.Companion.INDEX_STAT import org.opensearch.indexmanagement.IndexManagementPlugin.Companion.ISM_BASE_URI import org.opensearch.indexmanagement.IndexManagementPlugin.Companion.POLICY_BASE_URI import org.opensearch.indexmanagement.IndexManagementRestTestCase -import org.opensearch.indexmanagement.indexstatemanagement.model.ChangePolicy -import org.opensearch.indexmanagement.indexstatemanagement.model.ISMTemplate -import org.opensearch.indexmanagement.indexstatemanagement.model.ManagedIndexConfig -import org.opensearch.indexmanagement.indexstatemanagement.model.Policy import org.opensearch.indexmanagement.indexstatemanagement.model.Policy.Companion.POLICY_TYPE -import org.opensearch.indexmanagement.indexstatemanagement.model.StateFilter import org.opensearch.indexmanagement.indexstatemanagement.resthandler.RestExplainAction import org.opensearch.indexmanagement.indexstatemanagement.settings.ManagedIndexSettings import org.opensearch.indexmanagement.indexstatemanagement.util.FAILED_INDICES @@ -71,6 +66,12 @@ import org.opensearch.jobscheduler.spi.schedule.IntervalSchedule import org.opensearch.rest.RestRequest import org.opensearch.search.SearchModule import org.opensearch.core.rest.RestStatus +import org.opensearch.indexmanagement.indexstatemanagement.model.ChangePolicy +import org.opensearch.indexmanagement.indexstatemanagement.model.ExplainFilter +import org.opensearch.indexmanagement.indexstatemanagement.model.ISMTemplate +import org.opensearch.indexmanagement.indexstatemanagement.model.ManagedIndexConfig +import org.opensearch.indexmanagement.indexstatemanagement.model.Policy +import org.opensearch.indexmanagement.indexstatemanagement.model.StateFilter import org.opensearch.indexmanagement.rollup.randomTermQuery import org.opensearch.test.OpenSearchTestCase import java.io.IOException @@ -473,6 +474,8 @@ abstract class IndexStateManagementRestTestCase : IndexManagementRestTestCase() protected fun ManagedIndexConfig.toHttpEntity(): HttpEntity = StringEntity(toJsonString(), ContentType.APPLICATION_JSON) + protected fun ExplainFilter.toHttpEntity(): HttpEntity = StringEntity(toJsonString(), ContentType.APPLICATION_JSON) + protected fun ChangePolicy.toHttpEntity(): HttpEntity { var string = "{\"${ChangePolicy.POLICY_ID_FIELD}\":\"$policyID\"," if (state != null) { diff --git a/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/TestHelpers.kt b/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/TestHelpers.kt index 3ce0dc007..d6fa0bed7 100644 --- a/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/TestHelpers.kt +++ b/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/TestHelpers.kt @@ -31,6 +31,7 @@ import org.opensearch.indexmanagement.indexstatemanagement.action.SnapshotAction import org.opensearch.indexmanagement.indexstatemanagement.model.ChangePolicy import org.opensearch.indexmanagement.indexstatemanagement.model.Conditions import org.opensearch.indexmanagement.indexstatemanagement.model.ErrorNotification +import org.opensearch.indexmanagement.indexstatemanagement.model.ExplainFilter import org.opensearch.indexmanagement.indexstatemanagement.model.ISMTemplate import org.opensearch.indexmanagement.indexstatemanagement.model.ManagedIndexConfig import org.opensearch.indexmanagement.indexstatemanagement.model.Policy @@ -305,6 +306,15 @@ fun randomByteSizeValue(): ByteSizeValue = * End - Conditions helper functions */ +fun randomExplainFilter( + policyID: String? = if (OpenSearchRestTestCase.randomBoolean()) OpenSearchRestTestCase.randomAlphaOfLength(10) else null, + state: String? = if (OpenSearchRestTestCase.randomBoolean()) OpenSearchRestTestCase.randomAlphaOfLength(10) else null, + actionType: String? = if (OpenSearchRestTestCase.randomBoolean()) OpenSearchRestTestCase.randomAlphaOfLength(10) else null, + failed: Boolean? = if (OpenSearchRestTestCase.randomBoolean()) OpenSearchRestTestCase.randomBoolean() else null +): ExplainFilter { + return ExplainFilter(policyID, state, actionType, failed) +} + fun randomChangePolicy( policyID: String = OpenSearchRestTestCase.randomAlphaOfLength(10), state: String? = if (OpenSearchRestTestCase.randomBoolean()) OpenSearchRestTestCase.randomAlphaOfLength(10) else null, @@ -469,6 +479,11 @@ fun AllocationAction.toJsonString(): String { return this.toXContent(builder, ToXContent.EMPTY_PARAMS).string() } +fun ExplainFilter.toJsonString(): String { + val builder = XContentFactory.jsonBuilder() + return this.toXContent(builder, ToXContent.EMPTY_PARAMS).string() +} + fun ChangePolicy.toJsonString(): String { val builder = XContentFactory.jsonBuilder() return this.toXContent(builder, ToXContent.EMPTY_PARAMS).string() diff --git a/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/model/ExplainFilterTests.kt b/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/model/ExplainFilterTests.kt new file mode 100644 index 000000000..36cac7ad8 --- /dev/null +++ b/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/model/ExplainFilterTests.kt @@ -0,0 +1,35 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.opensearch.indexmanagement.indexstatemanagement.model + +import org.opensearch.indexmanagement.spi.indexstatemanagement.model.ActionMetaData +import org.opensearch.indexmanagement.spi.indexstatemanagement.model.ManagedIndexMetaData +import org.opensearch.indexmanagement.spi.indexstatemanagement.model.PolicyRetryInfoMetaData +import org.opensearch.indexmanagement.spi.indexstatemanagement.model.StateMetaData +import org.opensearch.test.OpenSearchTestCase + +class ExplainFilterTests : OpenSearchTestCase() { + fun `test byMetadata`() { + val stateMetaData = StateMetaData("state", 100) + val actionMetaData = ActionMetaData("action", null, 0, false, 0, null, null) + val policyRetryInfoMetaData = PolicyRetryInfoMetaData(false, 1) + + val managedIndexMetaDataAllNull = ManagedIndexMetaData("test", "indexUuid", "policy_id", null, null, null, null, null, null, null, null, null, null, null) + val managedIndexMetaDataNonNull = ManagedIndexMetaData("test", "indexUuid", "policy_id", null, null, null, null, null, null, stateMetaData, actionMetaData, null, policyRetryInfoMetaData, null) + val managedIndexMetaDataSomeNull = ManagedIndexMetaData("test", "indexUuid", "policy_id", null, null, null, null, null, null, null, actionMetaData, null, null, null) + + val explainFilter = ExplainFilter(state = "state", actionType = "action", failed = false) + + var res = explainFilter.byMetaData(managedIndexMetaDataAllNull) + assertFalse(res) + + res = explainFilter.byMetaData(managedIndexMetaDataNonNull) + assertTrue(res) + + res = explainFilter.byMetaData(managedIndexMetaDataSomeNull) + assertFalse(res) + } +} diff --git a/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/model/XContentTests.kt b/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/model/XContentTests.kt index defc5976e..fda797fac 100644 --- a/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/model/XContentTests.kt +++ b/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/model/XContentTests.kt @@ -20,6 +20,7 @@ import org.opensearch.indexmanagement.indexstatemanagement.randomChannel import org.opensearch.indexmanagement.indexstatemanagement.randomCloseActionConfig import org.opensearch.indexmanagement.indexstatemanagement.randomDeleteActionConfig import org.opensearch.indexmanagement.indexstatemanagement.randomDestination +import org.opensearch.indexmanagement.indexstatemanagement.randomExplainFilter import org.opensearch.indexmanagement.indexstatemanagement.randomForceMergeActionConfig import org.opensearch.indexmanagement.indexstatemanagement.randomIndexPriorityActionConfig import org.opensearch.indexmanagement.indexstatemanagement.randomManagedIndexConfig @@ -258,6 +259,14 @@ class XContentTests : OpenSearchTestCase() { assertEquals("Round tripping ManagedIndexMetaData doesn't work", metadata, parsedMetaData) } + fun `test explain filter parsing`() { + val explainFilter = randomExplainFilter() + + val explainFilterString = explainFilter.toJsonString() + val parsedExplainFilter = ExplainFilter.parse(parser(explainFilterString)) + assertEquals("Round tripping ExplainFilter doesn't work", explainFilter, parsedExplainFilter) + } + fun `test change policy parsing`() { val changePolicy = randomChangePolicy() 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 76dc83eb5..5c91f9364 100644 --- a/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/resthandler/RestExplainActionIT.kt +++ b/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/resthandler/RestExplainActionIT.kt @@ -9,17 +9,29 @@ import org.opensearch.common.xcontent.XContentFactory import org.opensearch.indexmanagement.IndexManagementPlugin import org.opensearch.indexmanagement.indexstatemanagement.IndexStateManagementRestTestCase import org.opensearch.indexmanagement.indexstatemanagement.model.ChangePolicy +import org.opensearch.indexmanagement.makeRequest +import org.opensearch.indexmanagement.opensearchapi.toMap +import org.opensearch.indexmanagement.waitFor +import org.opensearch.rest.RestRequest +import org.opensearch.core.rest.RestStatus +import org.opensearch.indexmanagement.indexstatemanagement.action.AllocationAction +import org.opensearch.indexmanagement.indexstatemanagement.action.DeleteAction +import org.opensearch.indexmanagement.indexstatemanagement.action.OpenAction +import org.opensearch.indexmanagement.indexstatemanagement.action.ReadOnlyAction +import org.opensearch.indexmanagement.indexstatemanagement.model.ExplainFilter +import org.opensearch.indexmanagement.indexstatemanagement.model.Transition +import org.opensearch.indexmanagement.indexstatemanagement.randomPolicy +import org.opensearch.indexmanagement.indexstatemanagement.randomState import org.opensearch.indexmanagement.indexstatemanagement.util.SHOW_POLICY_QUERY_PARAM import org.opensearch.indexmanagement.indexstatemanagement.util.TOTAL_MANAGED_INDICES import org.opensearch.indexmanagement.indexstatemanagement.util.XCONTENT_WITHOUT_TYPE_AND_USER -import org.opensearch.indexmanagement.makeRequest -import org.opensearch.indexmanagement.opensearchapi.toMap +import org.opensearch.indexmanagement.spi.indexstatemanagement.Step +import org.opensearch.indexmanagement.spi.indexstatemanagement.model.ActionMetaData +import org.opensearch.indexmanagement.spi.indexstatemanagement.model.ActionRetry import org.opensearch.indexmanagement.spi.indexstatemanagement.model.ManagedIndexMetaData import org.opensearch.indexmanagement.spi.indexstatemanagement.model.PolicyRetryInfoMetaData import org.opensearch.indexmanagement.spi.indexstatemanagement.model.StateMetaData -import org.opensearch.indexmanagement.waitFor -import org.opensearch.rest.RestRequest -import org.opensearch.core.rest.RestStatus +import org.opensearch.indexmanagement.spi.indexstatemanagement.model.StepMetaData import java.time.Instant import java.util.Locale @@ -309,6 +321,8 @@ class RestExplainActionIT : IndexStateManagementRestTestCase() { waitFor { val expectedInfoString = mapOf("message" to "Fail to load policy: ${changePolicy.policyID}").toString() + + val explainMap = getExplainMap(indexName) assertPredicatesOnMetaData( listOf( indexName to listOf( @@ -324,7 +338,7 @@ class RestExplainActionIT : IndexStateManagementRestTestCase() { ManagedIndexMetaData.ENABLED to true::equals ) ), - getExplainMap(indexName) + explainMap ) } } @@ -353,6 +367,248 @@ class RestExplainActionIT : IndexStateManagementRestTestCase() { } } + fun `test explain filter`() { + val indexName1 = "${testIndexName}_filter1" + val indexName2 = "${testIndexName}_filter2" + + val stateWithReadOnlyAction = randomState(actions = listOf(ReadOnlyAction(index = 0))) + val policy1 = createPolicy(randomPolicy(states = listOf(stateWithReadOnlyAction))) + + val stateWithDeleteAction = randomState(actions = listOf(DeleteAction(index = 0))) + val updatedStateWithReadOnlyAction = stateWithReadOnlyAction.copy( + actions = listOf(stateWithReadOnlyAction.actions.first(), OpenAction(index = 1)), + transitions = listOf(Transition(stateWithDeleteAction.name, null)) + ) + val policy2 = createPolicy(randomPolicy(states = listOf(stateWithDeleteAction, updatedStateWithReadOnlyAction))) + + createIndex(indexName1, policy1.id) + createIndex(indexName2, policy2.id) + + val managedIndexConfig1 = getExistingManagedIndexConfig(indexName1) + val managedIndexConfig2 = getExistingManagedIndexConfig(indexName2) + + // init policy on job + updateManagedIndexConfigStartTime(managedIndexConfig1) + + // verify we have policy + waitFor { assertEquals(policy1.id, getExplainManagedIndexMetaData(indexName1).policyID) } + + // do the same for index2 + updateManagedIndexConfigStartTime(managedIndexConfig2) + waitFor { assertEquals(policy2.id, getExplainManagedIndexMetaData(indexName2).policyID) } + + // speed up to execute set read only step + updateManagedIndexConfigStartTime(managedIndexConfig1) + + val index1Predicates = indexName1 to listOf( + explainResponseOpendistroPolicyIdSetting to policy1.id::equals, + explainResponseOpenSearchPolicyIdSetting to policy1.id::equals, + ManagedIndexMetaData.INDEX to managedIndexConfig1.index::equals, + ManagedIndexMetaData.INDEX_UUID to managedIndexConfig1.indexUuid::equals, + ManagedIndexMetaData.POLICY_ID to managedIndexConfig1.policyID::equals, + ManagedIndexMetaData.POLICY_SEQ_NO to policy1.seqNo.toInt()::equals, + ManagedIndexMetaData.POLICY_PRIMARY_TERM to policy1.primaryTerm.toInt()::equals, + ManagedIndexMetaData.INDEX_CREATION_DATE to fun(indexCreationDate: Any?): Boolean = (indexCreationDate as Long) > 1L, + StateMetaData.STATE to fun(stateMetaDataMap: Any?): Boolean = assertStateEquals( + StateMetaData(policy1.defaultState, Instant.now().toEpochMilli()), + stateMetaDataMap + ), + ActionMetaData.ACTION to fun(actionMetaDataMap: Any?): Boolean = assertActionEquals( + ActionMetaData( + name = "read_only", startTime = Instant.now().toEpochMilli(), failed = false, + index = 0, consumedRetries = 0, lastRetryTime = null, actionProperties = null + ), + actionMetaDataMap + ), + PolicyRetryInfoMetaData.RETRY_INFO to fun(retryInfoMetaDataMap: Any?): Boolean = + assertRetryInfoEquals(PolicyRetryInfoMetaData(false, 0), retryInfoMetaDataMap), + ManagedIndexMetaData.ENABLED to true::equals + ) + + val index2Predicates = indexName2 to listOf( + explainResponseOpendistroPolicyIdSetting to policy2.id::equals, + explainResponseOpenSearchPolicyIdSetting to policy2.id::equals, + ManagedIndexMetaData.INDEX to managedIndexConfig2.index::equals, + ManagedIndexMetaData.INDEX_UUID to managedIndexConfig2.indexUuid::equals, + ManagedIndexMetaData.POLICY_ID to managedIndexConfig2.policyID::equals, + ManagedIndexMetaData.POLICY_SEQ_NO to policy2.seqNo.toInt()::equals, + ManagedIndexMetaData.POLICY_PRIMARY_TERM to policy2.primaryTerm.toInt()::equals, + ManagedIndexMetaData.INDEX_CREATION_DATE to fun(indexCreationDate: Any?): Boolean = (indexCreationDate as Long) > 1L, + StateMetaData.STATE to fun(stateMetaDataMap: Any?): Boolean = assertStateEquals( + StateMetaData(policy2.defaultState, Instant.now().toEpochMilli()), + stateMetaDataMap + ), + ActionMetaData.ACTION to fun(actionMetaDataMap: Any?): Boolean = assertActionEquals( + ActionMetaData( + name = "delete", startTime = Instant.now().toEpochMilli(), failed = false, + index = 0, consumedRetries = 0, lastRetryTime = null, actionProperties = null + ), + actionMetaDataMap + ), + PolicyRetryInfoMetaData.RETRY_INFO to fun(retryInfoMetaDataMap: Any?): Boolean = + assertRetryInfoEquals(PolicyRetryInfoMetaData(false, 0), retryInfoMetaDataMap), + ManagedIndexMetaData.ENABLED to true::equals + ) + + // check metadata for result from filtering on the first policy and its state + waitFor { + val filterPolicy = ExplainFilter( + policyID = policy1.id, + state = policy1.states[0].name, + failed = false + ) + + val resp = client().makeRequest( + RestRequest.Method.POST.toString(), + RestExplainAction.EXPLAIN_BASE_URI, emptyMap(), filterPolicy.toHttpEntity() + ) + + assertEquals("Unexpected RestStatus", RestStatus.OK, resp.restStatus()) + + assertPredicatesOnMetaData( + listOf(index1Predicates), + resp.asMap(), false + ) + } + + // check metadata on filtering for the delete action + + // speed up to execute set read only step + updateManagedIndexConfigStartTime(managedIndexConfig1) + updateManagedIndexConfigStartTime(managedIndexConfig2) + + waitFor { + val filterPolicy = ExplainFilter( + actionType = "delete", + failed = false + ) + + val resp = client().makeRequest( + RestRequest.Method.POST.toString(), + RestExplainAction.EXPLAIN_BASE_URI, emptyMap(), filterPolicy.toHttpEntity() + ) + + assertEquals("Unexpected RestStatus", RestStatus.OK, resp.restStatus()) + + assertPredicatesOnMetaData( + listOf( + index2Predicates + ), + resp.asMap(), false + ) + } + + removePolicyFromIndex(indexName1) + removePolicyFromIndex(indexName2) + } + + fun `test explain filter failed index`() { + val indexName1 = "${testIndexName}_failed" + val indexName2 = "${testIndexName}_success" + + // for failed index + val config = AllocationAction(require = mapOf("..//" to "value"), exclude = emptyMap(), include = emptyMap(), index = 0) + config.configRetry = ActionRetry(0) + val states = listOf( + randomState().copy( + transitions = listOf(), + actions = listOf(config) + ) + ) + val invalidPolicy = randomPolicy().copy( + states = states, + defaultState = states[0].name + ) + + // for successful index + val stateWithReadOnlyAction = randomState(actions = listOf(ReadOnlyAction(index = 0))) + val validPolicy = createPolicy(randomPolicy(states = listOf(stateWithReadOnlyAction))) + + createPolicy(invalidPolicy, invalidPolicy.id) + createIndex(indexName1, invalidPolicy.id) + createIndex(indexName2, validPolicy.id) + + val managedIndexConfig1 = getExistingManagedIndexConfig(indexName1) + val managedIndexConfig2 = getExistingManagedIndexConfig(indexName2) + + // change the start time so the job will trigger in 2 seconds. + updateManagedIndexConfigStartTime(managedIndexConfig1) + waitFor { assertEquals(invalidPolicy.id, getExplainManagedIndexMetaData(indexName1).policyID) } + + updateManagedIndexConfigStartTime(managedIndexConfig2) + waitFor { assertEquals(validPolicy.id, getExplainManagedIndexMetaData(indexName2).policyID) } + + // Change the start time so that we attempt allocation that is intended to fail + updateManagedIndexConfigStartTime(managedIndexConfig1) + waitFor { + val explainFilter = ExplainFilter( + failed = true + ) + + val resp = client().makeRequest( + RestRequest.Method.POST.toString(), + RestExplainAction.EXPLAIN_BASE_URI, emptyMap(), explainFilter.toHttpEntity() + ) + + assertEquals("Unexpected RestStatus", RestStatus.OK, resp.restStatus()) + + assertPredicatesOnMetaData( + listOf( + indexName1 to listOf( + explainResponseOpendistroPolicyIdSetting to invalidPolicy.id::equals, + explainResponseOpenSearchPolicyIdSetting to invalidPolicy.id::equals, + ManagedIndexMetaData.INDEX to managedIndexConfig1.index::equals, + ManagedIndexMetaData.INDEX_UUID to managedIndexConfig1.indexUuid::equals, + ManagedIndexMetaData.POLICY_ID to managedIndexConfig1.policyID::equals, + ManagedIndexMetaData.INDEX_CREATION_DATE to fun(indexCreationDate: Any?): Boolean = (indexCreationDate as Long) > 1L, + StepMetaData.STEP to fun(stepMetaDataMap: Any?): Boolean = assertStepEquals( + StepMetaData("attempt_allocation", Instant.now().toEpochMilli(), Step.StepStatus.FAILED), + stepMetaDataMap + ), + ManagedIndexMetaData.ENABLED to true::equals + ) + ), + resp.asMap(), false + ) + } + + updateManagedIndexConfigStartTime(managedIndexConfig2) + waitFor { + val explainFilter = ExplainFilter( + failed = false + ) + + val resp = client().makeRequest( + RestRequest.Method.POST.toString(), + RestExplainAction.EXPLAIN_BASE_URI, emptyMap(), explainFilter.toHttpEntity() + ) + + assertEquals("Unexpected RestStatus", RestStatus.OK, resp.restStatus()) + + assertPredicatesOnMetaData( + listOf( + indexName2 to listOf( + explainResponseOpendistroPolicyIdSetting to validPolicy.id::equals, + explainResponseOpenSearchPolicyIdSetting to validPolicy.id::equals, + ManagedIndexMetaData.INDEX to managedIndexConfig2.index::equals, + ManagedIndexMetaData.INDEX_UUID to managedIndexConfig2.indexUuid::equals, + ManagedIndexMetaData.POLICY_ID to managedIndexConfig2.policyID::equals, + ManagedIndexMetaData.INDEX_CREATION_DATE to fun(indexCreationDate: Any?): Boolean = (indexCreationDate as Long) > 1L, + StepMetaData.STEP to fun(stepMetaDataMap: Any?): Boolean = assertStepEquals( + StepMetaData("set_read_only", Instant.now().toEpochMilli(), Step.StepStatus.STARTING), + stepMetaDataMap + ), + ManagedIndexMetaData.ENABLED to true::equals + ) + ), + resp.asMap(), false + ) + } + + removePolicyFromIndex(indexName1) + removePolicyFromIndex(indexName2) + } + @Suppress("UNCHECKED_CAST") // Do assertion of the response map here so we don't have many places to do suppression. private fun assertResponseMap(expected: Map, actual: Map) { assertEquals("Explain Map does not match", expected.size, actual.size) diff --git a/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/resthandler/RestRetryFailedManagedIndexActionIT.kt b/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/resthandler/RestRetryFailedManagedIndexActionIT.kt index 431115c1a..4425e5ffd 100644 --- a/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/resthandler/RestRetryFailedManagedIndexActionIT.kt +++ b/src/test/kotlin/org/opensearch/indexmanagement/indexstatemanagement/resthandler/RestRetryFailedManagedIndexActionIT.kt @@ -272,20 +272,21 @@ class RestRetryFailedManagedIndexActionIT : IndexStateManagementRestTestCase() { // speed up to execute set read only force merge step updateManagedIndexConfigStartTime(managedIndexConfig) waitFor { + val explainMap = getExplainMap(indexName) + assertPredicatesOnMetaData( listOf( indexName to listOf( - ActionMetaData.ACTION to fun(actionMetaDataMap: Any?): Boolean = - assertActionEquals( - ActionMetaData( - name = "force_merge", startTime = Instant.now().toEpochMilli(), failed = false, - index = 0, consumedRetries = 0, lastRetryTime = null, actionProperties = null - ), - actionMetaDataMap - ) + ActionMetaData.ACTION to fun(actionMetaDataMap: Any?): Boolean = assertActionEquals( + ActionMetaData( + name = "force_merge", startTime = Instant.now().toEpochMilli(), failed = false, + index = 0, consumedRetries = 0, lastRetryTime = null, actionProperties = null + ), + actionMetaDataMap + ) ) ), - getExplainMap(indexName), false + explainMap, false ) }