Skip to content

Commit

Permalink
add queryFieldNames field in Doc Level Queries (opensearch-project#582)…
Browse files Browse the repository at this point in the history
… (opensearch-project#597)

* add queryFieldNames field in Doc Level Queries

* add tests to verify queryFieldNames field in DocLevelQuery

---------

(cherry picked from commit 75925dc)

Signed-off-by: Surya Sashank Nistala <[email protected]>
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
2 people authored and eirsep committed Mar 13, 2024
1 parent 397cf0c commit f14f3b9
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import org.opensearch.core.xcontent.ToXContent
import org.opensearch.core.xcontent.XContentBuilder
import org.opensearch.core.xcontent.XContentParser
import java.io.IOException
import java.lang.IllegalArgumentException
import java.util.UUID

data class DocLevelQuery(
val id: String = UUID.randomUUID().toString(),
val name: String,
val query: String,
val tags: List<String> = mutableListOf()
val tags: List<String> = mutableListOf(),
val queryFieldNames: List<String> = mutableListOf(),
) : BaseModel {

init {
Expand All @@ -31,15 +31,17 @@ data class DocLevelQuery(
sin.readString(), // id
sin.readString(), // name
sin.readString(), // query
sin.readStringList() // tags
sin.readStringList(), // tags,
sin.readStringList() // fieldsBeingQueried
)

fun asTemplateArg(): Map<String, Any> {
return mapOf(
QUERY_ID_FIELD to id,
NAME_FIELD to name,
QUERY_FIELD to query,
TAGS_FIELD to tags
TAGS_FIELD to tags,
QUERY_FIELD_NAMES_FIELD to queryFieldNames
)
}

Expand All @@ -49,6 +51,7 @@ data class DocLevelQuery(
out.writeString(name)
out.writeString(query)
out.writeStringCollection(tags)
out.writeStringCollection(queryFieldNames)
}

override fun toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder {
Expand All @@ -57,6 +60,7 @@ data class DocLevelQuery(
.field(NAME_FIELD, name)
.field(QUERY_FIELD, query)
.field(TAGS_FIELD, tags.toTypedArray())
.field(QUERY_FIELD_NAMES_FIELD, queryFieldNames.toTypedArray())
.endObject()
return builder
}
Expand All @@ -66,6 +70,7 @@ data class DocLevelQuery(
const val NAME_FIELD = "name"
const val QUERY_FIELD = "query"
const val TAGS_FIELD = "tags"
const val QUERY_FIELD_NAMES_FIELD = "query_field_names"
const val NO_ID = ""
val INVALID_CHARACTERS: List<String> = listOf(" ", "[", "]", "{", "}", "(", ")")

Expand All @@ -76,6 +81,7 @@ data class DocLevelQuery(
lateinit var query: String
lateinit var name: String
val tags: MutableList<String> = mutableListOf()
val queryFieldNames: MutableList<String> = mutableListOf()

XContentParserUtils.ensureExpectedToken(XContentParser.Token.START_OBJECT, xcp.currentToken(), xcp)
while (xcp.nextToken() != XContentParser.Token.END_OBJECT) {
Expand All @@ -88,6 +94,7 @@ data class DocLevelQuery(
name = xcp.text()
validateQuery(name)
}

QUERY_FIELD -> query = xcp.text()
TAGS_FIELD -> {
XContentParserUtils.ensureExpectedToken(
Expand All @@ -101,14 +108,27 @@ data class DocLevelQuery(
tags.add(tag)
}
}

QUERY_FIELD_NAMES_FIELD -> {
XContentParserUtils.ensureExpectedToken(
XContentParser.Token.START_ARRAY,
xcp.currentToken(),
xcp
)
while (xcp.nextToken() != XContentParser.Token.END_ARRAY) {
val field = xcp.text()
queryFieldNames.add(field)
}
}
}
}

return DocLevelQuery(
id = id,
name = name,
query = query,
tags = tags
tags = tags,
queryFieldNames = queryFieldNames
)
}

Expand All @@ -129,4 +149,18 @@ data class DocLevelQuery(
}
}
}

// constructor for java plugins' convenience to optionally avoid passing empty list for 'fieldsBeingQueried' field
constructor(
id: String,
name: String,
query: String,
tags: MutableList<String>,
) : this(
id = id,
name = name,
query = query,
tags = tags,
queryFieldNames = emptyList()
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import org.opensearch.commons.alerting.randomAction
import org.opensearch.commons.alerting.randomActionExecutionPolicy
import org.opensearch.commons.alerting.randomBucketLevelTrigger
import org.opensearch.commons.alerting.randomChainedAlertTrigger
import org.opensearch.commons.alerting.randomDocLevelQuery
import org.opensearch.commons.alerting.randomDocumentLevelTrigger
import org.opensearch.commons.alerting.randomQueryLevelMonitor
import org.opensearch.commons.alerting.randomQueryLevelTrigger
Expand All @@ -19,6 +20,7 @@ import org.opensearch.commons.alerting.randomUser
import org.opensearch.commons.alerting.randomUserEmpty
import org.opensearch.commons.authuser.User
import org.opensearch.search.builder.SearchSourceBuilder
import kotlin.test.assertTrue

class WriteableTests {

Expand Down Expand Up @@ -112,6 +114,29 @@ class WriteableTests {
Assertions.assertEquals(trigger, newTrigger, "Round tripping DocumentLevelTrigger doesn't work")
}

@Test
fun `test doc-level query as stream`() {
val dlq = randomDocLevelQuery()
val out = BytesStreamOutput()
dlq.writeTo(out)
val sin = StreamInput.wrap(out.bytes().toBytesRef().bytes)
val newDlq = DocLevelQuery.readFrom(sin)
Assertions.assertEquals(dlq, newDlq, "Round tripping DocLevelQuery doesn't work")
assertTrue(newDlq.queryFieldNames.isEmpty())
}

@Test
fun `test doc-level query with query Field Names as stream`() {
val dlq = randomDocLevelQuery().copy(queryFieldNames = listOf("f1", "f2"))
val out = BytesStreamOutput()
dlq.writeTo(out)
val sin = StreamInput.wrap(out.bytes().toBytesRef().bytes)
val newDlq = DocLevelQuery.readFrom(sin)
assertTrue(newDlq.queryFieldNames.contains(dlq.queryFieldNames[0]))
assertTrue(newDlq.queryFieldNames.contains(dlq.queryFieldNames[1]))
Assertions.assertEquals(dlq, newDlq, "Round tripping DocLevelQuery doesn't work")
}

@Test
fun `test chained alert trigger as stream`() {
val trigger = randomChainedAlertTrigger()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,30 @@ class XContentTests {
)
}

@Test
fun `test doc level query toXcontent`() {
val dlq = DocLevelQuery("id", "name", "query", listOf("t1", "t2"))
val dlqString = dlq.toXContent(builder(), ToXContent.EMPTY_PARAMS).string()
val parsedDlq = DocLevelQuery.parse(parser(dlqString))
Assertions.assertEquals(
dlq,
parsedDlq,
"Round tripping Doc level query doesn't work"
)
}

@Test
fun `test doc level query toXcontent with query field names`() {
val dlq = DocLevelQuery("id", "name", "query", listOf("t1", "t2"), listOf("f1", "f2"))
val dlqString = dlq.toXContent(builder(), ToXContent.EMPTY_PARAMS).string()
val parsedDlq = DocLevelQuery.parse(parser(dlqString))
Assertions.assertEquals(
dlq,
parsedDlq,
"Round tripping Doc level query doesn't work"
)
}

@Test
fun `test alert parsing`() {
val alert = randomAlert()
Expand Down

0 comments on commit f14f3b9

Please sign in to comment.