kibana/x-pack/plugins/reporting/server/usage/schema.ts
Tim Sullivan e09ecd048e
[Reporting] New API alternative endpoint for exporting CSV (#149172)
## Summary

This new CSV endpoint will be usable for scripted reporting. As of this
PR, the endpoint is not going to be used in the UI: that will be handled
by [this issue](https://github.com/elastic/kibana/issues/151190). The
new endpoint is not documented yet, but should be once the endpoint is
used in the UI, according to [this
issue](https://github.com/elastic/kibana/issues/151745).

Depends on https://github.com/elastic/kibana/pull/150631
Closes https://github.com/elastic/kibana/issues/148775

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

## Using the endpoint from a script
A request to generate a report has a string of rison-encoded job
parameters. The parameters can now be made into a template for customers
to inject their own savedSearchID. The time range of the search,
filters, and query can also be dynamically filled in at the time of
requesting a report - much more easily than before.

```sh
SAVED_SEARCH_ID="d779c5d0-a1c3-11ed-bd60-6957c24fc275"
 
# Inject the search ID into the "jobParams" template
JOB_PARAMS="(browserTimezone:UTC,locatorParams:!((id:DISCOVER_APP_LOCATOR,params:(savedSearchId:'${SAVED_SEARCH_ID}',timeRange:(from:now-1M,to:now)))),objectType:search)"
 
# Send a request to generate a report
curl -XPOST $ENDPOINT \
  -H "${AUTH_HEADER}" \
  -H 'Content-Type: application/json' \
  -H 'kbn-xsrf: reporting' 
  -d '{ "jobParams": "'$JOB_PARAMS'"}'
```

## Limitations
A locator without a `savedSearchId` is currently not supported. Getting
that support will make it possible to create exports based on content in
Discover tied only to a Data View (unsaved search support).

## (Demo) Developer Example app
_The demo app is descoped from this PR_
~~This PR updates the Reporting example app to feature a "CSV Explorer."
In this app, you can select a saved search, build up a
DiscoverAppLocatorParams object, and send a request to generate a
report.~~


https://user-images.githubusercontent.com/908371/217356050-f556f897-33c6-4623-aa06-9af191378e48.mp4

## Release Note
We are skipping the release note for now, while waiting for
documentation.

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
2023-02-22 12:44:31 -07:00

189 lines
5.6 KiB
TypeScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { MakeSchemaFrom } from '@kbn/usage-collection-plugin/server';
import {
AppCounts,
ExecutionTimes,
AvailableTotal,
ByAppCounts,
JobTypes,
LayoutCounts,
MetricsPercentiles,
MetricsStats,
RangeStats,
ReportingUsageType,
SizePercentiles,
QueueTimes,
} from './types';
const appCountsSchema: MakeSchemaFrom<AppCounts> = {
search: { type: 'long' },
'canvas workpad': { type: 'long' },
dashboard: { type: 'long' },
visualization: { type: 'long' },
};
const executionTimesSchema: MakeSchemaFrom<ExecutionTimes> = {
min: { type: 'long' },
max: { type: 'long' },
avg: { type: 'float' },
};
const queueTimesSchema: MakeSchemaFrom<QueueTimes> = {
min: { type: 'long' },
max: { type: 'long' },
avg: { type: 'float' },
};
const layoutCountsSchema: MakeSchemaFrom<LayoutCounts> = {
canvas: { type: 'long' },
print: { type: 'long' },
preserve_layout: { type: 'long' },
};
const byAppCountsSchema: MakeSchemaFrom<ByAppCounts> = {
csv_searchsource: appCountsSchema,
csv_searchsource_immediate: appCountsSchema,
csv_v2: appCountsSchema,
PNG: appCountsSchema,
PNGV2: appCountsSchema,
printable_pdf: appCountsSchema,
printable_pdf_v2: appCountsSchema,
};
const sizesSchema: MakeSchemaFrom<SizePercentiles> = {
'1.0': { type: 'long' },
'5.0': { type: 'long' },
'25.0': { type: 'long' },
'50.0': { type: 'long' },
'75.0': { type: 'long' },
'95.0': { type: 'long' },
'99.0': { type: 'long' },
};
const metricsPercentilesSchema: MakeSchemaFrom<MetricsPercentiles> = {
'50.0': { type: 'long' },
'75.0': { type: 'long' },
'95.0': { type: 'long' },
'99.0': { type: 'long' },
};
const metricsSchemaCsv: MakeSchemaFrom<Pick<MetricsStats, 'csv_rows'>> = {
csv_rows: metricsPercentilesSchema,
};
const metricsSchemaPng: MakeSchemaFrom<Pick<MetricsStats, 'png_cpu' | 'png_memory'>> = {
png_cpu: metricsPercentilesSchema,
png_memory: metricsPercentilesSchema,
};
const metricsSchemaPdf: MakeSchemaFrom<Pick<MetricsStats, 'pdf_cpu' | 'pdf_memory' | 'pdf_pages'>> =
{
pdf_cpu: metricsPercentilesSchema,
pdf_memory: metricsPercentilesSchema,
pdf_pages: metricsPercentilesSchema,
};
const errorCodesSchemaCsv: MakeSchemaFrom<JobTypes['csv_searchsource']['error_codes']> = {
authentication_expired_error: { type: 'long' },
queue_timeout_error: { type: 'long' },
unknown_error: { type: 'long' },
kibana_shutting_down_error: { type: 'long' },
};
const errorCodesSchemaPng: MakeSchemaFrom<JobTypes['PNGV2']['error_codes']> = {
authentication_expired_error: { type: 'long' },
queue_timeout_error: { type: 'long' },
unknown_error: { type: 'long' },
kibana_shutting_down_error: { type: 'long' },
browser_could_not_launch_error: { type: 'long' },
browser_unexpectedly_closed_error: { type: 'long' },
browser_screenshot_error: { type: 'long' },
visual_reporting_soft_disabled_error: { type: 'long' },
invalid_layout_parameters_error: { type: 'long' },
};
const errorCodesSchemaPdf: MakeSchemaFrom<JobTypes['printable_pdf_v2']['error_codes']> = {
pdf_worker_out_of_memory_error: { type: 'long' },
authentication_expired_error: { type: 'long' },
queue_timeout_error: { type: 'long' },
unknown_error: { type: 'long' },
kibana_shutting_down_error: { type: 'long' },
browser_could_not_launch_error: { type: 'long' },
browser_unexpectedly_closed_error: { type: 'long' },
browser_screenshot_error: { type: 'long' },
visual_reporting_soft_disabled_error: { type: 'long' },
invalid_layout_parameters_error: { type: 'long' },
};
const availableTotalSchema: MakeSchemaFrom<AvailableTotal> = {
available: { type: 'boolean' },
total: { type: 'long' },
deprecated: { type: 'long' },
output_size: sizesSchema,
app: appCountsSchema,
execution_times: executionTimesSchema,
};
const jobTypesSchema: MakeSchemaFrom<JobTypes> = {
csv_searchsource: {
...availableTotalSchema,
metrics: metricsSchemaCsv,
error_codes: errorCodesSchemaCsv,
},
csv_searchsource_immediate: {
...availableTotalSchema,
metrics: metricsSchemaCsv,
error_codes: errorCodesSchemaCsv,
},
csv_v2: {
...availableTotalSchema,
metrics: metricsSchemaCsv,
error_codes: errorCodesSchemaCsv,
},
PNG: { ...availableTotalSchema, metrics: metricsSchemaPng, error_codes: errorCodesSchemaPng },
PNGV2: { ...availableTotalSchema, metrics: metricsSchemaPng, error_codes: errorCodesSchemaPng },
printable_pdf: {
...availableTotalSchema,
layout: layoutCountsSchema,
metrics: metricsSchemaPdf,
error_codes: errorCodesSchemaPdf,
},
printable_pdf_v2: {
...availableTotalSchema,
layout: layoutCountsSchema,
metrics: metricsSchemaPdf,
error_codes: errorCodesSchemaPdf,
},
};
const rangeStatsSchema: MakeSchemaFrom<RangeStats> = {
...jobTypesSchema,
_all: { type: 'long' },
status: {
completed: { type: 'long' },
completed_with_warnings: { type: 'long' },
failed: { type: 'long' },
pending: { type: 'long' },
processing: { type: 'long' },
},
statuses: {
completed: byAppCountsSchema,
completed_with_warnings: byAppCountsSchema,
failed: byAppCountsSchema,
pending: byAppCountsSchema,
processing: byAppCountsSchema,
},
output_size: sizesSchema,
queue_times: queueTimesSchema,
};
export const reportingSchema: MakeSchemaFrom<ReportingUsageType> = {
...rangeStatsSchema,
available: { type: 'boolean' },
enabled: { type: 'boolean' },
last7Days: rangeStatsSchema,
};