import { i18n } from '@kbn/i18n' ; import moment from 'moment' ; import { stringify } from 'query-string' ; import rison from 'rison-node' ; import type { HttpFetchQuery } from 'src/core/public' ; import { HttpSetup , IUiSettingsClient } from 'src/core/public' ; import { buildKibanaPath } from '../../../common/build_kibana_path' ; import { API_BASE_GENERATE , API_BASE_URL , API_GENERATE_IMMEDIATE , API_LIST_URL , API_MIGRATE_ILM_POLICY_URL , getRedirectAppPath , REPORTING_MANAGEMENT_HOME , } from '../../../common/constants' ; import { BaseParams , DownloadReportFn , JobId , ManagementLinkFn , ReportApiJSON , } from '../../../common/types' ; import { add } from '../../notifier/job_completion_notifications' ; import { Job } from '../job' ; type AppParams = Omit < BaseParams , 'browserTimezone' | 'version' > ; export interface DiagnoseResponse { help : string [ ] ; success : boolean ; logs : string ; } interface IReportingAPI { getReportURL ( jobId ) : string ; getReportingJobPath < T > ( exportType , jobParams ) : string ; createReportingJob < T > ( exportType , jobParams ) : Promise < Job > ; getServerBasePath ( ) : string ; downloadReport ( jobId ) : void ; deleteReport ( jobId ) : Promise < void > ; list ( page , jobIds ) : Promise < Job [ ] > ; total ( ) : Promise < number > ; getError ( jobId ) : Promise < string > ; getInfo ( jobId ) : Promise < Job > ; findForJobIds ( jobIds ) : Promise < Job [ ] > ; getManagementLink : ManagementLinkFn ; getDownloadLink : DownloadReportFn ; verifyBrowser ( ) : Promise < DiagnoseResponse > ; verifyScreenCapture ( ) : Promise < DiagnoseResponse > ; } implements IReportingAPI internal export class ReportingAPIClient implements IReportingAPI { private http : HttpSetup ; constructor ( http , private uiSettings , private kibanaVersion ) { this . http = http ; } public getKibanaAppHref ( job ) { const searchParams = stringify ( { jobId : job . id } ) ; const path = buildKibanaPath ( { basePath : this . http . basePath . serverBasePath , spaceId : job . spaceId , appPath : getRedirectAppPath ( ) , } ) ; const href = `${ path }?${ searchParams }` ; return href ; } public getReportURL ( jobId ) { const apiBaseUrl = this . http . basePath . prepend ( API_LIST_URL ) ; const downloadLink = `${ apiBaseUrl }/download/${ jobId }` ; return downloadLink ; } public downloadReport ( jobId ) { const location = this . getReportURL ( jobId ) ; window . open ( location ) ; } public async deleteReport ( jobId ) { return await this . http . delete < void > ( `${ API_LIST_URL }/delete/${ jobId }` , { asSystemRequest : true , } ) ; } public async list ( page = 0 , jobIds = [ ] ) { const query = { page } ; if ( jobIds . length > 0 ) { query . ids = jobIds . slice ( 0 , 10 ) . join ( ',' ) ; } const jobQueueEntries = await this . http . get ( `${ API_LIST_URL }/list` , { query , asSystemRequest : true , } ) ; return jobQueueEntries . map ( ( report ) => new Job ( report ) ) ; } public async total ( ) { return await this . http . get < number > ( `${ API_LIST_URL }/count` , { asSystemRequest : true , } ) ; } public async getError ( jobId ) { const job = await this . getInfo ( jobId ) ; if ( job . warnings ?. [ 0 ] ) { return job . warnings [ 0 ] ; } return i18n . translate ( 'xpack.reporting.apiClient.unknownError' , { defaultMessage : `Report job {job} failed. Error unknown.` , values : { job : jobId } , } ) ; } public async getInfo ( jobId ) { const report = await this . http . get ( `${ API_LIST_URL }/info/${ jobId }` , { asSystemRequest : true , } ) ; return new Job ( report ) ; } public async findForJobIds ( jobIds ) { const reports = await this . http . fetch ( `${ API_LIST_URL }/list` , { query : { page : 0 , ids : jobIds . join ( ',' ) } , method : 'GET' , } ) ; return reports . map ( ( report ) => new Job ( report ) ) ; } public getReportingJobPath ( exportType , jobParams ) { const params = stringify ( { jobParams : rison . encode ( jobParams ) , } ) ; return `${ this . http . basePath . prepend ( API_BASE_GENERATE ) }/${ exportType }?${ params }` ; } public async createReportingJob ( exportType , jobParams ) { const jobParamsRison = rison . encode ( jobParams ) ; const resp = await this . http . post ( `${ API_BASE_GENERATE }/${ exportType }` , { method : 'POST' , body : JSON . stringify ( { jobParams : jobParamsRison , } ) , } ) ; add ( resp . job . id ) ; return new Job ( resp . job ) ; } public async createImmediateReport ( baseParams ) { const { objectType : _objectType , ... params } = baseParams ; return this . http . post ( `${ API_GENERATE_IMMEDIATE }` , { body : JSON . stringify ( params ) } ) ; } public getDecoratedJobParams < T extends AppParams > ( baseParams ) { const browserTimezone = this . uiSettings . get ( 'dateFormat:tz' ) === 'Browser' ? moment . tz . guess ( ) : this . uiSettings . get ( 'dateFormat:tz' ) ; return { browserTimezone , version : this . kibanaVersion , ... baseParams , } ; } public getManagementLink : ManagementLinkFn = ( ) => this . http . basePath . prepend ( REPORTING_MANAGEMENT_HOME ) ; public getDownloadLink : DownloadReportFn = ( jobId ) => this . http . basePath . prepend ( `${ API_LIST_URL }/download/${ jobId }` ) ; public getServerBasePath = ( ) => this . http . basePath . serverBasePath ; public verifyBrowser ( ) { return this . http . post < DiagnoseResponse > ( `${ API_BASE_URL }/diagnose/browser` , { asSystemRequest : true , } ) ; } public verifyScreenCapture ( ) { return this . http . post < DiagnoseResponse > ( `${ API_BASE_URL }/diagnose/screenshot` , { asSystemRequest : true , } ) ; } public migrateReportingIndicesIlmPolicy ( ) { return this . http . put ( `${ API_MIGRATE_ILM_POLICY_URL }` ) ; } }