Skip to content

Commit

Permalink
[Reporting/Docs] Update Developer API docs (#179723)
Browse files Browse the repository at this point in the history
## Summary

Part of documentation updates required for
elastic/kibana-team#720

* Removes outdated info about Angular directives
* Remove outdated info about the original CSV export type
* Add explanation of what an Export Type is
* More detail about the job parameters for each export type
* Add tips to debug using POST URLs
  • Loading branch information
tsullivan authored Apr 1, 2024
1 parent 13dfd58 commit d041955
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 88 deletions.
67 changes: 30 additions & 37 deletions docs/developer/architecture/development/csv-integration.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,43 @@
=== CSV

[float]
==== Job parameters
If integrating with Reporting via a custom UI, the following job parameters must be Rison encoded and posted to
the aforementioned generate job url:
==== Job parameters of CsvSearchSource
The export type to generate CSV reports and is available in Discover uses "search source" objects. This export type is called
`csv_searchsource` in the code. A configuration for a CSV report job is represented with an interface that includes the
`BaseParams` and the following fields. To create a request for a CSV report, these required job parameters are Rison encoded into
a query string variable of the report generation URL:

----
interface jobParameters {
type: string;
title: string;
searchRequest: {
index: string;
body: object;
};
fields: string[];
metaFields: string[];
conflictedTypesFields: string[];
indexPatternId: string;
}
interface JobParamsCSV {
searchSource: SerializedSearchSourceFields; <1>
columns?: string[]; <2>
};
----

The `searchRequest.body` should abide by the {ref}/search-search.html[Elasticsearch Search Request Body] syntax
<1> An object of serialized data that internally represents a search object in Kibana. It will contain a reference to a DataView
saved object.
<2> An array of field names to include as columns in the CSV report.

[float]
==== `export-config` Directive
If integrating with Reporting via the `export-config` directive, the AngularJS controller that contains the directive should expose
the following methods and the `export-config` directive will POST them to the reporting API:
==== Job parameters of CsvFromSavedObject
A newer export type to generate CSV reports is available, currently only by API. This export type is called `csv_v2` in the code.

----
interface sharingData {
searchRequest: {
index: string;
body: object;
};
fields: string[];
metaFields: string[];
conflictedTypesFields: string[];
indexPatternId: string;
}
function getSharingData(): sharingData;
function getSharingType(): string;
interface JobParamsCsvFromSavedObject {
locatorParams: LocatorParams[]; <1>
};
----
<1> The `locatorParams` value is controlled by the Discover application and identifies a search loaded in Discover, including the
selection of DataView, columns and filters. Only a single value in the array is permitted in the `createJob` method.

function getSharingTitle() string;
[float]
==== Job payload
After the job parameters are received by the route handler for the report generation URL, an additional field is automatically
added to the fields from job parameters:

----

The `sharingData.searchRequest.body` should abide by the {ref}/search-search.html[{es} Search Request Body] syntax
interface TaskPayloadCSV {
pagingStrategy: 'scan' | 'pit' <1>
}
----
<1> The `pagingStrategy` value is taken from the value of the `xpack.reporting.csv.scroll.strategy` setting in kibana.yml and used
to control how the `runTask` method pages through all of the data.
61 changes: 49 additions & 12 deletions docs/developer/architecture/development/index.asciidoc
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
[role="xpack"]
[[reporting-integration]]
== Reporting integration
Integrating a {kib} application with the {report-features} requires a minimum
amount of code, and the goal is to not have to modify the reporting code as we
add additional applications. Instead, applications abide by a contract that
{report-features} use to determine the information that is required to export
CSVs and PDFs.
Applications abide by a contract that {report-features} use to determine the information that is required to request exports of
data from {kib}, and how to generate and store the reports.

[IMPORTANT]
==============================================
Expand All @@ -14,16 +11,56 @@ However, these docs will be kept up-to-date to reflect the current implementatio
==============================================

[float]
[[reporting-nav-bar-extensions]]
=== Reporting Export Types
"Export Types" are pieces of code that plug into the {kib} Reporting framework, and are responsible for exporting data on behalf
of a {kib} application. These pieces of code are implemented as TypeScript classes that extend an abstract base class, and
implement methods for controlling the creation of report jobs, and asynchronously generating report contents. Their `createJob`
methods handle requests to create report jobs, by accepting jobParams objects and returning "task payload" objects. Their
`runTask` methods generate the report contents by accepting the task payload object created from the `createJob` function, which
is then stored in a system index in Elasticsearch.

[float]
[[reporting-share-service-registrations]]
=== Share menu extensions
X-Pack uses the `share` plugin of the Kibana platform to register actions in the share menu.
X-Pack services, such as the {report-features}, register with the `share` plugin of the Kibana platform to register additional
actions available to make content shareable.

[float]
=== Generate a report job URL
To generate a new reporting job, different export types require different `jobParams` objects, which are Rison-encoded and used as
a `jobParams` query string variable in the Reporting generation endpoint URL. If you use the aforementioned
<<reporting-share-service-registrations, Sharing plugin registrations>> then this detail will be abstracted away. If your
application does not use the Share menu extensions, you will have to generate the URL and create a POST request to the URL.

[float]
=== Generate job URL
To generate a new reporting job, different export types require different `jobParams` that are Rison encoded into a URL
that abide by the following convention: `/api/reporting/generate?jobParams=${rison.encode(jobParams)}`. If you use the
aforementioned <<reporting-nav-bar-extensions, nav bar extensions>> then this detail will be abstracted away, but if you
provide a custom UI for generating the report, you will have to generate the URL and create a POST request to the URL.
=== Basic job parameters
Certain fields of Reporting job parameters are required for every type of export.

----
interface BaseParams {
title: string; <1>
objectType: string; <2>
browserTimezone: string; <3>
version: string; <4>
};
----
<1> The `title` for the report. This is shown in the listing of reports in **Stack Management > Alerts and
Insights > Reporting** and used as the filename when the report is downloaded.
<2> The `objectType` field is automatically added when using internal Reporting APIs. This value used for choosing an icon for the
report job in the listing of reports in {kib}.
<3> The `browserTimezone` field is automatically added when using internal Reporting APIs to craft the job parameters. This is
used to correctly format time-based data in the user's desired timezone.
<4> The `version` field is automatically added when using internal Reporting APIs. This is used in cases where job parameters are
reused after an upgrade of Kibana, and a migration may be needed.

include::csv-integration.asciidoc[]
include::pdf-integration.asciidoc[]

=== Using POST URLs for debugging
Developers can capture a POST URL from a reporting-capable application to access the `jobParams` query string variable in the
public API report generation endpoint. The query string variable can be passed through a URL de-encoder and then passed through a
Rison-to-JSON converter to make the job parameters human-readable.

If attempting to send requests to the POST URL to test generating a report, use a shell script containing the curl command that
POSTs the request. This will avoid any unintentional character escaping that can happen if running the curl command in an
interactive shell.
74 changes: 35 additions & 39 deletions docs/developer/architecture/development/pdf-integration.asciidoc
Original file line number Diff line number Diff line change
@@ -1,53 +1,47 @@
[float]
=== PDF
=== PDF and PNG

[float]
==== Job parameters
If integrating with Reporting via a custom UI, the following job parameters must be Rison encoded and posted to
the aforementioned generate job url:
A configuration for a PDF or PNG report job is represented with an interface that includes the `BaseParams` and the following
fields. To create a request for one of these report types, these required job parameters are encoded into a query string variable
of the report generation URL:

----
interface jobParameters {
objectType: string;
title: string;
browserTimezone: string;
relativeUrls: string[];
interface BaseParamsPDFV2 {
layout: {
id: string;
id: string; <1>
dimensions: {
height: number;
width: number;
};
};
locatorParams: LocatorParams[]; <2>
}
----

`jobParameters.browserTimezone` is a string that appears in the tz database
`jobParameters.layout.id` presently only accepts "print" and "preserve_layout"
`jobParameters.layout.dimensions` is only currently used by "preserve_layout"

[float]
==== `export-config` directive
If integrating with Reporting via the `export-config` directive, the AngularJS controller that contains
the directive should expose the following methods and the `export-config` directive will POST them to the
reporting API:

----
function getSharingType(): string;
function getSharingTitle(): string;
interface BaseParamsPNGV2 {
layout: {
id: string; <3>
dimensions: {
height: number;
width: number;
};
};
locatorParams: LocatorParams; <4>
}
----

The `export-config` directive will use the browser's current URL and timezone when generating the job
parameters automatically. The `export-config` directive will also grab the height/width of the element
with the `data-shared-items-container` attribute and use this as the dimensions.
<1> The available `layout.id` options for PDF exports are `preserve_layout`, `print`, and `canvas`. These control how dashboard
panels are captured and positioned into pages in the PDF file.
<2> The `locatorParams` value is controlled by the application loaded in the browser for which a screenshot will be captured. The
parameters to generate a PDF report allow an array of `locatorParams` to support multi-page PDF reports.
<3> The only available `layout.id` option for PNG exports is `preserve_layout`.
<4> The parameters to generate a PNG report allow a single value for `locatorParams`.

[float]
==== Screenshot capturing attributes
When generating the PDF, reporting looks for a number of attributes in the DOM to determine which elements
should have their screenshot taken and when the Visualizations are done rendering.
==== How applications make themselves screenshot-capable
When generating the PDF, the headless browser launched by the Reporting export type runs a script that looks for a number of
attributes in the DOM to determine which elements should have their screenshot taken and when the Visualizations are done
rendering.

The print layout takes a screenshot of every element with the `data-shared-item` attribute and includes the
individual screenshots in the PDF. The print layout also uses the `data-title` and `data-description`
Expand All @@ -58,10 +52,12 @@ reporting will resize the element with the `data-shared-items-container` to be t
The preserve layout also uses the `data-title` and `data-description` attributes on the HTMLElement with the
`data-shared-items-container` attribute to specify the title/description for the entire PDF.

Reporting needs to determine when all of the visualizations have completed rendering, so that it can begin taking screenshots.
If there are multiple visualizations, the `data-shared-items-count` attribute should be specified to let Reporting know how
many Visualizations to look for. Reporting will look at every element with the `data-shared-item` attribute and use the corresponding
`data-render-complete` attribute and `renderComplete` events to listen for rendering to complete. When rendering is complete for a visualization
the `data-render-complete` attribute should be set to "true" and it should dispatch a custom DOM `renderComplete` event.
Reporting needs to determine when all of the visualizations have completed rendering, so that it can begin taking screenshots. If
there are multiple visualizations, the `data-shared-items-count` attribute should be specified to let Reporting know how many
Visualizations to look for. Reporting will look at every element with the `data-shared-item` attribute and use the corresponding
`data-render-complete` attribute and `renderComplete` events to listen for rendering to complete. When rendering is complete for a
visualization the `data-render-complete` attribute should be set to "true" and it should dispatch a custom DOM `renderComplete`
event.

If the reporting job uses multiple URLs, before looking for any of the `data-shared-item` or `data-shared-items-count` attributes, it waits for a `data-shared-page` attribute that specifies which page is being loaded.
If the reporting job uses multiple URLs, before looking for any of the `data-shared-item` or `data-shared-items-count` attributes,
it waits for a `data-shared-page` attribute that specifies which page is being loaded.

0 comments on commit d041955

Please sign in to comment.