Package com.morpheusdata.core.providers
Interface ReportProvider
- All Superinterfaces:
PluginProvider
,UIExtensionProvider
- All Known Subinterfaces:
ReportProvider
- All Known Implementing Classes:
AbstractReportProvider
Provides an interface and standard set of methods for creating custom report types within Morpheus. The report engine
typically leverages a concept of a defined
ReportType
and its associated OptionType
filters
as well as a means to process a report and subsequently render the results in a nice view format.
A custom report has 2 parts. One is the method for processing/generating the report. This takes an input of a ReportResult
for details as to the users configured filters as well as
where the result rows should be stored. The process method should send data back as result rows grouped by section. These sections can be header,footer,main or custom.
But be aware, only the main section is used when automatically providing csv export functionality.
Example Process (Groovy Code):
void process(ReportResult reportResult) {
morpheus.report.updateReportResultStatus(reportResult,ReportResult.Status.generating).blockingGet();
Long displayOrder = 0
List<GroovyRowResult> results = []
Connection dbConnection
try {
dbConnection = morpheus.report.getReadOnlyDatabaseConnection().blockingGet()
if(reportResult.configMap?.phrase) {
String phraseMatch = "${reportResult.configMap?.phrase}%"
results = new Sql(dbConnection).rows("SELECT id,name,status from instance WHERE name LIKE ${phraseMatch} order by name asc;")
} else {
results = new Sql(dbConnection).rows("SELECT id,name,status from instance order by name asc;")
}
} finally {
morpheus.report.releaseDatabaseConnection(dbConnection)
}
log.info("Results: ${results}")
Observable<GroovyRowResult> observable = Observable.fromIterable(results) as Observable<GroovyRowResult>
observable.map{ resultRow ->
log.info("Mapping resultRow ${resultRow}")
Map<String,Object> data = [name: resultRow.name, id: resultRow.id, status: resultRow.status]
ReportResultRow resultRowRecord = new ReportResultRow(section: ReportResultRow.SECTION_MAIN, displayOrder: displayOrder++, dataMap: data)
log.info("resultRowRecord: ${resultRowRecord.dump()}")
return resultRowRecord
}.buffer(50).doOnComplete {
morpheus.report.updateReportResultStatus(reportResult,ReportResult.Status.ready).blockingGet();
}.doOnError { Throwable t ->
morpheus.report.updateReportResultStatus(reportResult,ReportResult.Status.failed).blockingGet();
}.subscribe {resultRows ->
morpheus.report.appendResultRows(reportResult,resultRows).blockingGet()
}
}
The second part of the report is the rendering/visual aspect. This is done via the renderTemplate(ReportResult, Map)
method.
This contains a reference to the originating report result as well as the rows grouped by section.
- Since:
- 0.15.2
-
Method Summary
Modifier and TypeMethodDescriptionGets the category string for the report.A short description of the report for the user to better understand its purpose.Some reports can only be run by the master tenant for security reasons.Only the owner of the report result can view the results.Detects whether or not this report is scopable to all cloud types or not TODO: Implement this for custom reports (NOT YET USABLE)void
process
(ReportResult reportResult) The primary entrypoint for generating a report.renderTemplate
(ReportResult reportResult, Map<String, List<ReportResultRow>> reportRowsBySection) Presents the HTML Rendered output of a report.validateOptions
(Map opts) Methods inherited from interface com.morpheusdata.core.providers.PluginProvider
getCode, getMorpheus, getName, getPlugin, isPlugin
Methods inherited from interface com.morpheusdata.core.providers.UIExtensionProvider
getContentSecurityPolicy, getRenderer
-
Method Details
-
validateOptions
-
process
The primary entrypoint for generating a report. This method can be a long running process that queries data in the database or from another external source and generatesReportResultRow
objects that can be pushed into the databaseExample:
void process(ReportResult reportResult) { morpheus.report.updateReportResultStatus(reportResult,ReportResult.Status.generating).blockingGet(); Long displayOrder = 0 List<GroovyRowResult> results = [] Connection dbConnection try { dbConnection = morpheus.report.getReadOnlyDatabaseConnection().blockingGet() if(reportResult.configMap?.phrase) { String phraseMatch = "${reportResult.configMap?.phrase}%" results = new Sql(dbConnection).rows("SELECT id,name,status from instance WHERE name LIKE ${phraseMatch} order by name asc;") } else { results = new Sql(dbConnection).rows("SELECT id,name,status from instance order by name asc;") } } finally { morpheus.report.releaseDatabaseConnection(dbConnection) } log.info("Results: ${results}") Observable<GroovyRowResult> observable = Observable.fromIterable(results) as Observable<GroovyRowResult> observable.map{ resultRow -> log.info("Mapping resultRow ${resultRow}") Map<String,Object> data = [name: resultRow.name, id: resultRow.id, status: resultRow.status] ReportResultRow resultRowRecord = new ReportResultRow(section: ReportResultRow.SECTION_MAIN, displayOrder: displayOrder++, dataMap: data) log.info("resultRowRecord: ${resultRowRecord.dump()}") return resultRowRecord }.buffer(50).doOnComplete { morpheus.report.updateReportResultStatus(reportResult,ReportResult.Status.ready).blockingGet(); }.doOnError { Throwable t -> morpheus.report.updateReportResultStatus(reportResult,ReportResult.Status.failed).blockingGet(); }.subscribe {resultRows -> morpheus.report.appendResultRows(reportResult,resultRows).blockingGet() } }
- Parameters:
reportResult
- the Report result the data is being attached to. Status of the run is updated here, also this object contains filter parameters that may have been applied based on thegetOptionTypes()
-
getDescription
String getDescription()A short description of the report for the user to better understand its purpose.- Returns:
- the description string
-
getCategory
String getCategory()Gets the category string for the report. Reports can be organized by category when viewing.- Returns:
- the category string (i.e. inventory)
-
getOwnerOnly
Boolean getOwnerOnly()Only the owner of the report result can view the results.- Returns:
- whether this report type can be read by the owning user only or not
-
getMasterOnly
Boolean getMasterOnly()Some reports can only be run by the master tenant for security reasons. This informs Morpheus that the report type is a master tenant only report.- Returns:
- whether or not this report is for the master tenant only.
-
getSupportsAllZoneTypes
Boolean getSupportsAllZoneTypes()Detects whether or not this report is scopable to all cloud types or not TODO: Implement this for custom reports (NOT YET USABLE)- Returns:
- whether or not the report is supported by all cloud types. This allows for cloud type specific reports
-
getOptionTypes
List<OptionType> getOptionTypes() -
renderTemplate
HTMLResponse renderTemplate(ReportResult reportResult, Map<String, List<ReportResultRow>> reportRowsBySection) Presents the HTML Rendered output of a report. This can use differentRenderer
implementations. The preferred is to use server side handlebars rendering withHandlebarsRenderer
Example Render:
ViewModel model = new ViewModel() model.object = reportRowsBySection getRenderer().renderTemplate("hbs/instanceReport", model)
- Parameters:
reportResult
- the results of a reportreportRowsBySection
- the individual row results by section (i.e. header, vs. data)- Returns:
- result of rendering an template
-