Skip to content
This repository has been archived by the owner on Aug 9, 2022. It is now read-only.

Commit

Permalink
ReportDefinition and ReportInstance index operations and REST APIs cr…
Browse files Browse the repository at this point in the history
…eated

Detail:
Created model for REST interface and index
Added index operations
Added index mapping and settings
Added REST APIs for index operations
  • Loading branch information
akbhatta committed Oct 22, 2020
1 parent d869501 commit eb9324b
Show file tree
Hide file tree
Showing 26 changed files with 2,664 additions and 18 deletions.
2 changes: 1 addition & 1 deletion reports-scheduler/build-tools/pkgbuild.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ afterEvaluate {
maintainer 'OpenDistro for Elasticsearch Team <[email protected]>'
url 'https://opendistro.github.io/elasticsearch/downloads'
summary '''
Open Distro for Elasticsearch Notifications.
Open Distro for Elasticsearch Report scheduler.
Reference documentation can be found at https://opendistro.github.io/elasticsearch/docs.
'''.stripIndent().replace('\n', ' ').trim()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ package com.amazon.opendistroforelasticsearch.reportsscheduler
import com.amazon.opendistroforelasticsearch.jobscheduler.spi.JobSchedulerExtension
import com.amazon.opendistroforelasticsearch.jobscheduler.spi.ScheduledJobParser
import com.amazon.opendistroforelasticsearch.jobscheduler.spi.ScheduledJobRunner
import com.amazon.opendistroforelasticsearch.reportsscheduler.index.IndexManager
import com.amazon.opendistroforelasticsearch.reportsscheduler.job.ReportsSchedulerJobRunnerProxy
import com.amazon.opendistroforelasticsearch.reportsscheduler.job.ScheduledReportJobParser
import com.amazon.opendistroforelasticsearch.reportsscheduler.resthandler.OnDemandReportRestHandler
import com.amazon.opendistroforelasticsearch.reportsscheduler.resthandler.ReportDefinitionListRestHandler
import com.amazon.opendistroforelasticsearch.reportsscheduler.resthandler.ReportDefinitionRestHandler
import com.amazon.opendistroforelasticsearch.reportsscheduler.resthandler.ReportInstanceListRestHandler
import com.amazon.opendistroforelasticsearch.reportsscheduler.resthandler.ReportInstanceRestHandler
import com.amazon.opendistroforelasticsearch.reportsscheduler.resthandler.ReportsJobRestHandler
import com.amazon.opendistroforelasticsearch.reportsscheduler.resthandler.ReportsScheduleRestHandler
import com.amazon.opendistroforelasticsearch.reportsscheduler.settings.PluginSettings
Expand Down Expand Up @@ -55,7 +61,9 @@ class ReportsSchedulerPlugin : Plugin(), ActionPlugin, JobSchedulerExtension {

companion object {
const val PLUGIN_NAME = "opendistro-reports-scheduler"
const val LOG_PREFIX = "reports"
const val BASE_SCHEDULER_URI = "/_opendistro/reports_scheduler"
const val BASE_REPORTS_URI = "/_opendistro/_reports"
const val JOB_INDEX_NAME = ".reports_scheduler"
const val JOB_QUEUE_INDEX_NAME = ".reports_scheduler_job_queue"
const val LOCK_DURATION_SECONDS = 300L
Expand Down Expand Up @@ -89,6 +97,7 @@ class ReportsSchedulerPlugin : Plugin(), ActionPlugin, JobSchedulerExtension {
): Collection<Any> {
this.clusterService = clusterService
PluginSettings.addSettingsUpdateConsumer(clusterService)
IndexManager.initialize(client, clusterService)
jobRunner.createRunnerInstance(clusterService, threadPool, client)
return emptyList()
}
Expand Down Expand Up @@ -134,6 +143,11 @@ class ReportsSchedulerPlugin : Plugin(), ActionPlugin, JobSchedulerExtension {
nodesInCluster: Supplier<DiscoveryNodes>
): List<RestHandler> {
return ImmutableList.of<RestHandler>(
ReportDefinitionRestHandler(),
ReportDefinitionListRestHandler(),
ReportInstanceRestHandler(),
ReportInstanceListRestHandler(),
OnDemandReportRestHandler(),
ReportsScheduleRestHandler(),
ReportsJobRestHandler(clusterService)
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/*
* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*
*/

package com.amazon.opendistroforelasticsearch.reportsscheduler.action

import com.amazon.opendistroforelasticsearch.reportsscheduler.ReportsSchedulerPlugin.Companion.LOG_PREFIX
import com.amazon.opendistroforelasticsearch.reportsscheduler.index.IndexManager
import com.amazon.opendistroforelasticsearch.reportsscheduler.model.ReportDefinition
import com.amazon.opendistroforelasticsearch.reportsscheduler.model.ReportDefinitionDetails
import com.amazon.opendistroforelasticsearch.reportsscheduler.resthandler.PluginRestHandler.Companion.ID_FIELD
import com.amazon.opendistroforelasticsearch.reportsscheduler.resthandler.PluginRestHandler.Companion.REPORT_DEFINITION_LIST_FIELD
import com.amazon.opendistroforelasticsearch.reportsscheduler.resthandler.PluginRestHandler.Companion.STATUS_TEXT_FIELD
import com.amazon.opendistroforelasticsearch.reportsscheduler.util.logger
import org.elasticsearch.client.node.NodeClient
import org.elasticsearch.common.xcontent.ToXContent
import org.elasticsearch.common.xcontent.XContentType
import org.elasticsearch.rest.BytesRestResponse
import org.elasticsearch.rest.RestChannel
import org.elasticsearch.rest.RestRequest
import org.elasticsearch.rest.RestStatus
import java.time.Instant

/**
* Report definitions index operation actions.
*/
internal class ReportDefinitionAction(
private val request: RestRequest,
private val client: NodeClient,
private val restChannel: RestChannel
) {

companion object {
private val log by logger(ReportDefinitionAction::class.java)
private const val TEMP_OWNER_ID = "ownerId" // TODO get this from request
}

/**
* Create new ReportDefinition
*/
fun create() {
log.info("$LOG_PREFIX:ReportDefinition-create")
val response = restChannel.newBuilder(XContentType.JSON, false).startObject()
var restStatus = RestStatus.OK // Default to success
val currentTime = Instant.now()
val contentParser = request.contentParser()
contentParser.nextToken()
val reportDefinition = ReportDefinition.parse(contentParser)
val reportDefinitionDetails = ReportDefinitionDetails("ignore",
currentTime,
currentTime,
TEMP_OWNER_ID, // TODO update with actual requester ID
reportDefinition
)
val docId = IndexManager.createReportDefinition(reportDefinitionDetails)
if (docId == null) {
response.field(STATUS_TEXT_FIELD, "Report Definition Creation failed")
restStatus = RestStatus.INTERNAL_SERVER_ERROR
} else {
response.field(ID_FIELD, docId)
}
response.endObject()
restChannel.sendResponse(BytesRestResponse(restStatus, response))
}

/**
* Update ReportDefinition
* @param reportDefinitionId ReportDefinition id
*/
fun update(reportDefinitionId: String) {
log.info("$LOG_PREFIX:ReportDefinition-update $reportDefinitionId")
val response = restChannel.newBuilder(XContentType.JSON, false).startObject()
var restStatus = RestStatus.OK // Default to success
val currentReportDefinitionDetails = IndexManager.getReportDefinition(reportDefinitionId)
if (currentReportDefinitionDetails == null) { // TODO verify actual requester ID
restStatus = RestStatus.NOT_FOUND
response.field(STATUS_TEXT_FIELD, "Report Definition $reportDefinitionId not found")
} else {
val currentTime = Instant.now()
val contentParser = request.contentParser()
contentParser.nextToken()
val reportDefinition = ReportDefinition.parse(contentParser)
val reportDefinitionDetails = ReportDefinitionDetails(reportDefinitionId,
currentTime,
currentReportDefinitionDetails.createdTime,
currentReportDefinitionDetails.ownerId,
reportDefinition
)
val isUpdated = IndexManager.updateReportDefinition(reportDefinitionId, reportDefinitionDetails)
if (isUpdated) {
response.field(ID_FIELD, reportDefinitionId)
} else {
response.field(STATUS_TEXT_FIELD, "Report Definition Update failed")
restStatus = RestStatus.INTERNAL_SERVER_ERROR
}
}
response.endObject()
restChannel.sendResponse(BytesRestResponse(restStatus, response))
}

/**
* Get ReportDefinition info
* @param reportDefinitionId ReportDefinition id
*/
fun info(reportDefinitionId: String) {
log.info("$LOG_PREFIX:ReportDefinition-info $reportDefinitionId")
val response = restChannel.newBuilder(XContentType.JSON, false)
var restStatus = RestStatus.OK // Default to success
val reportDefinitionDetails = IndexManager.getReportDefinition(reportDefinitionId)
if (reportDefinitionDetails == null) { // TODO verify actual requester ID
restStatus = RestStatus.NOT_FOUND
response.startObject()
.field(STATUS_TEXT_FIELD, "Report Definition $reportDefinitionId not found")
.endObject()
} else {
reportDefinitionDetails.toXContent(response, ToXContent.EMPTY_PARAMS, true)
}
restChannel.sendResponse(BytesRestResponse(restStatus, response))
}

/**
* Delete ReportDefinition
* @param reportDefinitionId ReportDefinition id
*/
fun delete(reportDefinitionId: String) {
log.info("$LOG_PREFIX:ReportDefinition-delete $reportDefinitionId")
val response = restChannel.newBuilder(XContentType.JSON, false).startObject()
var restStatus = RestStatus.OK // Default to success
val reportDefinitionDetails = IndexManager.getReportDefinition(reportDefinitionId)
if (reportDefinitionDetails == null) { // TODO verify actual requester ID
restStatus = RestStatus.NOT_FOUND
response.startObject()
.field(STATUS_TEXT_FIELD, "Report Definition $reportDefinitionId not found")
.endObject()
} else {
val isDeleted = IndexManager.deleteReportDefinition(reportDefinitionId)
if (!isDeleted) {
restStatus = RestStatus.REQUEST_TIMEOUT
response.field(STATUS_TEXT_FIELD, "Report Definition $reportDefinitionId delete failed")
} else {
response.field(STATUS_TEXT_FIELD, "Report Definition $reportDefinitionId deleted")
}
}
response.endObject()
restChannel.sendResponse(BytesRestResponse(restStatus, response))
}

/**
* Get all ReportDefinition for current user
*/
fun getAll(from: Int) {
log.info("$LOG_PREFIX:ReportDefinition-getAll")
val response = restChannel.newBuilder(XContentType.JSON, false).startObject()
var restStatus = RestStatus.OK // Default to success
// TODO verify actual requester ID
val reportDefinitionsList = IndexManager.getAllReportDefinitions(TEMP_OWNER_ID, from)
if (reportDefinitionsList.isEmpty()) {
restStatus = RestStatus.NOT_FOUND
response.field(STATUS_TEXT_FIELD, "No Report Definitions found")
} else {
response.startArray(REPORT_DEFINITION_LIST_FIELD)
reportDefinitionsList.forEach { it.toXContent(response, ToXContent.EMPTY_PARAMS, true) }
response.endArray()
}
response.endObject()
restChannel.sendResponse(BytesRestResponse(restStatus, response))
}
}
Loading

0 comments on commit eb9324b

Please sign in to comment.