Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ class DocLevelMonitorQueries(private val client: Client, private val clusterServ
// This is all information we need to update this node
val (oldName, newName, props) = processLeafFn(it.key, fullPath, it.value as MutableMap<String, Any>)
newNodes.add(Triple(oldName, newName, props))
} else {
} else if (nodeProps.containsKey(PROPERTIES) && nodeProps[PROPERTIES] != null) {
// Internal(non-leaf) node - visit children
traverseMappingsAndUpdate(nodeProps[PROPERTIES] as MutableMap<String, Any>, fullPath, processLeafFn, flattenPaths)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

package org.opensearch.alerting.util

import org.mockito.Mockito.mock
import org.opensearch.alerting.AlertService
import org.opensearch.alerting.MonitorRunnerService
import org.opensearch.alerting.model.AlertContext
import org.opensearch.alerting.randomAction
import org.opensearch.alerting.randomBucketLevelTrigger
Expand All @@ -14,8 +17,10 @@ import org.opensearch.alerting.randomQueryLevelTrigger
import org.opensearch.alerting.randomTemplateScript
import org.opensearch.alerting.script.BucketLevelTriggerExecutionContext
import org.opensearch.alerting.script.DocumentLevelTriggerExecutionContext
import org.opensearch.client.Client
import org.opensearch.cluster.service.ClusterService
import org.opensearch.common.unit.TimeValue
import org.opensearch.test.OpenSearchTestCase

class AlertingUtilsTests : OpenSearchTestCase() {
fun `test parseSampleDocTags only returns expected tags`() {
val expectedDocSourceTags = (0..3).map { "field$it" }
Expand Down Expand Up @@ -176,4 +181,79 @@ class AlertingUtilsTests : OpenSearchTestCase() {

triggers.forEach { trigger -> assertFalse(printsSampleDocData(trigger)) }
}

fun `test getCancelAfterTimeInterval returns -1 when setting is default`() {
val original = MonitorRunnerService.monitorCtx.cancelAfterTimeInterval
try {
MonitorRunnerService.monitorCtx.cancelAfterTimeInterval = TimeValue.timeValueMinutes(-1)
assertEquals(-1L, getCancelAfterTimeInterval())
} finally {
MonitorRunnerService.monitorCtx.cancelAfterTimeInterval = original
}
}

fun `test getCancelAfterTimeInterval returns at least ALERTS_SEARCH_TIMEOUT`() {
val original = MonitorRunnerService.monitorCtx.cancelAfterTimeInterval
try {
// Setting lower than ALERTS_SEARCH_TIMEOUT (5 min) should return 5 min
MonitorRunnerService.monitorCtx.cancelAfterTimeInterval = TimeValue.timeValueMinutes(1)
assertEquals(AlertService.ALERTS_SEARCH_TIMEOUT.minutes, getCancelAfterTimeInterval())
} finally {
MonitorRunnerService.monitorCtx.cancelAfterTimeInterval = original
}
}

fun `test getCancelAfterTimeInterval returns setting when higher than ALERTS_SEARCH_TIMEOUT`() {
val original = MonitorRunnerService.monitorCtx.cancelAfterTimeInterval
try {
MonitorRunnerService.monitorCtx.cancelAfterTimeInterval = TimeValue.timeValueMinutes(10)
assertEquals(10L, getCancelAfterTimeInterval())
} finally {
MonitorRunnerService.monitorCtx.cancelAfterTimeInterval = original
}
}

fun `test traverseMappingsAndUpdate with nested field type without properties succeeds`() {
// Verifies fix for https://github.com/opensearch-project/security-analytics/issues/1472
val docLevelMonitorQueries = DocLevelMonitorQueries(mock(Client::class.java), mock(ClusterService::class.java))
val mappings = mutableMapOf<String, Any>(
"message" to mutableMapOf<String, Any>("type" to "text"),
"http_request_headers" to mutableMapOf<String, Any>("type" to "nested")
)
val flattenPaths = mutableMapOf<String, MutableMap<String, Any>>()
val leafProcessor =
fun(fieldName: String, _: String, props: MutableMap<String, Any>):
Triple<String, String, MutableMap<String, Any>> {
return Triple(fieldName, fieldName, props)
}

docLevelMonitorQueries.traverseMappingsAndUpdate(mappings, "", leafProcessor, flattenPaths)

assertTrue("Expected 'message' in flatten paths", flattenPaths.containsKey("message"))
assertFalse("Expected nested field to be skipped", flattenPaths.containsKey("http_request_headers"))
}

fun `test traverseMappingsAndUpdate with nested field type with properties works`() {
val docLevelMonitorQueries = DocLevelMonitorQueries(mock(Client::class.java), mock(ClusterService::class.java))
val mappings = mutableMapOf<String, Any>(
"message" to mutableMapOf<String, Any>("type" to "text"),
"dll" to mutableMapOf<String, Any>(
"type" to "nested",
"properties" to mutableMapOf<String, Any>(
"name" to mutableMapOf<String, Any>("type" to "keyword")
)
)
)
val flattenPaths = mutableMapOf<String, MutableMap<String, Any>>()
val leafProcessor =
fun(fieldName: String, _: String, props: MutableMap<String, Any>):
Triple<String, String, MutableMap<String, Any>> {
return Triple(fieldName, fieldName, props)
}

docLevelMonitorQueries.traverseMappingsAndUpdate(mappings, "", leafProcessor, flattenPaths)

assertTrue("Expected 'message' in flatten paths", flattenPaths.containsKey("message"))
assertTrue("Expected 'dll.name' in flatten paths", flattenPaths.containsKey("dll.name"))
}
}
Loading