@@ -8,6 +8,7 @@ package org.opensearch.alerting
8
8
import org.junit.Assert
9
9
import org.opensearch.action.admin.cluster.state.ClusterStateRequest
10
10
import org.opensearch.action.admin.indices.create.CreateIndexRequest
11
+ import org.opensearch.action.admin.indices.mapping.put.PutMappingRequest
11
12
import org.opensearch.action.admin.indices.refresh.RefreshRequest
12
13
import org.opensearch.action.search.SearchRequest
13
14
import org.opensearch.action.support.WriteRequest
@@ -33,6 +34,7 @@ import org.opensearch.test.OpenSearchTestCase
33
34
import java.time.ZonedDateTime
34
35
import java.time.format.DateTimeFormatter
35
36
import java.time.temporal.ChronoUnit.MILLIS
37
+ import java.util.Map
36
38
import java.util.concurrent.TimeUnit
37
39
import java.util.stream.Collectors
38
40
@@ -128,25 +130,45 @@ class MonitorDataSourcesIT : AlertingSingleNodeTestCase() {
128
130
}
129
131
130
132
fun `test execute monitor with custom query index` () {
131
- val docQuery = DocLevelQuery (query = " test_field:\" us-west-2\" " , name = " 3" )
132
- val docLevelInput = DocLevelMonitorInput (" description" , listOf (index), listOf (docQuery))
133
+ val docQuery1 = DocLevelQuery (query = " source.ip.v6.v1:12345" , name = " 3" )
134
+ val docQuery2 = DocLevelQuery (query = " source.ip.v6.v2:16645" , name = " 4" )
135
+ val docQuery3 = DocLevelQuery (query = " source.ip.v4.v0:120" , name = " 5" )
136
+ val docQuery4 = DocLevelQuery (query = " alias.some.fff:\" us-west-2\" " , name = " 6" )
137
+ val docQuery5 = DocLevelQuery (query = " message:\" This is an error from IAD region\" " , name = " 7" )
138
+ val docLevelInput = DocLevelMonitorInput (
139
+ " description" , listOf (index), listOf (docQuery1, docQuery2, docQuery3, docQuery4, docQuery5)
140
+ )
133
141
val trigger = randomDocumentLevelTrigger(condition = ALWAYS_RUN )
142
+ val customFindingsIndex = " custom_findings_index"
143
+ val customFindingsIndexPattern = " custom_findings_index-1"
134
144
val customQueryIndex = " custom_alerts_index"
135
145
var monitor = randomDocumentLevelMonitor(
136
146
inputs = listOf (docLevelInput),
137
147
triggers = listOf (trigger),
138
- dataSources = DataSources (queryIndex = customQueryIndex)
148
+ dataSources = DataSources (
149
+ queryIndex = customQueryIndex,
150
+ findingsIndex = customFindingsIndex,
151
+ findingsIndexPattern = customFindingsIndexPattern
152
+ )
139
153
)
140
154
val monitorResponse = createMonitor(monitor)
141
155
val testTime = DateTimeFormatter .ISO_OFFSET_DATE_TIME .format(ZonedDateTime .now().truncatedTo(MILLIS ))
156
+ // Trying to test here few different "nesting" situations and "wierd" characters
142
157
val testDoc = """ {
143
158
"message" : "This is an error from IAD region",
159
+ "source.ip.v6.v1" : 12345,
160
+ "source.ip.v6.v2" : 16645,
161
+ "source.ip.v4.v0" : 120,
162
+ "test_bad_char" : "\u0000",
144
163
"test_strict_date_time" : "$testTime ",
145
- "test_field" : "us-west-2"
164
+ "test_field.some_other_field " : "us-west-2"
146
165
}"""
166
+ indexDoc(index, " 1" , testDoc)
167
+ client().admin().indices().putMapping(
168
+ PutMappingRequest (index).source(" alias.some.fff" , " type=alias,path=test_field.some_other_field" )
169
+ )
147
170
assertFalse(monitorResponse?.id.isNullOrEmpty())
148
171
monitor = monitorResponse!! .monitor
149
- indexDoc(index, " 1" , testDoc)
150
172
val id = monitorResponse.id
151
173
val executeMonitorResponse = executeMonitor(monitor, id, false )
152
174
Assert .assertEquals(executeMonitorResponse!! .monitorRunResult.monitorName, monitor.name)
@@ -158,11 +180,85 @@ class MonitorDataSourcesIT : AlertingSingleNodeTestCase() {
158
180
.get()
159
181
Assert .assertTrue(getAlertsResponse != null )
160
182
Assert .assertTrue(getAlertsResponse.alerts.size == 1 )
161
- getAlertsResponse = client()
162
- .execute(AlertingActions .GET_ALERTS_ACTION_TYPE , GetAlertsRequest (table, " ALL" , " ALL" , id, null ))
183
+ val findings = searchFindings(id, customFindingsIndex)
184
+ assertEquals(" Findings saved for test monitor" , 1 , findings.size)
185
+ assertTrue(" Findings saved for test monitor" , findings[0 ].relatedDocIds.contains(" 1" ))
186
+ assertEquals(" Didn't match all 5 queries" , 5 , findings[0 ].docLevelQueries.size)
187
+ }
188
+
189
+ fun `test execute monitor with custom query index and nested mappings` () {
190
+ val docQuery1 = DocLevelQuery (query = " message:\" msg 1 2 3 4\" " , name = " 3" )
191
+ val docLevelInput = DocLevelMonitorInput (" description" , listOf (index), listOf (docQuery1))
192
+ val trigger = randomDocumentLevelTrigger(condition = ALWAYS_RUN )
193
+ val customFindingsIndex = " custom_findings_index"
194
+ val customFindingsIndexPattern = " custom_findings_index-1"
195
+ val customQueryIndex = " custom_alerts_index"
196
+ var monitor = randomDocumentLevelMonitor(
197
+ inputs = listOf (docLevelInput),
198
+ triggers = listOf (trigger),
199
+ dataSources = DataSources (
200
+ queryIndex = customQueryIndex,
201
+ findingsIndex = customFindingsIndex,
202
+ findingsIndexPattern = customFindingsIndexPattern
203
+ )
204
+ )
205
+ val monitorResponse = createMonitor(monitor)
206
+
207
+ // We are verifying here that index with nested mappings and nested aliases
208
+ // won't break query matching
209
+
210
+ // Create index mappings
211
+ val m: MutableMap <String , Any > = HashMap ()
212
+ val m1: MutableMap <String , Any > = HashMap ()
213
+ m1[" title" ] = Map .of(" type" , " text" )
214
+ m1[" category" ] = Map .of(" type" , " keyword" )
215
+ m[" rule" ] = Map .of(" type" , " nested" , " properties" , m1)
216
+ val properties = Map .of<String , Any >(" properties" , m)
217
+
218
+ client().admin().indices().putMapping(
219
+ PutMappingRequest (
220
+ index
221
+ ).source(properties)
222
+ ).get()
223
+
224
+ // Put alias for nested fields
225
+ val mm: MutableMap <String , Any > = HashMap ()
226
+ val mm1: MutableMap <String , Any > = HashMap ()
227
+ mm1[" title_alias" ] = Map .of(" type" , " alias" , " path" , " rule.title" )
228
+ mm[" rule" ] = Map .of(" type" , " nested" , " properties" , mm1)
229
+ val properties1 = Map .of<String , Any >(" properties" , mm)
230
+ client().admin().indices().putMapping(
231
+ PutMappingRequest (
232
+ index
233
+ ).source(properties1)
234
+ ).get()
235
+
236
+ val testDoc = """ {
237
+ "rule": {"title": "some_title"},
238
+ "message": "msg 1 2 3 4"
239
+ }"""
240
+ indexDoc(index, " 2" , testDoc)
241
+
242
+ client().admin().indices().putMapping(
243
+ PutMappingRequest (index).source(" alias.some.fff" , " type=alias,path=test_field.some_other_field" )
244
+ )
245
+ assertFalse(monitorResponse?.id.isNullOrEmpty())
246
+ monitor = monitorResponse!! .monitor
247
+ val id = monitorResponse.id
248
+ val executeMonitorResponse = executeMonitor(monitor, id, false )
249
+ Assert .assertEquals(executeMonitorResponse!! .monitorRunResult.monitorName, monitor.name)
250
+ Assert .assertEquals(executeMonitorResponse.monitorRunResult.triggerResults.size, 1 )
251
+ searchAlerts(id)
252
+ val table = Table (" asc" , " id" , null , 1 , 0 , " " )
253
+ var getAlertsResponse = client()
254
+ .execute(AlertingActions .GET_ALERTS_ACTION_TYPE , GetAlertsRequest (table, " ALL" , " ALL" , null , null ))
163
255
.get()
164
256
Assert .assertTrue(getAlertsResponse != null )
165
257
Assert .assertTrue(getAlertsResponse.alerts.size == 1 )
258
+ val findings = searchFindings(id, customFindingsIndex)
259
+ assertEquals(" Findings saved for test monitor" , 1 , findings.size)
260
+ assertTrue(" Findings saved for test monitor" , findings[0 ].relatedDocIds.contains(" 2" ))
261
+ assertEquals(" Didn't match all 4 queries" , 1 , findings[0 ].docLevelQueries.size)
166
262
}
167
263
168
264
fun `test execute monitor with custom query index and custom field mappings` () {
@@ -373,7 +469,6 @@ class MonitorDataSourcesIT : AlertingSingleNodeTestCase() {
373
469
374
470
val customAlertsIndex = " custom_alerts_index"
375
471
val customQueryIndex = " custom_query_index"
376
- Assert .assertFalse(client().admin().cluster().state(ClusterStateRequest ()).get().state.routingTable.hasIndex(customQueryIndex))
377
472
val customFindingsIndex = " custom_findings_index"
378
473
val updateMonitorResponse = updateMonitor(
379
474
monitor.copy(
0 commit comments