From 8a848179b0cb65ba38c154ff02d3d81954025320 Mon Sep 17 00:00:00 2001 From: Jindal Date: Sat, 2 Apr 2022 01:37:56 -0700 Subject: [PATCH 1/2] Removal of NotificationEvent Request, Response , Search Results Addition of NotificationEventDoc and Removal of NotificationEventInfo Addition of NotificationEventDocTests Signed-off-by: Jindal --- .../model/NotificationEventDoc.kt | 68 +++++++++++ .../model/NotificationEventDocTests.kt | 114 ++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 src/main/kotlin/org/opensearch/commons/notifications/model/NotificationEventDoc.kt create mode 100644 src/test/kotlin/org/opensearch/commons/notifications/model/NotificationEventDocTests.kt diff --git a/src/main/kotlin/org/opensearch/commons/notifications/model/NotificationEventDoc.kt b/src/main/kotlin/org/opensearch/commons/notifications/model/NotificationEventDoc.kt new file mode 100644 index 00000000..48f4e6e7 --- /dev/null +++ b/src/main/kotlin/org/opensearch/commons/notifications/model/NotificationEventDoc.kt @@ -0,0 +1,68 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ +package org.opensearch.notifications.model + +import org.opensearch.common.xcontent.ToXContent +import org.opensearch.common.xcontent.XContentBuilder +import org.opensearch.common.xcontent.XContentParser +import org.opensearch.common.xcontent.XContentParserUtils +import org.opensearch.commons.notifications.NotificationConstants.EVENT_TAG +import org.opensearch.commons.notifications.model.NotificationEvent +import org.opensearch.commons.utils.logger +import java.io.IOException + +/** + * Data class representing Notification event. + */ +data class NotificationEventDoc( + val event: NotificationEvent +) : ToXContent { + + companion object { + private val log by logger(NotificationEventDoc::class.java) + + /** + * Parse the data from parser and create object + * @param parser data referenced at parser + * @return created object + */ + @JvmStatic + @Throws(IOException::class) + fun parse(parser: XContentParser): NotificationEventDoc { + var event: NotificationEvent? = null + + XContentParserUtils.ensureExpectedToken( + XContentParser.Token.START_OBJECT, + parser.currentToken(), + parser + ) + while (parser.nextToken() != XContentParser.Token.END_OBJECT) { + val fieldName = parser.currentName() + parser.nextToken() + when (fieldName) { + EVENT_TAG -> event = NotificationEvent.parse(parser) + else -> { + parser.skipChildren() + log.info("Unexpected field: $fieldName, while parsing event doc") + } + } + } + event ?: throw IllegalArgumentException("$EVENT_TAG field absent") + return NotificationEventDoc( + event + ) + } + } + + /** + * {@inheritDoc} + */ + override fun toXContent(builder: XContentBuilder?, params: ToXContent.Params?): XContentBuilder { + builder!! + return builder.startObject() + .field(EVENT_TAG, event) + .endObject() + } +} diff --git a/src/test/kotlin/org/opensearch/commons/notifications/model/NotificationEventDocTests.kt b/src/test/kotlin/org/opensearch/commons/notifications/model/NotificationEventDocTests.kt new file mode 100644 index 00000000..c299b916 --- /dev/null +++ b/src/test/kotlin/org/opensearch/commons/notifications/model/NotificationEventDocTests.kt @@ -0,0 +1,114 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ +package org.opensearch.notifications.model + +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.opensearch.commons.notifications.model.ConfigType +import org.opensearch.commons.notifications.model.DeliveryStatus +import org.opensearch.commons.notifications.model.EventSource +import org.opensearch.commons.notifications.model.EventStatus +import org.opensearch.commons.notifications.model.NotificationEvent +import org.opensearch.commons.notifications.model.SeverityType +import org.opensearch.commons.utils.createObjectFromJsonString +import org.opensearch.commons.utils.getJsonString +import java.time.Instant + +internal class NotificationEventDocTests { + + @Test + fun `Event doc serialize and deserialize using json config object should be equal`() { + val sampleEventSource = EventSource( + "title", + "reference_id", + tags = listOf("tag1", "tag2"), + severity = SeverityType.INFO + ) + val status = EventStatus( + "config_id", + "name", + ConfigType.CHIME, + deliveryStatus = DeliveryStatus("200", "success") + ) + val sampleEvent = NotificationEvent(sampleEventSource, listOf(status)) + val eventDoc = NotificationEventDoc(sampleEvent) + val jsonString = getJsonString(eventDoc) + val recreatedObject = createObjectFromJsonString(jsonString) { NotificationEventDoc.parse(it) } + assertEquals(eventDoc, recreatedObject) + } + + @Test + fun `Event doc should safely ignore extra field in json object`() { + val lastUpdatedTimeMs = Instant.ofEpochMilli(Instant.now().toEpochMilli()) + val createdTimeMs = Instant.ofEpochMilli(Instant.now().minusSeconds(2000).toEpochMilli()) + val eventSource = EventSource( + "title", + "reference_id", + tags = listOf("tag1", "tag2"), + severity = SeverityType.INFO + ) + val eventStatus = EventStatus( + "config_id", + "name", + ConfigType.CHIME, + deliveryStatus = DeliveryStatus("200", "success") + ) + val sampleEvent = NotificationEvent(eventSource, listOf(eventStatus)) + val eventDoc = NotificationEventDoc(sampleEvent) + val jsonString = """ + { + "metadata":{ + "last_updated_time_ms":"${lastUpdatedTimeMs.toEpochMilli()}", + "created_time_ms":"${createdTimeMs.toEpochMilli()}", + "access":["br1", "br2", "br3"] + }, + "event":{ + "event_source":{ + "title":"title", + "reference_id":"reference_id", + "severity":"info", + "tags":["tag1", "tag2"] + }, + "status_list":[ + { + "config_id":"config_id", + "config_type":"chime", + "config_name":"name", + "delivery_status": + { + "status_code":"200", + "status_text":"success" + } + } + ] + }, + "extra_field_1":["extra", "value"], + "extra_field_2":{"extra":"value"}, + "extra_field_3":"extra value 3" + } + """.trimIndent() + val recreatedObject = createObjectFromJsonString(jsonString) { NotificationEventDoc.parse(it) } + assertEquals(eventDoc, recreatedObject) + } + + @Test + fun `Event doc should throw exception if event is absent in json`() { + val lastUpdatedTimeMs = Instant.ofEpochMilli(Instant.now().toEpochMilli()) + val createdTimeMs = Instant.ofEpochMilli(Instant.now().minusSeconds(2000).toEpochMilli()) + val jsonString = """ + { + "metadata":{ + "last_updated_time_ms":"${lastUpdatedTimeMs.toEpochMilli()}", + "created_time_ms":"${createdTimeMs.toEpochMilli()}", + "access":["br1", "br2", "br3"] + } + } + """.trimIndent() + Assertions.assertThrows(IllegalArgumentException::class.java) { + createObjectFromJsonString(jsonString) { NotificationEventDoc.parse(it) } + } + } +} From bbcc973ef87cf4fe70a4d94262f87e3779c3fc9c Mon Sep 17 00:00:00 2001 From: Jindal Date: Mon, 4 Apr 2022 17:31:10 -0700 Subject: [PATCH 2/2] Removing NotificationEventDoc and NotificationEventDocTests Signed-off-by: Jindal --- .../action/SendNotificationResponse.kt | 43 ++----- .../model/NotificationEventDoc.kt | 68 ----------- .../NotificationsPluginInterfaceTests.kt | 14 ++- .../action/SendNotificationResponseTests.kt | 52 ++++++-- .../model/NotificationEventDocTests.kt | 114 ------------------ 5 files changed, 61 insertions(+), 230 deletions(-) delete mode 100644 src/main/kotlin/org/opensearch/commons/notifications/model/NotificationEventDoc.kt delete mode 100644 src/test/kotlin/org/opensearch/commons/notifications/model/NotificationEventDocTests.kt diff --git a/src/main/kotlin/org/opensearch/commons/notifications/action/SendNotificationResponse.kt b/src/main/kotlin/org/opensearch/commons/notifications/action/SendNotificationResponse.kt index 96599b3a..8967bdd9 100644 --- a/src/main/kotlin/org/opensearch/commons/notifications/action/SendNotificationResponse.kt +++ b/src/main/kotlin/org/opensearch/commons/notifications/action/SendNotificationResponse.kt @@ -10,19 +10,16 @@ import org.opensearch.common.io.stream.Writeable import org.opensearch.common.xcontent.ToXContent import org.opensearch.common.xcontent.XContentBuilder import org.opensearch.common.xcontent.XContentParser -import org.opensearch.common.xcontent.XContentParserUtils -import org.opensearch.commons.notifications.NotificationConstants.EVENT_ID_TAG -import org.opensearch.commons.utils.logger +import org.opensearch.commons.notifications.model.NotificationEvent import java.io.IOException /** * Action Response for send notification. */ class SendNotificationResponse : BaseResponse { - val notificationId: String + val notificationEvent: NotificationEvent companion object { - private val log by logger(SendNotificationResponse::class.java) /** * reader to create instance of class from writable. @@ -36,35 +33,16 @@ class SendNotificationResponse : BaseResponse { @JvmStatic @Throws(IOException::class) fun parse(parser: XContentParser): SendNotificationResponse { - var notificationId: String? = null - - XContentParserUtils.ensureExpectedToken( - XContentParser.Token.START_OBJECT, - parser.currentToken(), - parser - ) - while (parser.nextToken() != XContentParser.Token.END_OBJECT) { - val fieldName = parser.currentName() - parser.nextToken() - when (fieldName) { - EVENT_ID_TAG -> notificationId = parser.text() - else -> { - parser.skipChildren() - log.info("Unexpected field: $fieldName, while parsing SendNotificationResponse") - } - } - } - notificationId ?: throw IllegalArgumentException("$EVENT_ID_TAG field absent") - return SendNotificationResponse(notificationId) + return SendNotificationResponse(NotificationEvent.parse(parser)) } } /** * constructor for creating the class - * @param configId the id of the created notification configuration + * @param notificationEvent the id of the created notification configuration */ - constructor(configId: String) { - this.notificationId = configId + constructor(notificationEvent: NotificationEvent) { + this.notificationEvent = notificationEvent } /** @@ -72,7 +50,7 @@ class SendNotificationResponse : BaseResponse { */ @Throws(IOException::class) constructor(input: StreamInput) : super(input) { - notificationId = input.readString() + notificationEvent = NotificationEvent(input) } /** @@ -80,16 +58,13 @@ class SendNotificationResponse : BaseResponse { */ @Throws(IOException::class) override fun writeTo(output: StreamOutput) { - output.writeString(notificationId) + notificationEvent.writeTo(output) } /** * {@inheritDoc} */ override fun toXContent(builder: XContentBuilder?, params: ToXContent.Params?): XContentBuilder { - builder!! - return builder.startObject() - .field(EVENT_ID_TAG, notificationId) - .endObject() + return notificationEvent.toXContent(builder, params) } } diff --git a/src/main/kotlin/org/opensearch/commons/notifications/model/NotificationEventDoc.kt b/src/main/kotlin/org/opensearch/commons/notifications/model/NotificationEventDoc.kt deleted file mode 100644 index 48f4e6e7..00000000 --- a/src/main/kotlin/org/opensearch/commons/notifications/model/NotificationEventDoc.kt +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ -package org.opensearch.notifications.model - -import org.opensearch.common.xcontent.ToXContent -import org.opensearch.common.xcontent.XContentBuilder -import org.opensearch.common.xcontent.XContentParser -import org.opensearch.common.xcontent.XContentParserUtils -import org.opensearch.commons.notifications.NotificationConstants.EVENT_TAG -import org.opensearch.commons.notifications.model.NotificationEvent -import org.opensearch.commons.utils.logger -import java.io.IOException - -/** - * Data class representing Notification event. - */ -data class NotificationEventDoc( - val event: NotificationEvent -) : ToXContent { - - companion object { - private val log by logger(NotificationEventDoc::class.java) - - /** - * Parse the data from parser and create object - * @param parser data referenced at parser - * @return created object - */ - @JvmStatic - @Throws(IOException::class) - fun parse(parser: XContentParser): NotificationEventDoc { - var event: NotificationEvent? = null - - XContentParserUtils.ensureExpectedToken( - XContentParser.Token.START_OBJECT, - parser.currentToken(), - parser - ) - while (parser.nextToken() != XContentParser.Token.END_OBJECT) { - val fieldName = parser.currentName() - parser.nextToken() - when (fieldName) { - EVENT_TAG -> event = NotificationEvent.parse(parser) - else -> { - parser.skipChildren() - log.info("Unexpected field: $fieldName, while parsing event doc") - } - } - } - event ?: throw IllegalArgumentException("$EVENT_TAG field absent") - return NotificationEventDoc( - event - ) - } - } - - /** - * {@inheritDoc} - */ - override fun toXContent(builder: XContentBuilder?, params: ToXContent.Params?): XContentBuilder { - builder!! - return builder.startObject() - .field(EVENT_TAG, event) - .endObject() - } -} diff --git a/src/test/kotlin/org/opensearch/commons/notifications/NotificationsPluginInterfaceTests.kt b/src/test/kotlin/org/opensearch/commons/notifications/NotificationsPluginInterfaceTests.kt index 556c35b6..61cbca7a 100644 --- a/src/test/kotlin/org/opensearch/commons/notifications/NotificationsPluginInterfaceTests.kt +++ b/src/test/kotlin/org/opensearch/commons/notifications/NotificationsPluginInterfaceTests.kt @@ -40,10 +40,13 @@ import org.opensearch.commons.notifications.model.Channel import org.opensearch.commons.notifications.model.ChannelList import org.opensearch.commons.notifications.model.ChannelMessage import org.opensearch.commons.notifications.model.ConfigType +import org.opensearch.commons.notifications.model.DeliveryStatus import org.opensearch.commons.notifications.model.EventSource +import org.opensearch.commons.notifications.model.EventStatus import org.opensearch.commons.notifications.model.NotificationConfig import org.opensearch.commons.notifications.model.NotificationConfigInfo import org.opensearch.commons.notifications.model.NotificationConfigSearchResult +import org.opensearch.commons.notifications.model.NotificationEvent import org.opensearch.commons.notifications.model.SeverityType import org.opensearch.commons.notifications.model.Slack import org.opensearch.rest.RestStatus @@ -180,7 +183,16 @@ internal class NotificationsPluginInterfaceTests { null ) - val response = SendNotificationResponse("configId") + val sampleStatus = EventStatus( + "config_id", + "name", + ConfigType.SLACK, + deliveryStatus = DeliveryStatus("404", "invalid recipient") + ) + + val sampleEvent = NotificationEvent(notificationInfo, listOf(sampleStatus)) + + val response = SendNotificationResponse(sampleEvent) val listener: ActionListener = mock(ActionListener::class.java) as ActionListener diff --git a/src/test/kotlin/org/opensearch/commons/notifications/action/SendNotificationResponseTests.kt b/src/test/kotlin/org/opensearch/commons/notifications/action/SendNotificationResponseTests.kt index ca7f789c..4d828998 100644 --- a/src/test/kotlin/org/opensearch/commons/notifications/action/SendNotificationResponseTests.kt +++ b/src/test/kotlin/org/opensearch/commons/notifications/action/SendNotificationResponseTests.kt @@ -5,9 +5,15 @@ package org.opensearch.commons.notifications.action import com.fasterxml.jackson.core.JsonParseException +import org.junit.Test import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows +import org.opensearch.commons.notifications.model.ConfigType +import org.opensearch.commons.notifications.model.DeliveryStatus +import org.opensearch.commons.notifications.model.EventSource +import org.opensearch.commons.notifications.model.EventStatus +import org.opensearch.commons.notifications.model.NotificationEvent +import org.opensearch.commons.notifications.model.SeverityType import org.opensearch.commons.utils.createObjectFromJsonString import org.opensearch.commons.utils.getJsonString import org.opensearch.commons.utils.recreateObject @@ -16,25 +22,29 @@ internal class SendNotificationResponseTests { @Test fun `Create response serialize and deserialize transport object should be equal`() { - val configResponse = SendNotificationResponse("sample_notification_id") - val recreatedObject = recreateObject(configResponse) { SendNotificationResponse(it) } - assertEquals(configResponse.notificationId, recreatedObject.notificationId) + + val sampleEvent = getSampleEvent() + + val recreatedObject = recreateObject(sampleEvent) { SendNotificationResponse(it) } + assertEquals(sampleEvent, recreatedObject) } @Test fun `Create response serialize and deserialize using json object should be equal`() { - val configResponse = SendNotificationResponse("sample_notification_id") - val jsonString = getJsonString(configResponse) + + val sampleEvent = getSampleEvent() + + val jsonString = getJsonString(sampleEvent) val recreatedObject = createObjectFromJsonString(jsonString) { SendNotificationResponse.parse(it) } - assertEquals(configResponse.notificationId, recreatedObject.notificationId) + assertEquals(sampleEvent, recreatedObject) } @Test fun `Create response should deserialize json object using parser`() { - val notificationId = "sample_notification_id" - val jsonString = "{\"event_id\":\"$notificationId\"}" + val sampleEvent = getSampleEvent() + val jsonString = "{\"event_id\":\"$sampleEvent\"}" val recreatedObject = createObjectFromJsonString(jsonString) { SendNotificationResponse.parse(it) } - assertEquals(notificationId, recreatedObject.notificationId) + assertEquals(sampleEvent, recreatedObject) } @Test @@ -55,16 +65,32 @@ internal class SendNotificationResponseTests { @Test fun `Create response should safely ignore extra field in json object`() { - val notificationId = "sample_notification_id" + val sampleEvent = getSampleEvent() val jsonString = """ { - "event_id":"$notificationId", + "event_id":"$sampleEvent", "extra_field_1":["extra", "value"], "extra_field_2":{"extra":"value"}, "extra_field_3":"extra value 3" } """.trimIndent() val recreatedObject = createObjectFromJsonString(jsonString) { SendNotificationResponse.parse(it) } - assertEquals(notificationId, recreatedObject.notificationId) + assertEquals(sampleEvent, recreatedObject) + } + + private fun getSampleEvent(): NotificationEvent { + val sampleEventSource = EventSource( + "title", + "reference_id", + severity = SeverityType.INFO + ) + val sampleStatus = EventStatus( + "config_id", + "name", + ConfigType.SLACK, + deliveryStatus = DeliveryStatus("404", "invalid recipient") + ) + + return NotificationEvent(sampleEventSource, listOf(sampleStatus)) } } diff --git a/src/test/kotlin/org/opensearch/commons/notifications/model/NotificationEventDocTests.kt b/src/test/kotlin/org/opensearch/commons/notifications/model/NotificationEventDocTests.kt deleted file mode 100644 index c299b916..00000000 --- a/src/test/kotlin/org/opensearch/commons/notifications/model/NotificationEventDocTests.kt +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ -package org.opensearch.notifications.model - -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test -import org.opensearch.commons.notifications.model.ConfigType -import org.opensearch.commons.notifications.model.DeliveryStatus -import org.opensearch.commons.notifications.model.EventSource -import org.opensearch.commons.notifications.model.EventStatus -import org.opensearch.commons.notifications.model.NotificationEvent -import org.opensearch.commons.notifications.model.SeverityType -import org.opensearch.commons.utils.createObjectFromJsonString -import org.opensearch.commons.utils.getJsonString -import java.time.Instant - -internal class NotificationEventDocTests { - - @Test - fun `Event doc serialize and deserialize using json config object should be equal`() { - val sampleEventSource = EventSource( - "title", - "reference_id", - tags = listOf("tag1", "tag2"), - severity = SeverityType.INFO - ) - val status = EventStatus( - "config_id", - "name", - ConfigType.CHIME, - deliveryStatus = DeliveryStatus("200", "success") - ) - val sampleEvent = NotificationEvent(sampleEventSource, listOf(status)) - val eventDoc = NotificationEventDoc(sampleEvent) - val jsonString = getJsonString(eventDoc) - val recreatedObject = createObjectFromJsonString(jsonString) { NotificationEventDoc.parse(it) } - assertEquals(eventDoc, recreatedObject) - } - - @Test - fun `Event doc should safely ignore extra field in json object`() { - val lastUpdatedTimeMs = Instant.ofEpochMilli(Instant.now().toEpochMilli()) - val createdTimeMs = Instant.ofEpochMilli(Instant.now().minusSeconds(2000).toEpochMilli()) - val eventSource = EventSource( - "title", - "reference_id", - tags = listOf("tag1", "tag2"), - severity = SeverityType.INFO - ) - val eventStatus = EventStatus( - "config_id", - "name", - ConfigType.CHIME, - deliveryStatus = DeliveryStatus("200", "success") - ) - val sampleEvent = NotificationEvent(eventSource, listOf(eventStatus)) - val eventDoc = NotificationEventDoc(sampleEvent) - val jsonString = """ - { - "metadata":{ - "last_updated_time_ms":"${lastUpdatedTimeMs.toEpochMilli()}", - "created_time_ms":"${createdTimeMs.toEpochMilli()}", - "access":["br1", "br2", "br3"] - }, - "event":{ - "event_source":{ - "title":"title", - "reference_id":"reference_id", - "severity":"info", - "tags":["tag1", "tag2"] - }, - "status_list":[ - { - "config_id":"config_id", - "config_type":"chime", - "config_name":"name", - "delivery_status": - { - "status_code":"200", - "status_text":"success" - } - } - ] - }, - "extra_field_1":["extra", "value"], - "extra_field_2":{"extra":"value"}, - "extra_field_3":"extra value 3" - } - """.trimIndent() - val recreatedObject = createObjectFromJsonString(jsonString) { NotificationEventDoc.parse(it) } - assertEquals(eventDoc, recreatedObject) - } - - @Test - fun `Event doc should throw exception if event is absent in json`() { - val lastUpdatedTimeMs = Instant.ofEpochMilli(Instant.now().toEpochMilli()) - val createdTimeMs = Instant.ofEpochMilli(Instant.now().minusSeconds(2000).toEpochMilli()) - val jsonString = """ - { - "metadata":{ - "last_updated_time_ms":"${lastUpdatedTimeMs.toEpochMilli()}", - "created_time_ms":"${createdTimeMs.toEpochMilli()}", - "access":["br1", "br2", "br3"] - } - } - """.trimIndent() - Assertions.assertThrows(IllegalArgumentException::class.java) { - createObjectFromJsonString(jsonString) { NotificationEventDoc.parse(it) } - } - } -}