Skip to content

Commit a60ad67

Browse files
authored
Notification plugin interface and models (#31)
Currently Alerting, ISM and Reporting plugins are expected to make call to Notification plugin to send notification. The plugins can communicate using REST or Transport layer. Transport layer makes call to same node and hence avoids network hop so transport layer communication is preferred. common-utils contains the model (with marshaling/unmarshaling code) for the communication. above mentioned plugins consumes common-utils and uses these models for communication. Note: Plugins runs on different JVM and hence the notification plugins needs to check if the class is same before accessing the values. transport marshaling/unmarshaling ( writeTo(output: StreamOutput) and constructor(input: StreamInput) of models) are used for this purpose. REST APIs in notification plugin uses toXContent and parse marshaling/unmarshaling [Tests] Contains unit test for all model classes Signed-off-by: @akbhatta
1 parent 200649d commit a60ad67

File tree

102 files changed

+14928
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+14928
-1
lines changed

detekt.yml

+9-1
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,12 @@ style:
2020
max: 10
2121
ReturnCount:
2222
active: true
23-
max: 10
23+
max: 10
24+
25+
complexity:
26+
LargeClass:
27+
excludes: ['**/test/**']
28+
LongMethod:
29+
excludes: ['**/test/**']
30+
LongParameterList:
31+
excludes: ['**/test/**']
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package org.opensearch.commons.notifications
2+
3+
/**
4+
* Class containing Internal constants like JSON tags and defaults.
5+
*/
6+
object NotificationConstants {
7+
const val CONFIG_ID_TAG = "config_id"
8+
const val CONFIG_ID_LIST_TAG = "config_id_list"
9+
const val EVENT_ID_TAG = "event_id"
10+
const val EVENT_ID_LIST_TAG = "event_id_list"
11+
const val EMAIL_ACCOUNT_ID_TAG = "email_account_id"
12+
const val REFERENCE_ID_TAG = "reference_id"
13+
const val CHANNEL_ID_LIST_TAG = "channel_id_list"
14+
const val CONFIG_NAME_TAG = "config_name"
15+
const val CONFIG_TYPE_TAG = "config_type"
16+
const val CONFIG_TAG = "config"
17+
const val EVENT_TAG = "event"
18+
const val EVENT_SOURCE_TAG = "event_source"
19+
const val FEATURE_TAG = "feature"
20+
const val THREAD_CONTEXT_TAG = "context"
21+
const val CHANNEL_MESSAGE_TAG = "channel_message"
22+
const val TEXT_DESCRIPTION_TAG = "text_description"
23+
const val HTML_DESCRIPTION_TAG = "html_description"
24+
const val ATTACHMENT_TAG = "attachment"
25+
const val FILE_NAME_TAG = "file_name"
26+
const val FILE_ENCODING_TAG = "file_encoding"
27+
const val FILE_DATA_TAG = "file_data"
28+
const val FILE_CONTENT_TYPE_TAG = "file_content_type"
29+
const val RECIPIENT_TAG = "recipient"
30+
const val RECIPIENT_LIST_TAG = "recipient_list"
31+
const val EMAIL_RECIPIENT_STATUS_TAG = "email_recipient_status"
32+
const val EMAIL_GROUP_ID_LIST_TAG = "email_group_id_list"
33+
const val STATUS_CODE_TAG = "status_code"
34+
const val STATUS_TEXT_TAG = "status_text"
35+
const val DELIVERY_STATUS_TAG = "delivery_status"
36+
const val NAME_TAG = "name"
37+
const val DESCRIPTION_TAG = "description"
38+
const val IS_ENABLED_TAG = "is_enabled"
39+
const val FEATURE_LIST_TAG = "feature_list"
40+
const val TITLE_TAG = "title"
41+
const val SEVERITY_TAG = "severity"
42+
const val TAGS_TAG = "tags"
43+
const val URL_TAG = "url"
44+
const val HEADER_PARAMS_TAG = "header_params"
45+
const val HOST_TAG = "host"
46+
const val PORT_TAG = "port"
47+
const val METHOD_TAG = "method"
48+
const val FROM_ADDRESS_TAG = "from_address"
49+
const val UPDATED_TIME_TAG = "last_updated_time_ms"
50+
const val CREATED_TIME_TAG = "created_time_ms"
51+
const val TENANT_TAG = "tenant"
52+
const val CONFIG_LIST_TAG = "config_list"
53+
const val EVENT_LIST_TAG = "event_list"
54+
const val FEATURE_CONFIG_LIST_TAG = "feature_channel_list"
55+
const val DELETE_RESPONSE_LIST_TAG = "delete_response_list"
56+
const val FROM_INDEX_TAG = "from_index"
57+
const val MAX_ITEMS_TAG = "max_items"
58+
const val SORT_FIELD_TAG = "sort_field"
59+
const val SORT_ORDER_TAG = "sort_order"
60+
const val FILTER_PARAM_LIST_TAG = "filter_param_list"
61+
const val STATUS_LIST_TAG = "status_list"
62+
const val START_INDEX_TAG = "start_index"
63+
const val TOTAL_HITS_TAG = "total_hits"
64+
const val TOTAL_HIT_RELATION_TAG = "total_hit_relation"
65+
const val QUERY_TAG = "query"
66+
const val COMPACT_TAG = "compact"
67+
const val CONFIG_TYPE_LIST_TAG = "config_type_list"
68+
const val PLUGIN_FEATURES_TAG = "plugin_features"
69+
70+
const val DEFAULT_MAX_ITEMS = 1000
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*
8+
* Modifications Copyright OpenSearch Contributors. See
9+
* GitHub history for details.
10+
*/
11+
12+
/*
13+
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
14+
*
15+
* Licensed under the Apache License, Version 2.0 (the "License").
16+
* You may not use this file except in compliance with the License.
17+
* A copy of the License is located at
18+
*
19+
* http://www.apache.org/licenses/LICENSE-2.0
20+
*
21+
* or in the "license" file accompanying this file. This file is distributed
22+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
23+
* express or implied. See the License for the specific language governing
24+
* permissions and limitations under the License.
25+
*
26+
*/
27+
package org.opensearch.commons.notifications
28+
29+
import org.opensearch.action.ActionListener
30+
import org.opensearch.client.node.NodeClient
31+
import org.opensearch.commons.ConfigConstants.OPENSEARCH_SECURITY_USER_INFO_THREAD_CONTEXT
32+
import org.opensearch.commons.notifications.action.CreateNotificationConfigRequest
33+
import org.opensearch.commons.notifications.action.CreateNotificationConfigResponse
34+
import org.opensearch.commons.notifications.action.DeleteNotificationConfigRequest
35+
import org.opensearch.commons.notifications.action.DeleteNotificationConfigResponse
36+
import org.opensearch.commons.notifications.action.GetFeatureChannelListRequest
37+
import org.opensearch.commons.notifications.action.GetFeatureChannelListResponse
38+
import org.opensearch.commons.notifications.action.GetNotificationConfigRequest
39+
import org.opensearch.commons.notifications.action.GetNotificationConfigResponse
40+
import org.opensearch.commons.notifications.action.GetNotificationEventRequest
41+
import org.opensearch.commons.notifications.action.GetNotificationEventResponse
42+
import org.opensearch.commons.notifications.action.GetPluginFeaturesRequest
43+
import org.opensearch.commons.notifications.action.GetPluginFeaturesResponse
44+
import org.opensearch.commons.notifications.action.NotificationsActions.CREATE_NOTIFICATION_CONFIG_ACTION_TYPE
45+
import org.opensearch.commons.notifications.action.NotificationsActions.DELETE_NOTIFICATION_CONFIG_ACTION_TYPE
46+
import org.opensearch.commons.notifications.action.NotificationsActions.GET_FEATURE_CHANNEL_LIST_ACTION_TYPE
47+
import org.opensearch.commons.notifications.action.NotificationsActions.GET_NOTIFICATION_CONFIG_ACTION_TYPE
48+
import org.opensearch.commons.notifications.action.NotificationsActions.GET_NOTIFICATION_EVENT_ACTION_TYPE
49+
import org.opensearch.commons.notifications.action.NotificationsActions.GET_PLUGIN_FEATURES_ACTION_TYPE
50+
import org.opensearch.commons.notifications.action.NotificationsActions.SEND_NOTIFICATION_ACTION_TYPE
51+
import org.opensearch.commons.notifications.action.NotificationsActions.UPDATE_NOTIFICATION_CONFIG_ACTION_TYPE
52+
import org.opensearch.commons.notifications.action.SendNotificationRequest
53+
import org.opensearch.commons.notifications.action.SendNotificationResponse
54+
import org.opensearch.commons.notifications.action.UpdateNotificationConfigRequest
55+
import org.opensearch.commons.notifications.action.UpdateNotificationConfigResponse
56+
import org.opensearch.commons.notifications.model.ChannelMessage
57+
import org.opensearch.commons.notifications.model.EventSource
58+
import org.opensearch.commons.utils.SecureClientWrapper
59+
60+
/**
61+
* All the transport action plugin interfaces for the Notification plugin
62+
*/
63+
object NotificationsPluginInterface {
64+
65+
/**
66+
* Create notification configuration.
67+
* @param client Node client for making transport action
68+
* @param request The request object
69+
* @param listener The listener for getting response
70+
*/
71+
fun createNotificationConfig(
72+
client: NodeClient,
73+
request: CreateNotificationConfigRequest,
74+
listener: ActionListener<CreateNotificationConfigResponse>
75+
) {
76+
client.execute(
77+
CREATE_NOTIFICATION_CONFIG_ACTION_TYPE,
78+
request,
79+
listener
80+
)
81+
}
82+
83+
/**
84+
* Update notification configuration.
85+
* @param client Node client for making transport action
86+
* @param request The request object
87+
* @param listener The listener for getting response
88+
*/
89+
fun updateNotificationConfig(
90+
client: NodeClient,
91+
request: UpdateNotificationConfigRequest,
92+
listener: ActionListener<UpdateNotificationConfigResponse>
93+
) {
94+
client.execute(
95+
UPDATE_NOTIFICATION_CONFIG_ACTION_TYPE,
96+
request,
97+
listener
98+
)
99+
}
100+
101+
/**
102+
* Delete notification configuration.
103+
* @param client Node client for making transport action
104+
* @param request The request object
105+
* @param listener The listener for getting response
106+
*/
107+
fun deleteNotificationConfig(
108+
client: NodeClient,
109+
request: DeleteNotificationConfigRequest,
110+
listener: ActionListener<DeleteNotificationConfigResponse>
111+
) {
112+
client.execute(
113+
DELETE_NOTIFICATION_CONFIG_ACTION_TYPE,
114+
request,
115+
listener
116+
)
117+
}
118+
119+
/**
120+
* Get notification configuration.
121+
* @param client Node client for making transport action
122+
* @param request The request object
123+
* @param listener The listener for getting response
124+
*/
125+
fun getNotificationConfig(
126+
client: NodeClient,
127+
request: GetNotificationConfigRequest,
128+
listener: ActionListener<GetNotificationConfigResponse>
129+
) {
130+
client.execute(
131+
GET_NOTIFICATION_CONFIG_ACTION_TYPE,
132+
request,
133+
listener
134+
)
135+
}
136+
137+
/**
138+
* Get notification events.
139+
* @param client Node client for making transport action
140+
* @param request The request object
141+
* @param listener The listener for getting response
142+
*/
143+
fun getNotificationEvent(
144+
client: NodeClient,
145+
request: GetNotificationEventRequest,
146+
listener: ActionListener<GetNotificationEventResponse>
147+
) {
148+
client.execute(
149+
GET_NOTIFICATION_EVENT_ACTION_TYPE,
150+
request,
151+
listener
152+
)
153+
}
154+
155+
/**
156+
* Get notification plugin features.
157+
* @param client Node client for making transport action
158+
* @param request The request object
159+
* @param listener The listener for getting response
160+
*/
161+
fun getPluginFeatures(
162+
client: NodeClient,
163+
request: GetPluginFeaturesRequest,
164+
listener: ActionListener<GetPluginFeaturesResponse>
165+
) {
166+
client.execute(
167+
GET_PLUGIN_FEATURES_ACTION_TYPE,
168+
request,
169+
listener
170+
)
171+
}
172+
173+
/**
174+
* Get notification channel configuration enabled for a feature.
175+
* @param client Node client for making transport action
176+
* @param request The request object
177+
* @param listener The listener for getting response
178+
*/
179+
fun getFeatureChannelList(
180+
client: NodeClient,
181+
request: GetFeatureChannelListRequest,
182+
listener: ActionListener<GetFeatureChannelListResponse>
183+
) {
184+
client.execute(
185+
GET_FEATURE_CHANNEL_LIST_ACTION_TYPE,
186+
request,
187+
listener
188+
)
189+
}
190+
191+
/**
192+
* Send notification API enabled for a feature. No REST API. Internal API only for Inter plugin communication.
193+
* @param client Node client for making transport action
194+
* @param eventSource The notification event information
195+
* @param channelMessage The notification message
196+
* @param channelIds The list of channel ids to send message to.
197+
* @param listener The listener for getting response
198+
*/
199+
fun sendNotification(
200+
client: NodeClient,
201+
eventSource: EventSource,
202+
channelMessage: ChannelMessage,
203+
channelIds: List<String>,
204+
listener: ActionListener<SendNotificationResponse>
205+
) {
206+
val threadContext: String? =
207+
client.threadPool().threadContext.getTransient<String>(OPENSEARCH_SECURITY_USER_INFO_THREAD_CONTEXT)
208+
val wrapper = SecureClientWrapper(client) // Executing request in privileged mode
209+
wrapper.execute(
210+
SEND_NOTIFICATION_ACTION_TYPE,
211+
SendNotificationRequest(eventSource, channelMessage, channelIds, threadContext),
212+
listener
213+
)
214+
}
215+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*
8+
* Modifications Copyright OpenSearch Contributors. See
9+
* GitHub history for details.
10+
*/
11+
12+
/*
13+
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
14+
*
15+
* Licensed under the Apache License, Version 2.0 (the "License").
16+
* You may not use this file except in compliance with the License.
17+
* A copy of the License is located at
18+
*
19+
* http://www.apache.org/licenses/LICENSE-2.0
20+
*
21+
* or in the "license" file accompanying this file. This file is distributed
22+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
23+
* express or implied. See the License for the specific language governing
24+
* permissions and limitations under the License.
25+
*
26+
*/
27+
28+
package org.opensearch.commons.notifications.action
29+
30+
import org.opensearch.action.ActionResponse
31+
import org.opensearch.common.io.stream.StreamInput
32+
import org.opensearch.common.xcontent.ToXContentObject
33+
import org.opensearch.rest.RestStatus
34+
import java.io.IOException
35+
36+
/**
37+
* Base response which give REST status.
38+
*/
39+
abstract class BaseResponse : ActionResponse, ToXContentObject {
40+
41+
/**
42+
* constructor for creating the class
43+
*/
44+
constructor()
45+
46+
/**
47+
* {@inheritDoc}
48+
*/
49+
@Throws(IOException::class)
50+
constructor(input: StreamInput) : super(input)
51+
52+
/**
53+
* get rest status for the response. Useful override for multi-status response.
54+
* @return RestStatus for the response
55+
*/
56+
open fun getStatus(): RestStatus {
57+
return RestStatus.OK
58+
}
59+
}

0 commit comments

Comments
 (0)