Skip to content

Commit

Permalink
Alerting Enhancements: Alerting Comments (Experimental) (opensearch-p…
Browse files Browse the repository at this point in the history
…roject#663)

* initial commit, functional but needs refactoring

Signed-off-by: Dennis Toepker <[email protected]>

* added lastUpdatedTime to Note object

Signed-off-by: Dennis Toepker <[email protected]>

* changed name from alert id to entity id

Signed-off-by: Dennis Toepker <[email protected]>

* import cleanup

Signed-off-by: Dennis Toepker <[email protected]>

* changing name from Alerting Notes to Alerting Comments

Signed-off-by: Dennis Toepker <[email protected]>

* misc fixes and cleanup

Signed-off-by: Dennis Toepker <[email protected]>

* adding unit test coverage

Signed-off-by: Dennis Toepker <[email protected]>

* misc cleanup

Signed-off-by: Dennis Toepker <[email protected]>

* misc review-based cleanup

Signed-off-by: Dennis Toepker <[email protected]>

* added validation exception messages

Signed-off-by: Dennis Toepker <[email protected]>

---------

Signed-off-by: Dennis Toepker <[email protected]>
Co-authored-by: Dennis Toepker <[email protected]>
  • Loading branch information
toepkerd and toepkerd-zz authored Jun 7, 2024
1 parent 0d21526 commit acaa844
Show file tree
Hide file tree
Showing 14 changed files with 578 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ object AlertingActions {
const val SUBSCRIBE_FINDINGS_ACTION_NAME = "cluster:admin/opensearch/alerting/findings/subscribe"
const val GET_MONITOR_ACTION_NAME = "cluster:admin/opendistro/alerting/monitor/get"
const val SEARCH_MONITORS_ACTION_NAME = "cluster:admin/opendistro/alerting/monitor/search"
const val INDEX_COMMENT_ACTION_NAME = "cluster:admin/opensearch/alerting/alerts/comments/write"
const val SEARCH_COMMENTS_ACTION_NAME = "cluster:admin/opensearch/alerting/alerts/comments/search"
const val DELETE_COMMENT_ACTION_NAME = "cluster:admin/opensearch/alerting/alerts/comments/delete"

@JvmField
val INDEX_MONITOR_ACTION_TYPE =
Expand Down Expand Up @@ -73,4 +76,16 @@ object AlertingActions {
@JvmField
val SEARCH_MONITORS_ACTION_TYPE =
ActionType(SEARCH_MONITORS_ACTION_NAME, ::SearchResponse)

@JvmField
val INDEX_COMMENT_ACTION_TYPE =
ActionType(INDEX_COMMENT_ACTION_NAME, ::IndexCommentResponse)

@JvmField
val SEARCH_COMMENTS_ACTION_TYPE =
ActionType(SEARCH_COMMENTS_ACTION_NAME, ::SearchResponse)

@JvmField
val DELETE_COMMENT_ACTION_TYPE =
ActionType(DELETE_COMMENT_ACTION_NAME, ::DeleteCommentResponse)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.opensearch.commons.alerting.action

import org.opensearch.action.ActionRequest
import org.opensearch.action.ActionRequestValidationException
import org.opensearch.core.common.io.stream.StreamInput
import org.opensearch.core.common.io.stream.StreamOutput
import java.io.IOException

class DeleteCommentRequest : ActionRequest {
val commentId: String

constructor(commentId: String) : super() {
this.commentId = commentId
}

@Throws(IOException::class)
constructor(sin: StreamInput) : this(
commentId = sin.readString()
)

override fun validate(): ActionRequestValidationException? {
if (commentId.isBlank()) {
val exception = ActionRequestValidationException()
exception.addValidationError("comment id must not be blank")
return exception
}
return null
}

@Throws(IOException::class)
override fun writeTo(out: StreamOutput) {
out.writeString(commentId)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.opensearch.commons.alerting.action

import org.opensearch.commons.alerting.util.IndexUtils
import org.opensearch.commons.notifications.action.BaseResponse
import org.opensearch.core.common.io.stream.StreamInput
import org.opensearch.core.common.io.stream.StreamOutput
import org.opensearch.core.xcontent.ToXContent
import org.opensearch.core.xcontent.XContentBuilder

class DeleteCommentResponse : BaseResponse {
var commentId: String

constructor(
id: String
) : super() {
this.commentId = id
}

constructor(sin: StreamInput) : this(
sin.readString() // commentId
)

override fun writeTo(out: StreamOutput) {
out.writeString(commentId)
}

override fun toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder {
return builder.startObject()
.field(IndexUtils._ID, commentId)
.endObject()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.opensearch.commons.alerting.action

import org.opensearch.action.ActionRequest
import org.opensearch.action.ActionRequestValidationException
import org.opensearch.core.common.io.stream.StreamInput
import org.opensearch.core.common.io.stream.StreamOutput
import org.opensearch.rest.RestRequest
import java.io.IOException

/**
* Request to index/create a Comment
*
* entityId: the entity that the Comment is attached to and therefore associated with (e.g. in Alerting,
* the entity is an Alert). This field is expected to be non-blank if the request is to create a new Comment.
*
* commentId: the ID of an existing Comment. This field is expected to be non-blank if the request is to
* update an existing Comment.
*/
class IndexCommentRequest : ActionRequest {
val entityId: String
val commentId: String
val seqNo: Long
val primaryTerm: Long
val method: RestRequest.Method
var content: String

constructor(
entityId: String,
commentId: String,
seqNo: Long,
primaryTerm: Long,
method: RestRequest.Method,
content: String
) : super() {
this.entityId = entityId
this.commentId = commentId
this.seqNo = seqNo
this.primaryTerm = primaryTerm
this.method = method
this.content = content
}

@Throws(IOException::class)
constructor(sin: StreamInput) : this(
entityId = sin.readString(),
commentId = sin.readString(),
seqNo = sin.readLong(),
primaryTerm = sin.readLong(),
method = sin.readEnum(RestRequest.Method::class.java),
content = sin.readString()
)

override fun validate(): ActionRequestValidationException? {
if (method == RestRequest.Method.POST && entityId.isBlank() ||
method == RestRequest.Method.PUT && commentId.isBlank()
) {
val exception = ActionRequestValidationException()
exception.addValidationError("id must not be blank")
return exception
}
return null
}

@Throws(IOException::class)
override fun writeTo(out: StreamOutput) {
out.writeString(entityId)
out.writeString(commentId)
out.writeLong(seqNo)
out.writeLong(primaryTerm)
out.writeEnum(method)
out.writeString(content)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.opensearch.commons.alerting.action

import org.opensearch.commons.alerting.model.Comment
import org.opensearch.commons.alerting.util.IndexUtils.Companion._ID
import org.opensearch.commons.alerting.util.IndexUtils.Companion._PRIMARY_TERM
import org.opensearch.commons.alerting.util.IndexUtils.Companion._SEQ_NO
import org.opensearch.commons.notifications.action.BaseResponse
import org.opensearch.core.common.io.stream.StreamInput
import org.opensearch.core.common.io.stream.StreamOutput
import org.opensearch.core.xcontent.ToXContent
import org.opensearch.core.xcontent.XContentBuilder
import java.io.IOException

class IndexCommentResponse : BaseResponse {
var id: String
var seqNo: Long
var primaryTerm: Long
var comment: Comment

constructor(
id: String,
seqNo: Long,
primaryTerm: Long,
comment: Comment
) : super() {
this.id = id
this.seqNo = seqNo
this.primaryTerm = primaryTerm
this.comment = comment
}

@Throws(IOException::class)
constructor(sin: StreamInput) : this(
sin.readString(), // id
sin.readLong(), // seqNo
sin.readLong(), // primaryTerm
Comment.readFrom(sin) // comment
)

@Throws(IOException::class)
override fun writeTo(out: StreamOutput) {
out.writeString(id)
out.writeLong(seqNo)
out.writeLong(primaryTerm)
comment.writeTo(out)
}

@Throws(IOException::class)
override fun toXContent(builder: XContentBuilder, params: ToXContent.Params): XContentBuilder {
return builder.startObject()
.field(_ID, id)
.field(_SEQ_NO, seqNo)
.field(_PRIMARY_TERM, primaryTerm)
.field("comment", comment)
.endObject()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.opensearch.commons.alerting.action

import org.opensearch.action.ActionRequest
import org.opensearch.action.ActionRequestValidationException
import org.opensearch.action.search.SearchRequest
import org.opensearch.core.common.io.stream.StreamInput
import org.opensearch.core.common.io.stream.StreamOutput
import java.io.IOException

class SearchCommentRequest : ActionRequest {

val searchRequest: SearchRequest

constructor(
searchRequest: SearchRequest
) : super() {
this.searchRequest = searchRequest
}

@Throws(IOException::class)
constructor(sin: StreamInput) : this(
searchRequest = SearchRequest(sin)
)

override fun validate(): ActionRequestValidationException? {
return null
}

@Throws(IOException::class)
override fun writeTo(out: StreamOutput) {
searchRequest.writeTo(out)
}
}
Loading

0 comments on commit acaa844

Please sign in to comment.