From a96f5c47aebfb40b019e3862b1286f46ed92cc42 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Wed, 14 Jul 2021 16:12:30 -0700 Subject: [PATCH 01/14] WIP send notifications Signed-off-by: Joshua Li --- .../action/CreateReportDefinitionAction.kt | 3 +- .../action/NotificationsActions.kt | 56 +++++++++++++++++++ .../action/OnDemandReportCreateAction.kt | 3 +- .../action/ReportDefinitionActions.kt | 5 +- .../action/ReportInstanceActions.kt | 9 ++- .../ReportDefinitionRestHandler.kt | 1 + 6 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/NotificationsActions.kt diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/CreateReportDefinitionAction.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/CreateReportDefinitionAction.kt index 6f576959..7b383738 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/CreateReportDefinitionAction.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/CreateReportDefinitionAction.kt @@ -33,6 +33,7 @@ import org.opensearch.reportsscheduler.model.CreateReportDefinitionResponse import org.opensearch.action.ActionType import org.opensearch.action.support.ActionFilters import org.opensearch.client.Client +import org.opensearch.client.node.NodeClient import org.opensearch.common.inject.Inject import org.opensearch.common.xcontent.NamedXContentRegistry import org.opensearch.transport.TransportService @@ -59,6 +60,6 @@ internal class CreateReportDefinitionAction @Inject constructor( * {@inheritDoc} */ override fun executeRequest(request: CreateReportDefinitionRequest, user: User?): CreateReportDefinitionResponse { - return ReportDefinitionActions.create(request, user) + return ReportDefinitionActions.create(client as NodeClient, request, user) } } diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/NotificationsActions.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/NotificationsActions.kt new file mode 100644 index 00000000..73794186 --- /dev/null +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/NotificationsActions.kt @@ -0,0 +1,56 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.reportsscheduler.action + +import org.opensearch.action.ActionListener +import org.opensearch.client.node.NodeClient +import org.opensearch.commons.notifications.NotificationsPluginInterface +import org.opensearch.commons.notifications.action.SendNotificationResponse +import org.opensearch.commons.notifications.model.ChannelMessage +import org.opensearch.commons.notifications.model.EventSource +import org.opensearch.commons.notifications.model.Feature +import org.opensearch.commons.notifications.model.SeverityType +import org.opensearch.reportsscheduler.ReportsSchedulerPlugin.Companion.LOG_PREFIX +import org.opensearch.reportsscheduler.model.CreateReportDefinitionResponse +import org.opensearch.reportsscheduler.model.ReportDefinition +import org.opensearch.reportsscheduler.util.logger + +/** + * Report definitions index operation actions. + */ +internal object NotificationsActions { + private val log by logger(NotificationsActions::class.java) + + /** + * Send notifications based on delivery parameter + * @param delivery [ReportDefinition.Delivery] object + * @return [CreateReportDefinitionResponse] + */ + fun send(client: NodeClient, delivery: ReportDefinition.Delivery, referenceId: String) { + log.info("$LOG_PREFIX:NotificationsActions-send") + NotificationsPluginInterface.sendNotification( + client, + EventSource(delivery.title, referenceId, Feature.REPORTS, SeverityType.INFO), + ChannelMessage(delivery.textDescription, delivery.htmlDescription, null), + delivery.configIds, + object : ActionListener { + override fun onResponse(p0: SendNotificationResponse) { + log.info("$LOG_PREFIX:NotificationsActions-send:${p0.notificationId}") + } + + override fun onFailure(p0: java.lang.Exception) { + log.error("$LOG_PREFIX:NotificationsActions-send error:$p0") + } + } + ) + } +} diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/OnDemandReportCreateAction.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/OnDemandReportCreateAction.kt index 1af9858e..28dbae1c 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/OnDemandReportCreateAction.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/OnDemandReportCreateAction.kt @@ -33,6 +33,7 @@ import org.opensearch.reportsscheduler.model.OnDemandReportCreateResponse import org.opensearch.action.ActionType import org.opensearch.action.support.ActionFilters import org.opensearch.client.Client +import org.opensearch.client.node.NodeClient import org.opensearch.common.inject.Inject import org.opensearch.common.xcontent.NamedXContentRegistry import org.opensearch.transport.TransportService @@ -59,6 +60,6 @@ internal class OnDemandReportCreateAction @Inject constructor( * {@inheritDoc} */ override fun executeRequest(request: OnDemandReportCreateRequest, user: User?): OnDemandReportCreateResponse { - return ReportInstanceActions.createOnDemandFromDefinition(request, user) + return ReportInstanceActions.createOnDemandFromDefinition(client as NodeClient, request, user) } } diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportDefinitionActions.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportDefinitionActions.kt index 8a4f9ac1..83116b65 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportDefinitionActions.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportDefinitionActions.kt @@ -45,6 +45,7 @@ import org.opensearch.reportsscheduler.model.UpdateReportDefinitionResponse import org.opensearch.reportsscheduler.security.UserAccessManager import org.opensearch.reportsscheduler.util.logger import org.opensearch.OpenSearchStatusException +import org.opensearch.client.node.NodeClient import org.opensearch.rest.RestStatus import java.time.Instant @@ -59,7 +60,7 @@ internal object ReportDefinitionActions { * @param request [CreateReportDefinitionRequest] object * @return [CreateReportDefinitionResponse] */ - fun create(request: CreateReportDefinitionRequest, user: User?): CreateReportDefinitionResponse { + fun create(client: NodeClient, request: CreateReportDefinitionRequest, user: User?): CreateReportDefinitionResponse { log.info("$LOG_PREFIX:ReportDefinition-create") UserAccessManager.validateUser(user) val currentTime = Instant.now() @@ -73,6 +74,8 @@ internal object ReportDefinitionActions { val docId = ReportDefinitionsIndex.createReportDefinition(reportDefinitionDetails) docId ?: throw OpenSearchStatusException("Report Definition Creation failed", RestStatus.INTERNAL_SERVER_ERROR) + if (request.reportDefinition.delivery != null) + NotificationsActions.send(client, request.reportDefinition.delivery, docId) return CreateReportDefinitionResponse(docId) } diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportInstanceActions.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportInstanceActions.kt index 49e04e00..df02856a 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportInstanceActions.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportInstanceActions.kt @@ -49,6 +49,7 @@ import org.opensearch.reportsscheduler.security.UserAccessManager import org.opensearch.reportsscheduler.settings.PluginSettings import org.opensearch.reportsscheduler.util.logger import org.opensearch.OpenSearchStatusException +import org.opensearch.client.node.NodeClient import org.opensearch.rest.RestStatus import java.time.Instant import kotlin.random.Random @@ -93,7 +94,11 @@ internal object ReportInstanceActions { * @param request [OnDemandReportCreateRequest] object * @return [OnDemandReportCreateResponse] */ - fun createOnDemandFromDefinition(request: OnDemandReportCreateRequest, user: User?): OnDemandReportCreateResponse { + fun createOnDemandFromDefinition( + client: NodeClient, + request: OnDemandReportCreateRequest, + user: User? + ): OnDemandReportCreateResponse { log.info("$LOG_PREFIX:ReportInstance-createOnDemandFromDefinition ${request.reportDefinitionId}") UserAccessManager.validateUser(user) val currentTime = Instant.now() @@ -126,6 +131,8 @@ internal object ReportInstanceActions { throw OpenSearchStatusException("Report Instance Creation failed", RestStatus.INTERNAL_SERVER_ERROR) } val reportInstanceCopy = reportInstance.copy(id = docId) + if (reportDefinitionDetails.reportDefinition.delivery != null) + NotificationsActions.send(client, reportDefinitionDetails.reportDefinition.delivery, docId) return OnDemandReportCreateResponse(reportInstanceCopy, UserAccessManager.hasAllInfoAccess(user)) } diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/resthandler/ReportDefinitionRestHandler.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/resthandler/ReportDefinitionRestHandler.kt index 591209cd..016f6d17 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/resthandler/ReportDefinitionRestHandler.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/resthandler/ReportDefinitionRestHandler.kt @@ -41,6 +41,7 @@ import org.opensearch.reportsscheduler.model.RestTag.REPORT_DEFINITION_ID_FIELD import org.opensearch.reportsscheduler.model.UpdateReportDefinitionRequest import org.opensearch.reportsscheduler.util.contentParserNextToken import org.opensearch.client.node.NodeClient +import org.opensearch.reportsscheduler.action.NotificationsActions import org.opensearch.rest.BaseRestHandler.RestChannelConsumer import org.opensearch.rest.BytesRestResponse import org.opensearch.rest.RestHandler.Route From 4d12a59e7f2734b38e670b02c481ad6411cd33a4 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Thu, 15 Jul 2021 15:37:45 -0700 Subject: [PATCH 02/14] Remove send notification when creating report definition Signed-off-by: Joshua Li --- .../reportsscheduler/action/CreateReportDefinitionAction.kt | 3 +-- .../reportsscheduler/action/ReportDefinitionActions.kt | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/CreateReportDefinitionAction.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/CreateReportDefinitionAction.kt index 7b383738..6f576959 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/CreateReportDefinitionAction.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/CreateReportDefinitionAction.kt @@ -33,7 +33,6 @@ import org.opensearch.reportsscheduler.model.CreateReportDefinitionResponse import org.opensearch.action.ActionType import org.opensearch.action.support.ActionFilters import org.opensearch.client.Client -import org.opensearch.client.node.NodeClient import org.opensearch.common.inject.Inject import org.opensearch.common.xcontent.NamedXContentRegistry import org.opensearch.transport.TransportService @@ -60,6 +59,6 @@ internal class CreateReportDefinitionAction @Inject constructor( * {@inheritDoc} */ override fun executeRequest(request: CreateReportDefinitionRequest, user: User?): CreateReportDefinitionResponse { - return ReportDefinitionActions.create(client as NodeClient, request, user) + return ReportDefinitionActions.create(request, user) } } diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportDefinitionActions.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportDefinitionActions.kt index 83116b65..8a4f9ac1 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportDefinitionActions.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportDefinitionActions.kt @@ -45,7 +45,6 @@ import org.opensearch.reportsscheduler.model.UpdateReportDefinitionResponse import org.opensearch.reportsscheduler.security.UserAccessManager import org.opensearch.reportsscheduler.util.logger import org.opensearch.OpenSearchStatusException -import org.opensearch.client.node.NodeClient import org.opensearch.rest.RestStatus import java.time.Instant @@ -60,7 +59,7 @@ internal object ReportDefinitionActions { * @param request [CreateReportDefinitionRequest] object * @return [CreateReportDefinitionResponse] */ - fun create(client: NodeClient, request: CreateReportDefinitionRequest, user: User?): CreateReportDefinitionResponse { + fun create(request: CreateReportDefinitionRequest, user: User?): CreateReportDefinitionResponse { log.info("$LOG_PREFIX:ReportDefinition-create") UserAccessManager.validateUser(user) val currentTime = Instant.now() @@ -74,8 +73,6 @@ internal object ReportDefinitionActions { val docId = ReportDefinitionsIndex.createReportDefinition(reportDefinitionDetails) docId ?: throw OpenSearchStatusException("Report Definition Creation failed", RestStatus.INTERNAL_SERVER_ERROR) - if (request.reportDefinition.delivery != null) - NotificationsActions.send(client, request.reportDefinition.delivery, docId) return CreateReportDefinitionResponse(docId) } From c5674aeaa509b015527bb4d13d865f86586faf80 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Fri, 16 Jul 2021 09:28:08 -0700 Subject: [PATCH 03/14] WIP Signed-off-by: Joshua Li --- .../server/routes/lib/createReportDefinition.ts | 3 +++ .../reportsscheduler/ReportsSchedulerPlugin.kt | 3 +++ .../action/NotificationsActions.kt | 15 ++++++++++++++- .../action/OnDemandReportCreateAction.kt | 3 +-- .../action/ReportDefinitionActions.kt | 2 ++ .../action/ReportInstanceActions.kt | 13 ++++--------- .../scheduler/ReportDefinitionJobRunner.kt | 3 +++ 7 files changed, 30 insertions(+), 12 deletions(-) diff --git a/dashboards-reports/server/routes/lib/createReportDefinition.ts b/dashboards-reports/server/routes/lib/createReportDefinition.ts index 03434b2e..ec6bcdf5 100644 --- a/dashboards-reports/server/routes/lib/createReportDefinition.ts +++ b/dashboards-reports/server/routes/lib/createReportDefinition.ts @@ -45,6 +45,9 @@ export const createReportDefinition = async ( const reqBody = { reportDefinition: uiToBackendReportDefinition(reportDefinition), }; + console.log('!!') + console.log(reqBody) + console.log(JSON.stringify(reqBody, null, 2)) const opensearchResp = await opensearchReportsClient.callAsCurrentUser( 'opensearch_reports.createReportDefinition', { diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/ReportsSchedulerPlugin.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/ReportsSchedulerPlugin.kt index 9f0b7c33..c1f4033d 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/ReportsSchedulerPlugin.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/ReportsSchedulerPlugin.kt @@ -58,6 +58,7 @@ import org.opensearch.reportsscheduler.settings.PluginSettings import org.opensearch.action.ActionRequest import org.opensearch.action.ActionResponse import org.opensearch.client.Client +import org.opensearch.client.node.NodeClient import org.opensearch.cluster.metadata.IndexNameExpressionResolver import org.opensearch.cluster.node.DiscoveryNodes import org.opensearch.cluster.service.ClusterService @@ -72,6 +73,7 @@ import org.opensearch.env.Environment import org.opensearch.env.NodeEnvironment import org.opensearch.plugins.ActionPlugin import org.opensearch.plugins.Plugin +import org.opensearch.reportsscheduler.action.NotificationsActions import org.opensearch.repositories.RepositoriesService import org.opensearch.rest.RestController import org.opensearch.rest.RestHandler @@ -122,6 +124,7 @@ class ReportsSchedulerPlugin : Plugin(), ActionPlugin, JobSchedulerExtension { PluginSettings.addSettingsUpdateConsumer(clusterService) ReportDefinitionsIndex.initialize(client, clusterService) ReportInstancesIndex.initialize(client, clusterService) + NotificationsActions.initialize(client as NodeClient) return emptyList() } diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/NotificationsActions.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/NotificationsActions.kt index 73794186..06d52a46 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/NotificationsActions.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/NotificationsActions.kt @@ -12,7 +12,9 @@ package org.opensearch.reportsscheduler.action import org.opensearch.action.ActionListener +import org.opensearch.client.Client import org.opensearch.client.node.NodeClient +import org.opensearch.cluster.service.ClusterService import org.opensearch.commons.notifications.NotificationsPluginInterface import org.opensearch.commons.notifications.action.SendNotificationResponse import org.opensearch.commons.notifications.model.ChannelMessage @@ -22,6 +24,7 @@ import org.opensearch.commons.notifications.model.SeverityType import org.opensearch.reportsscheduler.ReportsSchedulerPlugin.Companion.LOG_PREFIX import org.opensearch.reportsscheduler.model.CreateReportDefinitionResponse import org.opensearch.reportsscheduler.model.ReportDefinition +import org.opensearch.reportsscheduler.util.SecureIndexClient import org.opensearch.reportsscheduler.util.logger /** @@ -30,12 +33,22 @@ import org.opensearch.reportsscheduler.util.logger internal object NotificationsActions { private val log by logger(NotificationsActions::class.java) + private lateinit var client: NodeClient + + /** + * Initialize the class + * @param client NodeClient for transport call + */ + fun initialize(client: NodeClient) { + this.client = client + } + /** * Send notifications based on delivery parameter * @param delivery [ReportDefinition.Delivery] object * @return [CreateReportDefinitionResponse] */ - fun send(client: NodeClient, delivery: ReportDefinition.Delivery, referenceId: String) { + fun send(delivery: ReportDefinition.Delivery, referenceId: String) { log.info("$LOG_PREFIX:NotificationsActions-send") NotificationsPluginInterface.sendNotification( client, diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/OnDemandReportCreateAction.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/OnDemandReportCreateAction.kt index 28dbae1c..1af9858e 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/OnDemandReportCreateAction.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/OnDemandReportCreateAction.kt @@ -33,7 +33,6 @@ import org.opensearch.reportsscheduler.model.OnDemandReportCreateResponse import org.opensearch.action.ActionType import org.opensearch.action.support.ActionFilters import org.opensearch.client.Client -import org.opensearch.client.node.NodeClient import org.opensearch.common.inject.Inject import org.opensearch.common.xcontent.NamedXContentRegistry import org.opensearch.transport.TransportService @@ -60,6 +59,6 @@ internal class OnDemandReportCreateAction @Inject constructor( * {@inheritDoc} */ override fun executeRequest(request: OnDemandReportCreateRequest, user: User?): OnDemandReportCreateResponse { - return ReportInstanceActions.createOnDemandFromDefinition(client as NodeClient, request, user) + return ReportInstanceActions.createOnDemandFromDefinition(request, user) } } diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportDefinitionActions.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportDefinitionActions.kt index 8a4f9ac1..980c31d6 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportDefinitionActions.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportDefinitionActions.kt @@ -73,6 +73,8 @@ internal object ReportDefinitionActions { val docId = ReportDefinitionsIndex.createReportDefinition(reportDefinitionDetails) docId ?: throw OpenSearchStatusException("Report Definition Creation failed", RestStatus.INTERNAL_SERVER_ERROR) + if (request.reportDefinition.delivery != null) + NotificationsActions.send(request.reportDefinition.delivery, docId) return CreateReportDefinitionResponse(docId) } diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportInstanceActions.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportInstanceActions.kt index df02856a..4cebea96 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportInstanceActions.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportInstanceActions.kt @@ -27,6 +27,7 @@ package org.opensearch.reportsscheduler.action +import org.opensearch.OpenSearchStatusException import org.opensearch.commons.authuser.User import org.opensearch.reportsscheduler.ReportsSchedulerPlugin.Companion.LOG_PREFIX import org.opensearch.reportsscheduler.index.ReportDefinitionsIndex @@ -48,8 +49,6 @@ import org.opensearch.reportsscheduler.model.UpdateReportInstanceStatusResponse import org.opensearch.reportsscheduler.security.UserAccessManager import org.opensearch.reportsscheduler.settings.PluginSettings import org.opensearch.reportsscheduler.util.logger -import org.opensearch.OpenSearchStatusException -import org.opensearch.client.node.NodeClient import org.opensearch.rest.RestStatus import java.time.Instant import kotlin.random.Random @@ -94,11 +93,7 @@ internal object ReportInstanceActions { * @param request [OnDemandReportCreateRequest] object * @return [OnDemandReportCreateResponse] */ - fun createOnDemandFromDefinition( - client: NodeClient, - request: OnDemandReportCreateRequest, - user: User? - ): OnDemandReportCreateResponse { + fun createOnDemandFromDefinition(request: OnDemandReportCreateRequest, user: User?): OnDemandReportCreateResponse { log.info("$LOG_PREFIX:ReportInstance-createOnDemandFromDefinition ${request.reportDefinitionId}") UserAccessManager.validateUser(user) val currentTime = Instant.now() @@ -130,9 +125,9 @@ internal object ReportInstanceActions { Metrics.REPORT_FROM_DEFINITION_ID_SYSTEM_ERROR.counter.increment() throw OpenSearchStatusException("Report Instance Creation failed", RestStatus.INTERNAL_SERVER_ERROR) } - val reportInstanceCopy = reportInstance.copy(id = docId) if (reportDefinitionDetails.reportDefinition.delivery != null) - NotificationsActions.send(client, reportDefinitionDetails.reportDefinition.delivery, docId) + NotificationsActions.send(reportDefinitionDetails.reportDefinition.delivery, docId) + val reportInstanceCopy = reportInstance.copy(id = docId) return OnDemandReportCreateResponse(reportInstanceCopy, UserAccessManager.hasAllInfoAccess(user)) } diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/scheduler/ReportDefinitionJobRunner.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/scheduler/ReportDefinitionJobRunner.kt index 2a9c9067..d27f61c9 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/scheduler/ReportDefinitionJobRunner.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/scheduler/ReportDefinitionJobRunner.kt @@ -38,6 +38,7 @@ import org.opensearch.reportsscheduler.util.logger import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import org.opensearch.reportsscheduler.action.NotificationsActions import java.time.Instant internal object ReportDefinitionJobRunner : ScheduledJobRunner { @@ -67,6 +68,8 @@ internal object ReportDefinitionJobRunner : ScheduledJobRunner { if (id == null) { log.warn("$LOG_PREFIX:runJob-job creation failed for $reportInstance") } else { + if (reportDefinitionDetails.reportDefinition.delivery != null) + NotificationsActions.send(reportDefinitionDetails.reportDefinition.delivery, id) log.info("$LOG_PREFIX:runJob-created job:$id") } } From 112585be2ea5e45b879ccbbb84afa7a25c05ee59 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Fri, 16 Jul 2021 15:39:40 -0700 Subject: [PATCH 04/14] Remove unused lines Signed-off-by: Joshua Li --- dashboards-reports/server/routes/lib/createReportDefinition.ts | 3 --- .../reportsscheduler/action/ReportDefinitionActions.kt | 2 -- 2 files changed, 5 deletions(-) diff --git a/dashboards-reports/server/routes/lib/createReportDefinition.ts b/dashboards-reports/server/routes/lib/createReportDefinition.ts index ec6bcdf5..03434b2e 100644 --- a/dashboards-reports/server/routes/lib/createReportDefinition.ts +++ b/dashboards-reports/server/routes/lib/createReportDefinition.ts @@ -45,9 +45,6 @@ export const createReportDefinition = async ( const reqBody = { reportDefinition: uiToBackendReportDefinition(reportDefinition), }; - console.log('!!') - console.log(reqBody) - console.log(JSON.stringify(reqBody, null, 2)) const opensearchResp = await opensearchReportsClient.callAsCurrentUser( 'opensearch_reports.createReportDefinition', { diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportDefinitionActions.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportDefinitionActions.kt index 980c31d6..8a4f9ac1 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportDefinitionActions.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportDefinitionActions.kt @@ -73,8 +73,6 @@ internal object ReportDefinitionActions { val docId = ReportDefinitionsIndex.createReportDefinition(reportDefinitionDetails) docId ?: throw OpenSearchStatusException("Report Definition Creation failed", RestStatus.INTERNAL_SERVER_ERROR) - if (request.reportDefinition.delivery != null) - NotificationsActions.send(request.reportDefinition.delivery, docId) return CreateReportDefinitionResponse(docId) } From ca0e1d948a20409e150a3d8c48e734f55a5bb0e1 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Fri, 16 Jul 2021 15:40:02 -0700 Subject: [PATCH 05/14] Move notifications actions into separate package Signed-off-by: Joshua Li --- .../ReportsSchedulerPlugin.kt | 46 +++++++++++++++---- .../action/ReportInstanceActions.kt | 1 + .../NotificationsActions.kt | 7 +-- .../ReportDefinitionRestHandler.kt | 1 - .../scheduler/ReportDefinitionJobRunner.kt | 8 ++-- 5 files changed, 44 insertions(+), 19 deletions(-) rename reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/{action => notifications}/NotificationsActions.kt (91%) diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/ReportsSchedulerPlugin.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/ReportsSchedulerPlugin.kt index c1f4033d..3179d348 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/ReportsSchedulerPlugin.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/ReportsSchedulerPlugin.kt @@ -26,6 +26,7 @@ */ package org.opensearch.reportsscheduler +import org.opensearch.OpenSearchStatusException import org.opensearch.jobscheduler.spi.JobSchedulerExtension import org.opensearch.jobscheduler.spi.ScheduledJobParser import org.opensearch.jobscheduler.spi.ScheduledJobRunner @@ -73,10 +74,11 @@ import org.opensearch.env.Environment import org.opensearch.env.NodeEnvironment import org.opensearch.plugins.ActionPlugin import org.opensearch.plugins.Plugin -import org.opensearch.reportsscheduler.action.NotificationsActions +import org.opensearch.reportsscheduler.notifications.NotificationsActions import org.opensearch.repositories.RepositoriesService import org.opensearch.rest.RestController import org.opensearch.rest.RestHandler +import org.opensearch.rest.RestStatus import org.opensearch.script.ScriptService import org.opensearch.threadpool.ThreadPool import org.opensearch.watcher.ResourceWatcherService @@ -124,7 +126,12 @@ class ReportsSchedulerPlugin : Plugin(), ActionPlugin, JobSchedulerExtension { PluginSettings.addSettingsUpdateConsumer(clusterService) ReportDefinitionsIndex.initialize(client, clusterService) ReportInstancesIndex.initialize(client, clusterService) - NotificationsActions.initialize(client as NodeClient) + (client as? NodeClient)?.let { NotificationsActions.initialize(it) } ?: run { + throw OpenSearchStatusException( + "Unable to cast client to NodeClient for Notifications call", + RestStatus.INTERNAL_SERVER_ERROR + ) + } return emptyList() } @@ -184,17 +191,38 @@ class ReportsSchedulerPlugin : Plugin(), ActionPlugin, JobSchedulerExtension { */ override fun getActions(): List> { return listOf( - ActionPlugin.ActionHandler(CreateReportDefinitionAction.ACTION_TYPE, CreateReportDefinitionAction::class.java), - ActionPlugin.ActionHandler(DeleteReportDefinitionAction.ACTION_TYPE, DeleteReportDefinitionAction::class.java), - ActionPlugin.ActionHandler(GetAllReportDefinitionsAction.ACTION_TYPE, GetAllReportDefinitionsAction::class.java), - ActionPlugin.ActionHandler(GetAllReportInstancesAction.ACTION_TYPE, GetAllReportInstancesAction::class.java), + ActionPlugin.ActionHandler( + CreateReportDefinitionAction.ACTION_TYPE, + CreateReportDefinitionAction::class.java + ), + ActionPlugin.ActionHandler( + DeleteReportDefinitionAction.ACTION_TYPE, + DeleteReportDefinitionAction::class.java + ), + ActionPlugin.ActionHandler( + GetAllReportDefinitionsAction.ACTION_TYPE, + GetAllReportDefinitionsAction::class.java + ), + ActionPlugin.ActionHandler( + GetAllReportInstancesAction.ACTION_TYPE, + GetAllReportInstancesAction::class.java + ), ActionPlugin.ActionHandler(GetReportDefinitionAction.ACTION_TYPE, GetReportDefinitionAction::class.java), ActionPlugin.ActionHandler(GetReportInstanceAction.ACTION_TYPE, GetReportInstanceAction::class.java), - ActionPlugin.ActionHandler(InContextReportCreateAction.ACTION_TYPE, InContextReportCreateAction::class.java), + ActionPlugin.ActionHandler( + InContextReportCreateAction.ACTION_TYPE, + InContextReportCreateAction::class.java + ), ActionPlugin.ActionHandler(OnDemandReportCreateAction.ACTION_TYPE, OnDemandReportCreateAction::class.java), ActionPlugin.ActionHandler(PollReportInstanceAction.ACTION_TYPE, PollReportInstanceAction::class.java), - ActionPlugin.ActionHandler(UpdateReportDefinitionAction.ACTION_TYPE, UpdateReportDefinitionAction::class.java), - ActionPlugin.ActionHandler(UpdateReportInstanceStatusAction.ACTION_TYPE, UpdateReportInstanceStatusAction::class.java) + ActionPlugin.ActionHandler( + UpdateReportDefinitionAction.ACTION_TYPE, + UpdateReportDefinitionAction::class.java + ), + ActionPlugin.ActionHandler( + UpdateReportInstanceStatusAction.ACTION_TYPE, + UpdateReportInstanceStatusAction::class.java + ) ) } } diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportInstanceActions.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportInstanceActions.kt index 4cebea96..7a00b66a 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportInstanceActions.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/ReportInstanceActions.kt @@ -46,6 +46,7 @@ import org.opensearch.reportsscheduler.model.ReportInstance import org.opensearch.reportsscheduler.model.ReportInstance.Status import org.opensearch.reportsscheduler.model.UpdateReportInstanceStatusRequest import org.opensearch.reportsscheduler.model.UpdateReportInstanceStatusResponse +import org.opensearch.reportsscheduler.notifications.NotificationsActions import org.opensearch.reportsscheduler.security.UserAccessManager import org.opensearch.reportsscheduler.settings.PluginSettings import org.opensearch.reportsscheduler.util.logger diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/NotificationsActions.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/notifications/NotificationsActions.kt similarity index 91% rename from reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/NotificationsActions.kt rename to reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/notifications/NotificationsActions.kt index 06d52a46..ac2d6618 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/NotificationsActions.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/notifications/NotificationsActions.kt @@ -9,12 +9,10 @@ * GitHub history for details. */ -package org.opensearch.reportsscheduler.action +package org.opensearch.reportsscheduler.notifications import org.opensearch.action.ActionListener -import org.opensearch.client.Client import org.opensearch.client.node.NodeClient -import org.opensearch.cluster.service.ClusterService import org.opensearch.commons.notifications.NotificationsPluginInterface import org.opensearch.commons.notifications.action.SendNotificationResponse import org.opensearch.commons.notifications.model.ChannelMessage @@ -24,7 +22,6 @@ import org.opensearch.commons.notifications.model.SeverityType import org.opensearch.reportsscheduler.ReportsSchedulerPlugin.Companion.LOG_PREFIX import org.opensearch.reportsscheduler.model.CreateReportDefinitionResponse import org.opensearch.reportsscheduler.model.ReportDefinition -import org.opensearch.reportsscheduler.util.SecureIndexClient import org.opensearch.reportsscheduler.util.logger /** @@ -61,7 +58,7 @@ internal object NotificationsActions { } override fun onFailure(p0: java.lang.Exception) { - log.error("$LOG_PREFIX:NotificationsActions-send error:$p0") + log.error("$LOG_PREFIX:NotificationsActions-send Error:$p0") } } ) diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/resthandler/ReportDefinitionRestHandler.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/resthandler/ReportDefinitionRestHandler.kt index 016f6d17..591209cd 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/resthandler/ReportDefinitionRestHandler.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/resthandler/ReportDefinitionRestHandler.kt @@ -41,7 +41,6 @@ import org.opensearch.reportsscheduler.model.RestTag.REPORT_DEFINITION_ID_FIELD import org.opensearch.reportsscheduler.model.UpdateReportDefinitionRequest import org.opensearch.reportsscheduler.util.contentParserNextToken import org.opensearch.client.node.NodeClient -import org.opensearch.reportsscheduler.action.NotificationsActions import org.opensearch.rest.BaseRestHandler.RestChannelConsumer import org.opensearch.rest.BytesRestResponse import org.opensearch.rest.RestHandler.Route diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/scheduler/ReportDefinitionJobRunner.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/scheduler/ReportDefinitionJobRunner.kt index d27f61c9..23d132cf 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/scheduler/ReportDefinitionJobRunner.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/scheduler/ReportDefinitionJobRunner.kt @@ -27,6 +27,9 @@ package org.opensearch.reportsscheduler.scheduler +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.opensearch.jobscheduler.spi.JobExecutionContext import org.opensearch.jobscheduler.spi.ScheduledJobParameter import org.opensearch.jobscheduler.spi.ScheduledJobRunner @@ -34,11 +37,8 @@ import org.opensearch.reportsscheduler.ReportsSchedulerPlugin.Companion.LOG_PREF import org.opensearch.reportsscheduler.index.ReportInstancesIndex import org.opensearch.reportsscheduler.model.ReportDefinitionDetails import org.opensearch.reportsscheduler.model.ReportInstance +import org.opensearch.reportsscheduler.notifications.NotificationsActions import org.opensearch.reportsscheduler.util.logger -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import org.opensearch.reportsscheduler.action.NotificationsActions import java.time.Instant internal object ReportDefinitionJobRunner : ScheduledJobRunner { From e4655a481618a62cc4ec44c9ab3b47b67b8cc6c3 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Fri, 16 Jul 2021 15:41:26 -0700 Subject: [PATCH 06/14] Revert formatting Signed-off-by: Joshua Li --- .../ReportsSchedulerPlugin.kt | 35 ++++--------------- .../scheduler/ReportDefinitionJobRunner.kt | 8 ++--- 2 files changed, 11 insertions(+), 32 deletions(-) diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/ReportsSchedulerPlugin.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/ReportsSchedulerPlugin.kt index 3179d348..f2d50da9 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/ReportsSchedulerPlugin.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/ReportsSchedulerPlugin.kt @@ -191,38 +191,17 @@ class ReportsSchedulerPlugin : Plugin(), ActionPlugin, JobSchedulerExtension { */ override fun getActions(): List> { return listOf( - ActionPlugin.ActionHandler( - CreateReportDefinitionAction.ACTION_TYPE, - CreateReportDefinitionAction::class.java - ), - ActionPlugin.ActionHandler( - DeleteReportDefinitionAction.ACTION_TYPE, - DeleteReportDefinitionAction::class.java - ), - ActionPlugin.ActionHandler( - GetAllReportDefinitionsAction.ACTION_TYPE, - GetAllReportDefinitionsAction::class.java - ), - ActionPlugin.ActionHandler( - GetAllReportInstancesAction.ACTION_TYPE, - GetAllReportInstancesAction::class.java - ), + ActionPlugin.ActionHandler(CreateReportDefinitionAction.ACTION_TYPE, CreateReportDefinitionAction::class.java), + ActionPlugin.ActionHandler(DeleteReportDefinitionAction.ACTION_TYPE, DeleteReportDefinitionAction::class.java), + ActionPlugin.ActionHandler(GetAllReportDefinitionsAction.ACTION_TYPE, GetAllReportDefinitionsAction::class.java), + ActionPlugin.ActionHandler(GetAllReportInstancesAction.ACTION_TYPE, GetAllReportInstancesAction::class.java), ActionPlugin.ActionHandler(GetReportDefinitionAction.ACTION_TYPE, GetReportDefinitionAction::class.java), ActionPlugin.ActionHandler(GetReportInstanceAction.ACTION_TYPE, GetReportInstanceAction::class.java), - ActionPlugin.ActionHandler( - InContextReportCreateAction.ACTION_TYPE, - InContextReportCreateAction::class.java - ), + ActionPlugin.ActionHandler(InContextReportCreateAction.ACTION_TYPE, InContextReportCreateAction::class.java), ActionPlugin.ActionHandler(OnDemandReportCreateAction.ACTION_TYPE, OnDemandReportCreateAction::class.java), ActionPlugin.ActionHandler(PollReportInstanceAction.ACTION_TYPE, PollReportInstanceAction::class.java), - ActionPlugin.ActionHandler( - UpdateReportDefinitionAction.ACTION_TYPE, - UpdateReportDefinitionAction::class.java - ), - ActionPlugin.ActionHandler( - UpdateReportInstanceStatusAction.ACTION_TYPE, - UpdateReportInstanceStatusAction::class.java - ) + ActionPlugin.ActionHandler(UpdateReportDefinitionAction.ACTION_TYPE, UpdateReportDefinitionAction::class.java), + ActionPlugin.ActionHandler(UpdateReportInstanceStatusAction.ACTION_TYPE, UpdateReportInstanceStatusAction::class.java) ) } } diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/scheduler/ReportDefinitionJobRunner.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/scheduler/ReportDefinitionJobRunner.kt index 23d132cf..d6e74609 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/scheduler/ReportDefinitionJobRunner.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/scheduler/ReportDefinitionJobRunner.kt @@ -27,9 +27,6 @@ package org.opensearch.reportsscheduler.scheduler -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch import org.opensearch.jobscheduler.spi.JobExecutionContext import org.opensearch.jobscheduler.spi.ScheduledJobParameter import org.opensearch.jobscheduler.spi.ScheduledJobRunner @@ -39,6 +36,9 @@ import org.opensearch.reportsscheduler.model.ReportDefinitionDetails import org.opensearch.reportsscheduler.model.ReportInstance import org.opensearch.reportsscheduler.notifications.NotificationsActions import org.opensearch.reportsscheduler.util.logger +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import java.time.Instant internal object ReportDefinitionJobRunner : ScheduledJobRunner { @@ -68,9 +68,9 @@ internal object ReportDefinitionJobRunner : ScheduledJobRunner { if (id == null) { log.warn("$LOG_PREFIX:runJob-job creation failed for $reportInstance") } else { + log.info("$LOG_PREFIX:runJob-created job:$id") if (reportDefinitionDetails.reportDefinition.delivery != null) NotificationsActions.send(reportDefinitionDetails.reportDefinition.delivery, id) - log.info("$LOG_PREFIX:runJob-created job:$id") } } } From aeffad9fae4b9a43480293b7c1e78bfba0bd222c Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Wed, 28 Jul 2021 11:13:08 -0700 Subject: [PATCH 07/14] Remove delivery settings to unblock CI for now Signed-off-by: Joshua Li --- reports-scheduler/build.gradle | 2 +- .../org/opensearch/reportsscheduler/TestHelpers.kt | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/reports-scheduler/build.gradle b/reports-scheduler/build.gradle index f1d457d5..73aba18c 100644 --- a/reports-scheduler/build.gradle +++ b/reports-scheduler/build.gradle @@ -247,7 +247,7 @@ integTest.dependsOn(bundle) integTest.getClusters().forEach{c -> c.plugin(project.getObjects().fileProperty().value(bundle.getArchiveFile()))} testClusters.integTest { - testDistribution = "ARCHIVE" + testDistribution = "INTEG_TEST" // need to install job-scheduler first, need to assemble job-scheduler first plugin(provider(new Callable(){ @Override diff --git a/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/TestHelpers.kt b/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/TestHelpers.kt index dff75aa3..4996b595 100644 --- a/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/TestHelpers.kt +++ b/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/TestHelpers.kt @@ -54,21 +54,13 @@ fun constructReportDefinitionRequest( "origin":"localhost:5601", "id":"id" }, + $trigger "format":{ "duration":"PT1H", "fileFormat":"Pdf", "limit":1000, "header":"optional header", "footer":"optional footer" - }, - $trigger - "delivery":{ - "recipients":["nobody@email.com"], - "deliveryFormat":"LinkOnly", - "title":"title", - "textDescription":"textDescription", - "htmlDescription":"optional htmlDescription", - "configIds":["optional_configIds"] } } } From 3271b580b2d021e5509c28b82d4ec731bcbfad33 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Tue, 10 Aug 2021 16:32:47 -0700 Subject: [PATCH 08/14] Preserve thread context in coroutine Signed-off-by: Joshua Li --- .../action/PluginBaseAction.kt | 58 +++++++++++++++++-- .../notifications/NotificationsActions.kt | 1 + 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/PluginBaseAction.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/PluginBaseAction.kt index cda4fbb9..b1cde0e9 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/PluginBaseAction.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/PluginBaseAction.kt @@ -44,6 +44,7 @@ import org.opensearch.action.support.ActionFilters import org.opensearch.action.support.HandledTransportAction import org.opensearch.client.Client import org.opensearch.common.io.stream.Writeable +import org.opensearch.common.util.concurrent.ThreadContext import org.opensearch.index.IndexNotFoundException import org.opensearch.index.engine.VersionConflictEngineException import org.opensearch.indices.InvalidIndexNameException @@ -73,11 +74,16 @@ abstract class PluginBaseAction ) { - val userStr: String? = client.threadPool().threadContext.getTransient(OPENSEARCH_SECURITY_USER_INFO_THREAD_CONTEXT) + val userStr: String? = + client.threadPool().threadContext.getTransient(OPENSEARCH_SECURITY_USER_INFO_THREAD_CONTEXT) val user: User? = User.parse(userStr) + val storedThreadContext = client.threadPool().threadContext.newStoredContext(false) scope.launch { try { - listener.onResponse(executeRequest(request, user)) + client.threadPool().threadContext.stashContext().use { + storedThreadContext.restore() + listener.onResponse(executeRequest(request, user)) + } } catch (exception: OpenSearchStatusException) { Metrics.REPORT_EXCEPTIONS_ES_STATUS_EXCEPTION.counter.increment() log.warn("$LOG_PREFIX:OpenSearchStatusException: message:${exception.message}") @@ -85,8 +91,12 @@ abstract class PluginBaseAction T.use(block: (T) -> R): R { + var exception: Throwable? = null + try { + return block(this) + } catch (e: Throwable) { + exception = e + throw e + } finally { + closeFinally(exception) + } + } + + /** + * Closes this [AutoCloseable], suppressing possible exception or error thrown by [AutoCloseable.close] function when + * it's being closed due to some other [cause] exception occurred. + * + * The suppressed exception is added to the list of suppressed exceptions of [cause] exception. + */ + @Suppress("TooGenericExceptionCaught") + private fun ThreadContext.StoredContext.closeFinally(cause: Throwable?) = when (cause) { + null -> close() + else -> try { + close() + } catch (closeException: Throwable) { + cause.addSuppressed(closeException) + } + } + } diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/notifications/NotificationsActions.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/notifications/NotificationsActions.kt index ac2d6618..577dd7bd 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/notifications/NotificationsActions.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/notifications/NotificationsActions.kt @@ -55,6 +55,7 @@ internal object NotificationsActions { object : ActionListener { override fun onResponse(p0: SendNotificationResponse) { log.info("$LOG_PREFIX:NotificationsActions-send:${p0.notificationId}") + // TODO need to get listener and return listener.onResponse(p0) } override fun onFailure(p0: java.lang.Exception) { From 53e862a09eb87dda04c8469f7109bc7f2bf82ca2 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Wed, 11 Aug 2021 12:14:19 -0700 Subject: [PATCH 09/14] Catch WarningFailureException to fix integTests for legacy APIs Signed-off-by: Joshua Li --- .../reportsscheduler/PluginRestTestCase.kt | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/PluginRestTestCase.kt b/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/PluginRestTestCase.kt index 596b9657..ae06199d 100644 --- a/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/PluginRestTestCase.kt +++ b/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/PluginRestTestCase.kt @@ -39,12 +39,16 @@ import org.apache.http.impl.client.BasicCredentialsProvider import org.apache.http.impl.nio.client.HttpAsyncClientBuilder import org.apache.http.message.BasicHeader import org.apache.http.ssl.SSLContextBuilder +import org.junit.After +import org.junit.AfterClass +import org.junit.Before import org.opensearch.client.Request import org.opensearch.client.RequestOptions import org.opensearch.client.Response import org.opensearch.client.ResponseException import org.opensearch.client.RestClient import org.opensearch.client.RestClientBuilder +import org.opensearch.client.WarningFailureException import org.opensearch.common.settings.Settings import org.opensearch.common.unit.TimeValue import org.opensearch.common.util.concurrent.ThreadContext @@ -52,15 +56,12 @@ import org.opensearch.common.xcontent.DeprecationHandler import org.opensearch.common.xcontent.NamedXContentRegistry import org.opensearch.common.xcontent.XContentType import org.opensearch.test.rest.OpenSearchRestTestCase -import org.junit.After -import org.junit.AfterClass -import org.junit.Before import java.io.BufferedReader import java.io.IOException import java.io.InputStreamReader +import java.nio.charset.StandardCharsets import java.nio.file.Files import java.nio.file.Path -import java.nio.charset.StandardCharsets import java.security.cert.X509Certificate import javax.management.MBeanServerInvocationHandler import javax.management.ObjectName @@ -184,6 +185,8 @@ abstract class PluginRestTestCase : OpenSearchRestTestCase() { client().performRequest(request) } catch (exception: ResponseException) { exception.response + } catch (exception: WarningFailureException) { + exception.response } if (expectedRestStatus != null) { assertEquals(expectedRestStatus, response.statusLine.statusCode) @@ -275,10 +278,10 @@ abstract class PluginRestTestCase : OpenSearchRestTestCase() { val serverUrl = "service:jmx:rmi:///jndi/rmi://127.0.0.1:7777/jmxrmi" JMXConnectorFactory.connect(JMXServiceURL(serverUrl)).use { connector -> val proxy = MBeanServerInvocationHandler.newProxyInstance( - connector.mBeanServerConnection, - ObjectName("org.jacoco:type=Runtime"), - IProxy::class.java, - false + connector.mBeanServerConnection, + ObjectName("org.jacoco:type=Runtime"), + IProxy::class.java, + false ) proxy.getExecutionData(false)?.let { val path = Path.of("$jacocoBuildPath/integTest.exec") From 14f895996726f0411accd295dc665284f6162dbc Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Wed, 11 Aug 2021 12:14:50 -0700 Subject: [PATCH 10/14] Remove unnecessary blank line Signed-off-by: Joshua Li --- .../org/opensearch/reportsscheduler/action/PluginBaseAction.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/PluginBaseAction.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/PluginBaseAction.kt index b1cde0e9..cb7a9488 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/PluginBaseAction.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/action/PluginBaseAction.kt @@ -174,5 +174,4 @@ abstract class PluginBaseAction Date: Mon, 23 Aug 2021 13:34:41 -0700 Subject: [PATCH 11/14] Change feature type to string Signed-off-by: Joshua Li --- .../notifications/NotificationsActions.kt | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/notifications/NotificationsActions.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/notifications/NotificationsActions.kt index 577dd7bd..1e45205a 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/notifications/NotificationsActions.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/notifications/NotificationsActions.kt @@ -13,11 +13,11 @@ package org.opensearch.reportsscheduler.notifications import org.opensearch.action.ActionListener import org.opensearch.client.node.NodeClient +import org.opensearch.commons.notifications.NotificationConstants.FEATURE_REPORTS import org.opensearch.commons.notifications.NotificationsPluginInterface import org.opensearch.commons.notifications.action.SendNotificationResponse import org.opensearch.commons.notifications.model.ChannelMessage import org.opensearch.commons.notifications.model.EventSource -import org.opensearch.commons.notifications.model.Feature import org.opensearch.commons.notifications.model.SeverityType import org.opensearch.reportsscheduler.ReportsSchedulerPlugin.Companion.LOG_PREFIX import org.opensearch.reportsscheduler.model.CreateReportDefinitionResponse @@ -49,17 +49,16 @@ internal object NotificationsActions { log.info("$LOG_PREFIX:NotificationsActions-send") NotificationsPluginInterface.sendNotification( client, - EventSource(delivery.title, referenceId, Feature.REPORTS, SeverityType.INFO), + EventSource(delivery.title, referenceId, FEATURE_REPORTS, SeverityType.INFO), ChannelMessage(delivery.textDescription, delivery.htmlDescription, null), delivery.configIds, object : ActionListener { - override fun onResponse(p0: SendNotificationResponse) { - log.info("$LOG_PREFIX:NotificationsActions-send:${p0.notificationId}") - // TODO need to get listener and return listener.onResponse(p0) + override fun onResponse(sendNotificationResponse: SendNotificationResponse) { + log.info("$LOG_PREFIX:NotificationsActions-send:$sendNotificationResponse") } - override fun onFailure(p0: java.lang.Exception) { - log.error("$LOG_PREFIX:NotificationsActions-send Error:$p0") + override fun onFailure(exception: Exception) { + log.error("$LOG_PREFIX:NotificationsActions-send Error:$exception") } } ) From 22aa2db2c34f1661adcc9f2149822522eafd9dc8 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Thu, 26 Aug 2021 11:40:54 -0700 Subject: [PATCH 12/14] Add integTest with notifications Signed-off-by: Joshua Li --- reports-scheduler/build.gradle | 3 + .../reportsscheduler/TestHelpers.kt | 4 +- .../rest/ReportWithNotificationIT.kt | 98 +++++++++++++++++++ 3 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/rest/ReportWithNotificationIT.kt diff --git a/reports-scheduler/build.gradle b/reports-scheduler/build.gradle index 84023b4d..291ea9f7 100644 --- a/reports-scheduler/build.gradle +++ b/reports-scheduler/build.gradle @@ -239,6 +239,9 @@ integTest { if (System.getProperty("tests.clustername") != null) { exclude 'org/opensearch/reportsscheduler/ReportsSchedulerPluginIT.class' + } else { + // assuming that opensearch-notifications will be installed when running integTest against a remote cluster + exclude 'org/opensearch/reportsscheduler/rest/ReportWithNotificationIT.class' } } diff --git a/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/TestHelpers.kt b/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/TestHelpers.kt index 4996b595..0b3dd43a 100644 --- a/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/TestHelpers.kt +++ b/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/TestHelpers.kt @@ -41,7 +41,8 @@ fun constructReportDefinitionRequest( "triggerType":"OnDemand" }, """.trimIndent(), - name: String = "report_definition" + name: String = "report_definition", + delivery: String = "" ): String { return """ { @@ -55,6 +56,7 @@ fun constructReportDefinitionRequest( "id":"id" }, $trigger + $delivery "format":{ "duration":"PT1H", "fileFormat":"Pdf", diff --git a/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/rest/ReportWithNotificationIT.kt b/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/rest/ReportWithNotificationIT.kt new file mode 100644 index 00000000..63919fa3 --- /dev/null +++ b/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/rest/ReportWithNotificationIT.kt @@ -0,0 +1,98 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + * Modifications Copyright OpenSearch Contributors. See + * GitHub history for details. + */ + +package org.opensearch.reportsscheduler.rest + +import org.junit.Assert +import org.opensearch.reportsscheduler.PluginRestTestCase +import org.opensearch.reportsscheduler.ReportsSchedulerPlugin.Companion.BASE_REPORTS_URI +import org.opensearch.reportsscheduler.constructReportDefinitionRequest +import org.opensearch.reportsscheduler.jsonify +import org.opensearch.rest.RestRequest +import org.opensearch.rest.RestStatus + +class ReportWithNotificationIT : PluginRestTestCase() { + fun `test create on-demand report with notifications configured`() { + val notificationsConfigRequest = """ + { + "config": { + "name": "Test channel", + "description": "Dummy channel for reports and notifications integration testing.", + "config_type": "slack", + "feature_list": ["reports"], + "is_enabled": true, + "slack": { + "url": "https://test-webhook" + } + } + } + """.trimIndent() + val notificationsConfigResponse = executeRequest( + RestRequest.Method.POST.name, + "_plugins/_notifications/configs", + notificationsConfigRequest, + RestStatus.OK.status + ) + val notificationsConfigId = notificationsConfigResponse.get("config_id").asString + Assert.assertNotNull("notificationsConfigId should be generated", notificationsConfigId) + val trigger = """ + "trigger":{ + "triggerType":"OnDemand" + }, + """.trimIndent() + val delivery = """ + "delivery":{ + "title":"title", + "textDescription":"textDescription", + "htmlDescription":"optional htmlDescription", + "configIds":["optional_configIds"] + }, + """.trimIndent() + val reportDefinitionRequest = constructReportDefinitionRequest(trigger, "report_definition", delivery) + val reportDefinitionResponse = executeRequest( + RestRequest.Method.POST.name, + "$BASE_REPORTS_URI/definition", + reportDefinitionRequest, + RestStatus.OK.status + ) + val reportDefinitionId = reportDefinitionResponse.get("reportDefinitionId").asString + Assert.assertNotNull("reportDefinitionId should be generated", reportDefinitionId) + Thread.sleep(100) + val onDemandResponse = executeRequest( + RestRequest.Method.POST.name, + "$BASE_REPORTS_URI/on_demand/$reportDefinitionId", + "{}", + RestStatus.OK.status + ) + Assert.assertNotNull("reportInstance should be generated", onDemandResponse) + val reportInstance = onDemandResponse.get("reportInstance").asJsonObject + val reportDefinitionDetails = reportInstance.get("reportDefinitionDetails").asJsonObject + val reportDefinition = reportDefinitionDetails.get("reportDefinition").asJsonObject + Assert.assertEquals(reportDefinitionId, reportDefinitionDetails.get("id").asString) + Assert.assertEquals(jsonify(reportDefinitionRequest).get("reportDefinition").asJsonObject, reportDefinition) + Thread.sleep(2000) + val notificationEventResponse = executeRequest( + RestRequest.Method.GET.name, + "_plugins/_notifications/events", + "", + RestStatus.OK.status + ) + println(notificationEventResponse) + Assert.assertEquals(1, notificationEventResponse.get("total_hits").asInt) + val notificationsStatusList = notificationEventResponse.getAsJsonArray("event_list").get(0).asJsonObject + .getAsJsonObject("event").getAsJsonArray("status_list").get(0).asJsonObject + Assert.assertEquals(notificationsConfigId, notificationsStatusList.get("config_id").asString) + Assert.assertEquals( + "500", + notificationsStatusList.get("delivery_status").asJsonObject.get("status_code").asString + ) + } +} From 5871859e692f724826b9597fb1bcff5ada3bf238 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Mon, 27 Sep 2021 10:53:26 -0700 Subject: [PATCH 13/14] Remove println Signed-off-by: Joshua Li --- .../opensearch/reportsscheduler/rest/ReportWithNotificationIT.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/rest/ReportWithNotificationIT.kt b/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/rest/ReportWithNotificationIT.kt index 63919fa3..2f84e739 100644 --- a/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/rest/ReportWithNotificationIT.kt +++ b/reports-scheduler/src/test/kotlin/org/opensearch/reportsscheduler/rest/ReportWithNotificationIT.kt @@ -85,7 +85,6 @@ class ReportWithNotificationIT : PluginRestTestCase() { "", RestStatus.OK.status ) - println(notificationEventResponse) Assert.assertEquals(1, notificationEventResponse.get("total_hits").asInt) val notificationsStatusList = notificationEventResponse.getAsJsonArray("event_list").get(0).asJsonObject .getAsJsonObject("event").getAsJsonArray("status_list").get(0).asJsonObject From 1c3056718193d67014728ca53e9f7dcd4d251474 Mon Sep 17 00:00:00 2001 From: Joshua Li Date: Tue, 28 Sep 2021 15:56:03 -0700 Subject: [PATCH 14/14] Add user context for background jobs Signed-off-by: Joshua Li --- .../notifications/NotificationsActions.kt | 79 ++++++++++++++++++- .../scheduler/ReportDefinitionJobRunner.kt | 14 ++-- .../security/UserAccessManager.kt | 25 +++++- 3 files changed, 107 insertions(+), 11 deletions(-) diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/notifications/NotificationsActions.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/notifications/NotificationsActions.kt index 1e45205a..bb9bbe86 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/notifications/NotificationsActions.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/notifications/NotificationsActions.kt @@ -13,6 +13,8 @@ package org.opensearch.reportsscheduler.notifications import org.opensearch.action.ActionListener import org.opensearch.client.node.NodeClient +import org.opensearch.common.util.concurrent.ThreadContext +import org.opensearch.commons.ConfigConstants import org.opensearch.commons.notifications.NotificationConstants.FEATURE_REPORTS import org.opensearch.commons.notifications.NotificationsPluginInterface import org.opensearch.commons.notifications.action.SendNotificationResponse @@ -43,17 +45,50 @@ internal object NotificationsActions { /** * Send notifications based on delivery parameter * @param delivery [ReportDefinition.Delivery] object + * @param referenceId [String] object * @return [CreateReportDefinitionResponse] */ - fun send(delivery: ReportDefinition.Delivery, referenceId: String) { + fun send(delivery: ReportDefinition.Delivery, referenceId: String): SendNotificationResponse? { + return send(delivery, referenceId, "") + } + + /** + * Send notifications based on delivery parameter + * @param delivery [ReportDefinition.Delivery] object + * @param referenceId [String] object + * @param userStr [String] object, + * @return [CreateReportDefinitionResponse] + */ + fun send(delivery: ReportDefinition.Delivery, referenceId: String, userStr: String?): SendNotificationResponse? { + if (userStr.isNullOrEmpty()) { + return sendNotificationHelper(delivery, referenceId) + } + + var sendNotificationResponse: SendNotificationResponse? = null + client.threadPool().threadContext.stashContext().use { + client.threadPool().threadContext.putTransient( + ConfigConstants.OPENSEARCH_SECURITY_USER_INFO_THREAD_CONTEXT, + userStr + ) + sendNotificationResponse = sendNotificationHelper(delivery, referenceId) + } + return sendNotificationResponse + } + + private fun sendNotificationHelper( + delivery: ReportDefinition.Delivery, + referenceId: String + ): SendNotificationResponse? { log.info("$LOG_PREFIX:NotificationsActions-send") + var sendNotificationResponse: SendNotificationResponse? = null NotificationsPluginInterface.sendNotification( client, EventSource(delivery.title, referenceId, FEATURE_REPORTS, SeverityType.INFO), ChannelMessage(delivery.textDescription, delivery.htmlDescription, null), delivery.configIds, object : ActionListener { - override fun onResponse(sendNotificationResponse: SendNotificationResponse) { + override fun onResponse(response: SendNotificationResponse) { + sendNotificationResponse = response log.info("$LOG_PREFIX:NotificationsActions-send:$sendNotificationResponse") } @@ -62,5 +97,45 @@ internal object NotificationsActions { } } ) + return sendNotificationResponse + } + + /** + * Executes the given [block] function on this resource and then closes it down correctly whether an exception + * is thrown or not. + * + * In case if the resource is being closed due to an exception occurred in [block], and the closing also fails with an exception, + * the latter is added to the [suppressed][java.lang.Throwable.addSuppressed] exceptions of the former. + * + * @param block a function to process this [AutoCloseable] resource. + * @return the result of [block] function invoked on this resource. + */ + @Suppress("TooGenericExceptionCaught") + private inline fun T.use(block: (T) -> R): R { + var exception: Throwable? = null + try { + return block(this) + } catch (e: Throwable) { + exception = e + throw e + } finally { + closeFinally(exception) + } + } + + /** + * Closes this [AutoCloseable], suppressing possible exception or error thrown by [AutoCloseable.close] function when + * it's being closed due to some other [cause] exception occurred. + * + * The suppressed exception is added to the list of suppressed exceptions of [cause] exception. + */ + @Suppress("TooGenericExceptionCaught") + private fun ThreadContext.StoredContext.closeFinally(cause: Throwable?) = when (cause) { + null -> close() + else -> try { + close() + } catch (closeException: Throwable) { + cause.addSuppressed(closeException) + } } } diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/scheduler/ReportDefinitionJobRunner.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/scheduler/ReportDefinitionJobRunner.kt index d6e74609..fb767f7b 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/scheduler/ReportDefinitionJobRunner.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/scheduler/ReportDefinitionJobRunner.kt @@ -27,6 +27,9 @@ package org.opensearch.reportsscheduler.scheduler +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.opensearch.jobscheduler.spi.JobExecutionContext import org.opensearch.jobscheduler.spi.ScheduledJobParameter import org.opensearch.jobscheduler.spi.ScheduledJobRunner @@ -35,10 +38,8 @@ import org.opensearch.reportsscheduler.index.ReportInstancesIndex import org.opensearch.reportsscheduler.model.ReportDefinitionDetails import org.opensearch.reportsscheduler.model.ReportInstance import org.opensearch.reportsscheduler.notifications.NotificationsActions +import org.opensearch.reportsscheduler.security.UserAccessManager import org.opensearch.reportsscheduler.util.logger -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch import java.time.Instant internal object ReportDefinitionJobRunner : ScheduledJobRunner { @@ -69,8 +70,11 @@ internal object ReportDefinitionJobRunner : ScheduledJobRunner { log.warn("$LOG_PREFIX:runJob-job creation failed for $reportInstance") } else { log.info("$LOG_PREFIX:runJob-created job:$id") - if (reportDefinitionDetails.reportDefinition.delivery != null) - NotificationsActions.send(reportDefinitionDetails.reportDefinition.delivery, id) + if (reportDefinitionDetails.reportDefinition.delivery != null) { + val user = UserAccessManager.getUserFromAccess(job.access) + val userStr = user?.let { it.toString() } ?: "" + NotificationsActions.send(reportDefinitionDetails.reportDefinition.delivery, id, userStr) + } } } } diff --git a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/security/UserAccessManager.kt b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/security/UserAccessManager.kt index f2059c38..27f54b2a 100644 --- a/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/security/UserAccessManager.kt +++ b/reports-scheduler/src/main/kotlin/org/opensearch/reportsscheduler/security/UserAccessManager.kt @@ -57,15 +57,19 @@ internal object UserAccessManager { fun validateUser(user: User?) { if (isUserPrivateTenant(user) && user?.name == null) { Metrics.REPORT_PERMISSION_USER_ERROR.counter.increment() - throw OpenSearchStatusException("User name not provided for private tenant access", - RestStatus.FORBIDDEN) + throw OpenSearchStatusException( + "User name not provided for private tenant access", + RestStatus.FORBIDDEN + ) } if (PluginSettings.isRbacEnabled()) { // backend roles must be present if (user?.backendRoles.isNullOrEmpty()) { Metrics.REPORT_PERMISSION_USER_ERROR.counter.increment() - throw OpenSearchStatusException("User doesn't have backend roles configured. Contact administrator.", - RestStatus.FORBIDDEN) + throw OpenSearchStatusException( + "User doesn't have backend roles configured. Contact administrator.", + RestStatus.FORBIDDEN + ) } } } @@ -96,6 +100,19 @@ internal object UserAccessManager { return retList } + /** + * Get user object from all user access info. + */ + fun getUserFromAccess(access: List): User? { + if (access.isNullOrEmpty()) { + return null + } + val name = access.find { it.startsWith(USER_TAG) }?.substring(USER_TAG.length) + val backendRoles = access.filter { it.startsWith(ROLE_TAG) }.map { it.substring(ROLE_TAG.length) } + val roles = access.filter { it.startsWith(BACKEND_ROLE_TAG) }.map { it.substring(BACKEND_ROLE_TAG.length) } + return User(name, backendRoles, roles, listOf()) + } + /** * Get access info for search filtering */