diff --git a/spi/src/main/kotlin/org.opensearch.indexmanagement.spi/indexstatemanagement/model/StateMetaData.kt b/spi/src/main/kotlin/org.opensearch.indexmanagement.spi/indexstatemanagement/model/StateMetaData.kt index 7c6174106..21a94d418 100644 --- a/spi/src/main/kotlin/org.opensearch.indexmanagement.spi/indexstatemanagement/model/StateMetaData.kt +++ b/spi/src/main/kotlin/org.opensearch.indexmanagement.spi/indexstatemanagement/model/StateMetaData.kt @@ -22,7 +22,8 @@ import org.opensearch.indexmanagement.spi.indexstatemanagement.model.ManagedInde import java.io.ByteArrayInputStream import java.nio.charset.StandardCharsets -data class StateMetaData( +data class +StateMetaData( val name: String, val startTime: Long ) : Writeable, ToXContentFragment { 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 ba562948f..83ab63a58 100644 --- a/src/main/kotlin/org/opensearch/indexmanagement/indexstatemanagement/model/ExplainFilter.kt +++ b/src/main/kotlin/org/opensearch/indexmanagement/indexstatemanagement/model/ExplainFilter.kt @@ -5,58 +5,96 @@ package org.opensearch.indexmanagement.indexstatemanagement.model +import org.apache.logging.log4j.LogManager 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.XContentParser import org.opensearch.core.xcontent.XContentParser.Token import org.opensearch.core.xcontent.XContentParserUtils.ensureExpectedToken +import org.opensearch.index.query.BoolQueryBuilder +import org.opensearch.index.query.Operator +import org.opensearch.index.query.QueryBuilders +import org.opensearch.indexmanagement.indexstatemanagement.util.MANAGED_INDEX_POLICY_ID_FIELD +import org.opensearch.indexmanagement.spi.indexstatemanagement.model.ManagedIndexMetaData import java.io.IOException +private val log = LogManager.getLogger(ExplainFilter::class.java) + data class ExplainFilter( - val filterPolicyID: String?, - val filterState: String?, - val filterAction: String? + val policyID: String?, + val state: String?, + val actionType: String?, + val failed: Boolean? ) : Writeable { constructor() : this( - filterPolicyID = null, - filterState = null, - filterAction = null + policyID = null, + state = null, + actionType = null, + failed = null ) @Throws(IOException::class) constructor(sin: StreamInput) : this( - filterPolicyID = sin.readOptionalString(), - filterState = sin.readOptionalString(), - filterAction = sin.readOptionalString() + policyID = sin.readString(), + state = sin.readString(), + actionType = sin.readString(), + failed = sin.readBoolean() ) @Throws(IOException::class) override fun writeTo(out: StreamOutput) { - out.writeOptionalString(filterPolicyID) - out.writeOptionalString(filterState) - out.writeOptionalString(filterAction) + out.writeOptionalString(policyID) + out.writeOptionalString(state) + out.writeOptionalString(actionType) + out.writeOptionalBoolean(failed) + } + + fun convertToBoolQueryBuilder(): BoolQueryBuilder { + val boolQuery = QueryBuilders.boolQuery() + + if (policyID != null) { + boolQuery.must( + QueryBuilders + .queryStringQuery(policyID) + .field(MANAGED_INDEX_POLICY_ID_FIELD) + .defaultOperator(Operator.AND) + ) + } + + return boolQuery } - fun isValid(managedIndexConfig: ManagedIndexConfig): Boolean { - var valid = true + fun validMetaData(metaData: ManagedIndexMetaData): Boolean { + log.info("----FILTER---- $metaData") // : ${metaData.stateMetaData!!.name} ${metaData.actionMetaData!!.name} ${metaData.actionMetaData!!.failed}") - if (filterPolicyID != null && filterPolicyID != managedIndexConfig.policyID) { - valid = false + val stateMetaData = metaData.stateMetaData + if (stateMetaData != null) { + log.info("STATE META DATA: ${stateMetaData.name} : $state") } - val policy = managedIndexConfig.policy + if (state != null && (stateMetaData == null || stateMetaData.name != state)) { + log.info("filter error on state") + return false + } - if (filterState != null && policy != null && !policy.states.any { it.name == filterState }) { - valid = false + val actionMetaData = metaData.actionMetaData + if (actionMetaData != null) { + log.info("ACTION META DATA: ${actionMetaData.name} : $actionType, ${actionMetaData.failed} : $failed") } - if (filterAction != null && policy != null && !policy.states.any { state -> state.actions.any { it.type == filterAction } }) { - valid = false + if (actionType != null && (actionMetaData == null || actionMetaData.name != actionType)) { + log.info("filter error on action") + return false } - return valid + if (failed != null && (actionMetaData == null || actionMetaData.failed != failed)) { + log.info("filter error on failed") + return false + } + + return true } companion object { @@ -64,13 +102,15 @@ data class ExplainFilter( const val POLICY_ID_FIELD = "policy_id" const val STATE_FIELD = "state" const val ACTION_FIELD = "action_type" + const val FAILURE_FIELD = "failure" @JvmStatic @Throws(IOException::class) fun parse(xcp: XContentParser): ExplainFilter { var policyID: String? = null var state: String? = null - var action: String? = null + var actionType: String? = null + var failed: Boolean? = null ensureExpectedToken(Token.START_OBJECT, xcp.currentToken(), xcp) while (xcp.nextToken() != Token.END_OBJECT) { @@ -87,14 +127,17 @@ data class ExplainFilter( when (filter) { POLICY_ID_FIELD -> policyID = xcp.text() STATE_FIELD -> state = xcp.text() - ACTION_FIELD -> action = xcp.text() + ACTION_FIELD -> actionType = xcp.text() + FAILURE_FIELD -> failed = xcp.booleanValue() } } } } } - return ExplainFilter(policyID, state, action) + log.info("[PARSE] pid: $policyID, s: $state, a: $actionType, f: $failed") + + return ExplainFilter(policyID, state, actionType, failed) } } } 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 d8f140b7b..f12b8bc91 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 @@ -155,11 +155,24 @@ class TransportExplainAction @Inject constructor( private fun getSearchMetadataRequest(params: SearchParams, indexUUIDs: List, searchSize: Int): SearchRequest { val sortBuilder = params.getSortBuilder() - val queryBuilder = QueryBuilders.boolQuery() + // change query builder based off of the given json body +// val queryBuilder = QueryBuilders.boolQuery() +// .must( +// QueryBuilders +// .queryStringQuery(params.queryString) +// .defaultField(MANAGED_INDEX_NAME_KEYWORD_FIELD) +// .defaultOperator(Operator.AND) +// ).filter(QueryBuilders.termsQuery(MANAGED_INDEX_INDEX_UUID_FIELD, indexUUIDs)) + + log.info("QUERY STRING: ${params.queryString} :: $params") + + // can I string multiple bool queries together + + val queryBuilder = request.explainFilter.convertToBoolQueryBuilder() .must( QueryBuilders .queryStringQuery(params.queryString) - .defaultField(MANAGED_INDEX_NAME_KEYWORD_FIELD) + .field(MANAGED_INDEX_NAME_KEYWORD_FIELD) .defaultOperator(Operator.AND) ).filter(QueryBuilders.termsQuery(MANAGED_INDEX_INDEX_UUID_FIELD, indexUUIDs)) @@ -190,21 +203,19 @@ class TransportExplainAction @Inject constructor( } parseSearchHits(response.hits.hits).forEach { managedIndex -> - if (request.explainFilter.isValid(managedIndex)) { - managedIndices.add(managedIndex.index) - enabledState[managedIndex.index] = managedIndex.enabled - managedIndicesMetaDataMap[managedIndex.index] = mapOf( - "index" to managedIndex.index, - "index_uuid" to managedIndex.indexUuid, - "policy_id" to managedIndex.policyID, - "enabled" to managedIndex.enabled.toString() - ) - if (showPolicy) { - managedIndex.policy?.let { appliedPolicies[managedIndex.index] = it } - } - if (validateAction) { - managedIndex.policy?.let { policiesforValidation[managedIndex.index] = it } - } + managedIndices.add(managedIndex.index) + enabledState[managedIndex.index] = managedIndex.enabled + managedIndicesMetaDataMap[managedIndex.index] = mapOf( + "index" to managedIndex.index, + "index_uuid" to managedIndex.indexUuid, + "policy_id" to managedIndex.policyID, + "enabled" to managedIndex.enabled.toString() + ) + if (showPolicy) { + managedIndex.policy?.let { appliedPolicies[managedIndex.index] = it } + } + if (validateAction) { + managedIndex.policy?.let { policiesforValidation[managedIndex.index] = it } } } @@ -293,8 +304,28 @@ class TransportExplainAction @Inject constructor( mgetMetadataReq, object : ActionListener { override fun onResponse(response: MultiGetResponse) { - val metadataMap: Map = + var metadataMap: Map = response.responses.associate { it.id to getMetadata(it.response)?.toMap() } + + log.info("BEFORE METADATA MAP: $metadataMap") + + metadataMap = metadataMap.filter { (_, value) -> + var ok = false + + if (value != null) { + val metaData = ManagedIndexMetaData.fromMap(value) + ok = request.explainFilter.validMetaData(metaData) + if (!ok) { + indexNamesToUUIDs.remove(metaData.index) + } + } + + ok + } + + log.info("FILTERED METADATA MAP: $metadataMap") + log.info("FILTED INDEX NAMES TO UUID: $indexNamesToUUIDs") + buildResponse(indexNamesToUUIDs, metadataMap, clusterStateIndexMetadatas, threadContext) } diff --git a/src/main/kotlin/org/opensearch/indexmanagement/indexstatemanagement/util/RestHandlerUtils.kt b/src/main/kotlin/org/opensearch/indexmanagement/indexstatemanagement/util/RestHandlerUtils.kt index 4442ccc82..6c5a45694 100644 --- a/src/main/kotlin/org/opensearch/indexmanagement/indexstatemanagement/util/RestHandlerUtils.kt +++ b/src/main/kotlin/org/opensearch/indexmanagement/indexstatemanagement/util/RestHandlerUtils.kt @@ -39,6 +39,7 @@ const val MANAGED_INDEX_FIELD = "managed_index" const val MANAGED_INDEX_NAME_KEYWORD_FIELD = "$MANAGED_INDEX_FIELD.name.keyword" const val MANAGED_INDEX_INDEX_FIELD = "$MANAGED_INDEX_FIELD.index" const val MANAGED_INDEX_INDEX_UUID_FIELD = "$MANAGED_INDEX_FIELD.index_uuid" +const val MANAGED_INDEX_POLICY_ID_FIELD = "$MANAGED_INDEX_FIELD.policy_id" const val DEFAULT_JOB_SORT_FIELD = MANAGED_INDEX_INDEX_FIELD const val DEFAULT_POLICY_SORT_FIELD = "policy.policy_id.keyword"