@@ -74,6 +74,21 @@ class DocumentMonitorRunnerIT : AlertingRestTestCase() {
74
74
75
75
val alerts = searchAlerts(monitor)
76
76
assertEquals(" Alert saved for test monitor" , 0 , alerts.size)
77
+
78
+ // ensure doc level query is deleted on dry run
79
+ val request = """ {
80
+ "size": 10,
81
+ "query": {
82
+ "match_all": {}
83
+ }
84
+ }"""
85
+ var httpResponse = adminClient().makeRequest(
86
+ " GET" , " /${monitor.dataSources.queryIndex} /_search" ,
87
+ StringEntity (request, ContentType .APPLICATION_JSON )
88
+ )
89
+ assertEquals(" Search failed" , RestStatus .OK , httpResponse.restStatus())
90
+ var searchResponse = SearchResponse .fromXContent(createParser(JsonXContent .jsonXContent, httpResponse.entity.content))
91
+ searchResponse.hits.totalHits?.let { assertEquals(" Query saved in query index" , 0L , it.value) }
77
92
}
78
93
79
94
fun `test dryrun execute monitor with queryFieldNames set up with correct field` () {
@@ -252,6 +267,120 @@ class DocumentMonitorRunnerIT : AlertingRestTestCase() {
252
267
assertEquals(" Incorrect search result" , 2 , matchingDocsToQuery.size)
253
268
assertTrue(" Incorrect search result" , matchingDocsToQuery.contains(" 1|$testIndex " ))
254
269
assertTrue(" Incorrect search result" , matchingDocsToQuery.contains(" 5|$testIndex " ))
270
+
271
+ // ensure doc level query is deleted on dry run
272
+ val request = """ {
273
+ "size": 10,
274
+ "query": {
275
+ "match_all": {}
276
+ }
277
+ }"""
278
+ var httpResponse = adminClient().makeRequest(
279
+ " GET" , " /${monitor.dataSources.queryIndex} /_search" ,
280
+ StringEntity (request, ContentType .APPLICATION_JSON )
281
+ )
282
+ assertEquals(" Search failed" , RestStatus .OK , httpResponse.restStatus())
283
+ var searchResponse = SearchResponse .fromXContent(createParser(JsonXContent .jsonXContent, httpResponse.entity.content))
284
+ searchResponse.hits.totalHits?.let { assertEquals(" Query saved in query index" , 0L , it.value) }
285
+ }
286
+
287
+ fun `test execute monitor returns search result with dryrun then without dryrun ensure dry run query not saved` () {
288
+ val testIndex = createTestIndex()
289
+ val testTime = DateTimeFormatter .ISO_OFFSET_DATE_TIME .format(ZonedDateTime .now().truncatedTo(MILLIS ))
290
+ val testDoc = """ {
291
+ "message" : "This is an error from IAD region",
292
+ "test_strict_date_time" : "$testTime ",
293
+ "test_field" : "us-west-2"
294
+ }"""
295
+
296
+ val docQuery = DocLevelQuery (query = " test_field:\" us-west-2\" " , name = " 3" , fields = listOf ())
297
+ val docLevelInput = DocLevelMonitorInput (" description" , listOf (testIndex), listOf (docQuery))
298
+
299
+ val trigger = randomDocumentLevelTrigger(condition = ALWAYS_RUN )
300
+ val monitor = randomDocumentLevelMonitor(inputs = listOf (docLevelInput), triggers = listOf (trigger))
301
+
302
+ indexDoc(testIndex, " 1" , testDoc)
303
+ indexDoc(testIndex, " 2" , testDoc)
304
+
305
+ val response = executeMonitor(monitor, params = DRYRUN_MONITOR )
306
+
307
+ val output = entityAsMap(response)
308
+
309
+ assertEquals(monitor.name, output[" monitor_name" ])
310
+ @Suppress(" UNCHECKED_CAST" )
311
+ val searchResult = (output.objectMap(" input_results" )[" results" ] as List <Map <String , Any >>).first()
312
+ @Suppress(" UNCHECKED_CAST" )
313
+ val matchingDocsToQuery = searchResult[docQuery.id] as List <String >
314
+ assertEquals(" Incorrect search result" , 2 , matchingDocsToQuery.size)
315
+ assertTrue(" Incorrect search result" , matchingDocsToQuery.contains(" 1|$testIndex " ))
316
+ assertTrue(" Incorrect search result" , matchingDocsToQuery.contains(" 2|$testIndex " ))
317
+
318
+ // ensure doc level query is deleted on dry run
319
+ val request = """ {
320
+ "size": 10,
321
+ "query": {
322
+ "match_all": {}
323
+ }
324
+ }"""
325
+ var httpResponse = adminClient().makeRequest(
326
+ " GET" , " /${monitor.dataSources.queryIndex} /_search" ,
327
+ StringEntity (request, ContentType .APPLICATION_JSON )
328
+ )
329
+ assertEquals(" Search failed" , RestStatus .OK , httpResponse.restStatus())
330
+ var searchResponse = SearchResponse .fromXContent(createParser(JsonXContent .jsonXContent, httpResponse.entity.content))
331
+ searchResponse.hits.totalHits?.let { assertEquals(0L , it.value) }
332
+
333
+ // create and execute second monitor not as dryrun
334
+ val testIndex2 = createTestIndex(" test1" )
335
+ val testTime2 = DateTimeFormatter .ISO_OFFSET_DATE_TIME .format(ZonedDateTime .now().truncatedTo(MILLIS ))
336
+ val testDoc2 = """ {
337
+ "message" : "This is an error from IAD region",
338
+ "test_strict_date_time" : "$testTime2 ",
339
+ "test_field" : "us-east-1"
340
+ }"""
341
+
342
+ val docQuery2 = DocLevelQuery (query = " test_field:\" us-east-1\" " , name = " 3" , fields = listOf ())
343
+ val docLevelInput2 = DocLevelMonitorInput (" description" , listOf (testIndex2), listOf (docQuery2))
344
+
345
+ val trigger2 = randomDocumentLevelTrigger(condition = ALWAYS_RUN )
346
+ val monitor2 = createMonitor(randomDocumentLevelMonitor(inputs = listOf (docLevelInput2), triggers = listOf (trigger2)))
347
+ assertNotNull(monitor2.id)
348
+
349
+ indexDoc(testIndex2, " 1" , testDoc2)
350
+ indexDoc(testIndex2, " 5" , testDoc2)
351
+
352
+ val response2 = executeMonitor(monitor2.id)
353
+ val output2 = entityAsMap(response2)
354
+
355
+ assertEquals(monitor2.name, output2[" monitor_name" ])
356
+ @Suppress(" UNCHECKED_CAST" )
357
+ val searchResult2 = (output2.objectMap(" input_results" )[" results" ] as List <Map <String , Any >>).first()
358
+ @Suppress(" UNCHECKED_CAST" )
359
+ val matchingDocsToQuery2 = searchResult2[docQuery2.id] as List <String >
360
+ assertEquals(" Incorrect search result" , 2 , matchingDocsToQuery2.size)
361
+ assertTrue(" Incorrect search result" , matchingDocsToQuery2.containsAll(listOf (" 1|$testIndex2 " , " 5|$testIndex2 " )))
362
+
363
+ val alerts = searchAlertsWithFilter(monitor2)
364
+ assertEquals(" Alert saved for test monitor" , 2 , alerts.size)
365
+
366
+ val findings = searchFindings(monitor2)
367
+ assertEquals(" Findings saved for test monitor" , 2 , findings.size)
368
+ assertTrue(" Findings saved for test monitor" , findings[0 ].relatedDocIds.contains(" 1" ))
369
+ assertTrue(" Findings saved for test monitor" , findings[1 ].relatedDocIds.contains(" 5" ))
370
+
371
+ // ensure query from second monitor was saved
372
+ val expectedQueries = listOf (" test_field_test1_${monitor2.id} :\" us-east-1\" " )
373
+ httpResponse = adminClient().makeRequest(
374
+ " GET" , " /${monitor.dataSources.queryIndex} /_search" ,
375
+ StringEntity (request, ContentType .APPLICATION_JSON )
376
+ )
377
+ assertEquals(" Search failed" , RestStatus .OK , httpResponse.restStatus())
378
+ searchResponse = SearchResponse .fromXContent(createParser(JsonXContent .jsonXContent, httpResponse.entity.content))
379
+ searchResponse.hits.forEach { hit ->
380
+ val query = ((hit.sourceAsMap[" query" ] as Map <String , Any >)[" query_string" ] as Map <String , Any >)[" query" ]
381
+ assertTrue(expectedQueries.contains(query))
382
+ }
383
+ searchResponse.hits.totalHits?.let { assertEquals(" Query saved in query index" , 1L , it.value) }
255
384
}
256
385
257
386
fun `test execute monitor generates alerts and findings` () {
0 commit comments