diff --git a/x-pack/plugins/reporting/public/plugin.tsx b/x-pack/plugins/reporting/public/plugin.tsx index fcaa295a45eccd4..aad3d9b026c6ee8 100644 --- a/x-pack/plugins/reporting/public/plugin.tsx +++ b/x-pack/plugins/reporting/public/plugin.tsx @@ -155,8 +155,6 @@ export class ReportingPublicPlugin implements Plugin { ); } - // FIXME: only perform these actions for authenticated routes - // Depends on https://github.com/elastic/kibana/pull/39477 public start(core: CoreStart) { const { http, notifications } = core; const apiClient = new ReportingAPIClient(http); diff --git a/x-pack/plugins/reporting/server/export_types/common/execute_job/decrypt_job_headers.ts b/x-pack/plugins/reporting/server/export_types/common/execute_job/decrypt_job_headers.ts index e5124c80601d7fb..579b5196ad4d962 100644 --- a/x-pack/plugins/reporting/server/export_types/common/execute_job/decrypt_job_headers.ts +++ b/x-pack/plugins/reporting/server/export_types/common/execute_job/decrypt_job_headers.ts @@ -14,14 +14,14 @@ interface HasEncryptedHeaders { // TODO merge functionality with CSV execute job export const decryptJobHeaders = async < JobParamsType, - JobDocPayloadType extends HasEncryptedHeaders + ScheduledTaskParamsType extends HasEncryptedHeaders >({ encryptionKey, job, logger, }: { encryptionKey?: string; - job: JobDocPayloadType; + job: ScheduledTaskParamsType; logger: LevelLogger; }): Promise> => { try { diff --git a/x-pack/plugins/reporting/server/export_types/common/execute_job/get_conditional_headers.test.ts b/x-pack/plugins/reporting/server/export_types/common/execute_job/get_conditional_headers.test.ts index 5d651ad5f8aea1e..030ced5dc4b80b5 100644 --- a/x-pack/plugins/reporting/server/export_types/common/execute_job/get_conditional_headers.test.ts +++ b/x-pack/plugins/reporting/server/export_types/common/execute_job/get_conditional_headers.test.ts @@ -8,8 +8,8 @@ import sinon from 'sinon'; import { ReportingConfig } from '../../../'; import { ReportingCore } from '../../../core'; import { createMockReportingCore } from '../../../test_helpers'; -import { JobDocPayload } from '../../../types'; -import { JobDocPayloadPDF } from '../../printable_pdf/types'; +import { ScheduledTaskParams } from '../../../types'; +import { ScheduledTaskParamsPDF } from '../../printable_pdf/types'; import { getConditionalHeaders, getCustomLogo } from './index'; let mockConfig: ReportingConfig; @@ -37,7 +37,7 @@ describe('conditions', () => { }; const conditionalHeaders = await getConditionalHeaders({ - job: {} as JobDocPayload, + job: {} as ScheduledTaskParams, filteredHeaders: permittedHeaders, config: mockConfig, }); @@ -64,14 +64,14 @@ test('uses basePath from job when creating saved object service', async () => { baz: 'quix', }; const conditionalHeaders = await getConditionalHeaders({ - job: {} as JobDocPayload, + job: {} as ScheduledTaskParams, filteredHeaders: permittedHeaders, config: mockConfig, }); const jobBasePath = '/sbp/s/marketing'; await getCustomLogo({ reporting: mockReportingPlugin, - job: { basePath: jobBasePath } as JobDocPayloadPDF, + job: { basePath: jobBasePath } as ScheduledTaskParamsPDF, conditionalHeaders, config: mockConfig, }); @@ -94,14 +94,14 @@ test(`uses basePath from server if job doesn't have a basePath when creating sav baz: 'quix', }; const conditionalHeaders = await getConditionalHeaders({ - job: {} as JobDocPayload, + job: {} as ScheduledTaskParams, filteredHeaders: permittedHeaders, config: mockConfig, }); await getCustomLogo({ reporting: mockReportingPlugin, - job: {} as JobDocPayloadPDF, + job: {} as ScheduledTaskParamsPDF, conditionalHeaders, config: mockConfig, }); @@ -139,7 +139,7 @@ describe('config formatting', () => { mockConfig = getMockConfig(mockConfigGet); const conditionalHeaders = await getConditionalHeaders({ - job: {} as JobDocPayload, + job: {} as ScheduledTaskParams, filteredHeaders: {}, config: mockConfig, }); diff --git a/x-pack/plugins/reporting/server/export_types/common/execute_job/get_conditional_headers.ts b/x-pack/plugins/reporting/server/export_types/common/execute_job/get_conditional_headers.ts index 6854f678aa97590..7a50eaac80d859a 100644 --- a/x-pack/plugins/reporting/server/export_types/common/execute_job/get_conditional_headers.ts +++ b/x-pack/plugins/reporting/server/export_types/common/execute_job/get_conditional_headers.ts @@ -7,13 +7,13 @@ import { ReportingConfig } from '../../../'; import { ConditionalHeaders } from '../../../types'; -export const getConditionalHeaders = ({ +export const getConditionalHeaders = ({ config, job, filteredHeaders, }: { config: ReportingConfig; - job: JobDocPayloadType; + job: ScheduledTaskParamsType; filteredHeaders: Record; }) => { const { kbnConfig } = config; diff --git a/x-pack/plugins/reporting/server/export_types/common/execute_job/get_custom_logo.test.ts b/x-pack/plugins/reporting/server/export_types/common/execute_job/get_custom_logo.test.ts index bd6eb4644d87f9f..c364752c8dd0f50 100644 --- a/x-pack/plugins/reporting/server/export_types/common/execute_job/get_custom_logo.test.ts +++ b/x-pack/plugins/reporting/server/export_types/common/execute_job/get_custom_logo.test.ts @@ -6,7 +6,7 @@ import { ReportingCore } from '../../../core'; import { createMockReportingCore } from '../../../test_helpers'; -import { JobDocPayloadPDF } from '../../printable_pdf/types'; +import { ScheduledTaskParamsPDF } from '../../printable_pdf/types'; import { getConditionalHeaders, getCustomLogo } from './index'; const mockConfigGet = jest.fn().mockImplementation((key: string) => { @@ -37,7 +37,7 @@ test(`gets logo from uiSettings`, async () => { }); const conditionalHeaders = await getConditionalHeaders({ - job: {} as JobDocPayloadPDF, + job: {} as ScheduledTaskParamsPDF, filteredHeaders: permittedHeaders, config: mockConfig, }); @@ -45,7 +45,7 @@ test(`gets logo from uiSettings`, async () => { const { logo } = await getCustomLogo({ reporting: mockReportingPlugin, config: mockConfig, - job: {} as JobDocPayloadPDF, + job: {} as ScheduledTaskParamsPDF, conditionalHeaders, }); diff --git a/x-pack/plugins/reporting/server/export_types/common/execute_job/get_custom_logo.ts b/x-pack/plugins/reporting/server/export_types/common/execute_job/get_custom_logo.ts index 85d1272fc22ceda..36c02eb47565c5f 100644 --- a/x-pack/plugins/reporting/server/export_types/common/execute_job/get_custom_logo.ts +++ b/x-pack/plugins/reporting/server/export_types/common/execute_job/get_custom_logo.ts @@ -7,7 +7,7 @@ import { ReportingConfig, ReportingCore } from '../../../'; import { UI_SETTINGS_CUSTOM_PDF_LOGO } from '../../../../common/constants'; import { ConditionalHeaders } from '../../../types'; -import { JobDocPayloadPDF } from '../../printable_pdf/types'; // Logo is PDF only +import { ScheduledTaskParamsPDF } from '../../printable_pdf/types'; // Logo is PDF only export const getCustomLogo = async ({ reporting, @@ -17,7 +17,7 @@ export const getCustomLogo = async ({ }: { reporting: ReportingCore; config: ReportingConfig; - job: JobDocPayloadPDF; + job: ScheduledTaskParamsPDF; conditionalHeaders: ConditionalHeaders; }) => { const serverBasePath: string = config.kbnConfig.get('server', 'basePath'); diff --git a/x-pack/plugins/reporting/server/export_types/common/execute_job/get_full_urls.test.ts b/x-pack/plugins/reporting/server/export_types/common/execute_job/get_full_urls.test.ts index cacea41477ea4a7..ad952c084d4f39e 100644 --- a/x-pack/plugins/reporting/server/export_types/common/execute_job/get_full_urls.test.ts +++ b/x-pack/plugins/reporting/server/export_types/common/execute_job/get_full_urls.test.ts @@ -5,12 +5,12 @@ */ import { ReportingConfig } from '../../../'; -import { JobDocPayloadPNG } from '../../png/types'; -import { JobDocPayloadPDF } from '../../printable_pdf/types'; +import { ScheduledTaskParamsPNG } from '../../png/types'; +import { ScheduledTaskParamsPDF } from '../../printable_pdf/types'; import { getFullUrls } from './get_full_urls'; interface FullUrlsOpts { - job: JobDocPayloadPNG & JobDocPayloadPDF; + job: ScheduledTaskParamsPNG & ScheduledTaskParamsPDF; config: ReportingConfig; } @@ -35,7 +35,7 @@ beforeEach(() => { mockConfig = getMockConfig(mockConfigGet); }); -const getMockJob = (base: object) => base as JobDocPayloadPNG & JobDocPayloadPDF; +const getMockJob = (base: object) => base as ScheduledTaskParamsPNG & ScheduledTaskParamsPDF; test(`fails if no URL is passed`, async () => { const fn = () => getFullUrls({ job: getMockJob({}), config: mockConfig } as FullUrlsOpts); diff --git a/x-pack/plugins/reporting/server/export_types/common/execute_job/get_full_urls.ts b/x-pack/plugins/reporting/server/export_types/common/execute_job/get_full_urls.ts index bcd7f122748cb82..67bc8d16fa758d1 100644 --- a/x-pack/plugins/reporting/server/export_types/common/execute_job/get_full_urls.ts +++ b/x-pack/plugins/reporting/server/export_types/common/execute_job/get_full_urls.ts @@ -13,22 +13,26 @@ import { import { ReportingConfig } from '../../..'; import { getAbsoluteUrlFactory } from '../../../../common/get_absolute_url'; import { validateUrls } from '../../../../common/validate_urls'; -import { JobDocPayloadPNG } from '../../png/types'; -import { JobDocPayloadPDF } from '../../printable_pdf/types'; +import { ScheduledTaskParamsPNG } from '../../png/types'; +import { ScheduledTaskParamsPDF } from '../../printable_pdf/types'; -function isPngJob(job: JobDocPayloadPNG | JobDocPayloadPDF): job is JobDocPayloadPNG { - return (job as JobDocPayloadPNG).relativeUrl !== undefined; +function isPngJob( + job: ScheduledTaskParamsPNG | ScheduledTaskParamsPDF +): job is ScheduledTaskParamsPNG { + return (job as ScheduledTaskParamsPNG).relativeUrl !== undefined; } -function isPdfJob(job: JobDocPayloadPNG | JobDocPayloadPDF): job is JobDocPayloadPDF { - return (job as JobDocPayloadPDF).relativeUrls !== undefined; +function isPdfJob( + job: ScheduledTaskParamsPNG | ScheduledTaskParamsPDF +): job is ScheduledTaskParamsPDF { + return (job as ScheduledTaskParamsPDF).relativeUrls !== undefined; } -export function getFullUrls({ +export function getFullUrls({ config, job, }: { config: ReportingConfig; - job: JobDocPayloadPDF | JobDocPayloadPNG; + job: ScheduledTaskParamsPDF | ScheduledTaskParamsPNG; }) { const [basePath, protocol, hostname, port] = [ config.kbnConfig.get('server', 'basePath'), diff --git a/x-pack/plugins/reporting/server/export_types/common/execute_job/omit_blacklisted_headers.ts b/x-pack/plugins/reporting/server/export_types/common/execute_job/omit_blacklisted_headers.ts index 5147881a980eac4..db7137c30513bfa 100644 --- a/x-pack/plugins/reporting/server/export_types/common/execute_job/omit_blacklisted_headers.ts +++ b/x-pack/plugins/reporting/server/export_types/common/execute_job/omit_blacklisted_headers.ts @@ -9,11 +9,11 @@ import { KBN_SCREENSHOT_HEADER_BLACKLIST_STARTS_WITH_PATTERN, } from '../../../../common/constants'; -export const omitBlacklistedHeaders = ({ +export const omitBlacklistedHeaders = ({ job, decryptedHeaders, }: { - job: JobDocPayloadType; + job: ScheduledTaskParamsType; decryptedHeaders: Record; }) => { const filteredHeaders: Record = omit( diff --git a/x-pack/plugins/reporting/server/export_types/csv/index.ts b/x-pack/plugins/reporting/server/export_types/csv/index.ts index 8642a6d5758a80e..b5eacdfc62c8b90 100644 --- a/x-pack/plugins/reporting/server/export_types/csv/index.ts +++ b/x-pack/plugins/reporting/server/export_types/csv/index.ts @@ -15,21 +15,21 @@ import { import { CSV_JOB_TYPE as jobType } from '../../../constants'; import { ESQueueCreateJobFn, ESQueueWorkerExecuteFn, ExportTypeDefinition } from '../../types'; import { metadata } from './metadata'; -import { createJobFactory } from './server/create_job'; -import { executeJobFactory } from './server/execute_job'; -import { JobDocPayloadDiscoverCsv, JobParamsDiscoverCsv } from './types'; +import { scheduleTaskFnFactory } from './server/create_job'; +import { runTaskFnFactory } from './server/execute_job'; +import { JobParamsDiscoverCsv, ScheduledTaskParamsCSV } from './types'; export const getExportType = (): ExportTypeDefinition< JobParamsDiscoverCsv, ESQueueCreateJobFn, - JobDocPayloadDiscoverCsv, - ESQueueWorkerExecuteFn + ScheduledTaskParamsCSV, + ESQueueWorkerExecuteFn > => ({ ...metadata, jobType, jobContentExtension: 'csv', - createJobFactory, - executeJobFactory, + scheduleTaskFnFactory, + runTaskFnFactory, validLicenses: [ LICENSE_TYPE_TRIAL, LICENSE_TYPE_BASIC, diff --git a/x-pack/plugins/reporting/server/export_types/csv/server/create_job.ts b/x-pack/plugins/reporting/server/export_types/csv/server/create_job.ts index acf7f0505a735ec..c4fa1cd8e4fa6e1 100644 --- a/x-pack/plugins/reporting/server/export_types/csv/server/create_job.ts +++ b/x-pack/plugins/reporting/server/export_types/csv/server/create_job.ts @@ -4,24 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ -import { KibanaRequest, RequestHandlerContext } from 'src/core/server'; -import { ReportingCore } from '../../../'; import { cryptoFactory } from '../../../lib'; -import { CreateJobFactory, ESQueueCreateJobFn } from '../../../types'; +import { ESQueueCreateJobFn, ScheduleTaskFnFactory } from '../../../types'; import { JobParamsDiscoverCsv } from '../types'; -export const createJobFactory: CreateJobFactory> = function createJobFactoryFn(reporting: ReportingCore) { +>> = function createJobFactoryFn(reporting) { const config = reporting.getConfig(); const crypto = cryptoFactory(config.get('encryptionKey')); const setupDeps = reporting.getPluginSetupDeps(); - return async function createJob( - jobParams: JobParamsDiscoverCsv, - context: RequestHandlerContext, - request: KibanaRequest - ) { + return async function scheduleTask(jobParams, context, request) { const serializedEncryptedHeaders = await crypto.encrypt(request.headers); const savedObjectsClient = context.core.savedObjects.client; diff --git a/x-pack/plugins/reporting/server/export_types/csv/server/execute_job.test.ts b/x-pack/plugins/reporting/server/export_types/csv/server/execute_job.test.ts index ddcf94079ade426..742828b2b806603 100644 --- a/x-pack/plugins/reporting/server/export_types/csv/server/execute_job.test.ts +++ b/x-pack/plugins/reporting/server/export_types/csv/server/execute_job.test.ts @@ -9,17 +9,17 @@ import nodeCrypto from '@elastic/node-crypto'; import Puid from 'puid'; import sinon from 'sinon'; import { fieldFormats, UI_SETTINGS } from '../../../../../../../src/plugins/data/server'; +import { + CSV_QUOTE_VALUES_SETTING, + CSV_SEPARATOR_SETTING, +} from '../../../../../../../src/plugins/share/server'; import { CancellationToken } from '../../../../common'; import { CSV_BOM_CHARS } from '../../../../common/constants'; import { LevelLogger } from '../../../lib'; import { setFieldFormats } from '../../../services'; import { createMockReportingCore } from '../../../test_helpers'; -import { JobDocPayloadDiscoverCsv } from '../types'; -import { executeJobFactory } from './execute_job'; -import { - CSV_SEPARATOR_SETTING, - CSV_QUOTE_VALUES_SETTING, -} from '../../../../../../../src/plugins/share/server'; +import { ScheduledTaskParamsCSV } from '../types'; +import { runTaskFnFactory } from './execute_job'; const delay = (ms: number) => new Promise((resolve) => setTimeout(() => resolve(), ms)); @@ -28,7 +28,7 @@ const getRandomScrollId = () => { return puid.generate(); }; -const getJobDocPayload = (baseObj: any) => baseObj as JobDocPayloadDiscoverCsv; +const getScheduledTaskParams = (baseObj: any) => baseObj as ScheduledTaskParamsCSV; describe('CSV Execute Job', function () { const encryptionKey = 'testEncryptionKey'; @@ -121,10 +121,10 @@ describe('CSV Execute Job', function () { describe('basic Elasticsearch call behavior', function () { it('should decrypt encrypted headers and pass to callAsCurrentUser', async function () { - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - await executeJob( + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + await runTask( 'job456', - getJobDocPayload({ + getScheduledTaskParams({ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null }, @@ -141,8 +141,8 @@ describe('CSV Execute Job', function () { testBody: true, }; - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const job = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const job = getScheduledTaskParams({ headers: encryptedHeaders, fields: [], searchRequest: { @@ -151,7 +151,7 @@ describe('CSV Execute Job', function () { }, }); - await executeJob('job777', job, cancellationToken); + await runTask('job777', job, cancellationToken); const searchCall = callAsCurrentUserStub.firstCall; expect(searchCall.args[0]).toBe('search'); @@ -168,10 +168,10 @@ describe('CSV Execute Job', function () { _scroll_id: scrollId, }); callAsCurrentUserStub.onSecondCall().resolves(defaultElasticsearchResponse); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - await executeJob( + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + await runTask( 'job456', - getJobDocPayload({ + getScheduledTaskParams({ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null }, @@ -186,10 +186,10 @@ describe('CSV Execute Job', function () { }); it('should not execute scroll if there are no hits from the search', async function () { - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - await executeJob( + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + await runTask( 'job456', - getJobDocPayload({ + getScheduledTaskParams({ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null }, @@ -220,10 +220,10 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - await executeJob( + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + await runTask( 'job456', - getJobDocPayload({ + getScheduledTaskParams({ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null }, @@ -259,10 +259,10 @@ describe('CSV Execute Job', function () { _scroll_id: lastScrollId, }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - await executeJob( + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + await runTask( 'job456', - getJobDocPayload({ + getScheduledTaskParams({ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null }, @@ -291,16 +291,16 @@ describe('CSV Execute Job', function () { _scroll_id: lastScrollId, }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], conflictedTypesFields: undefined, searchRequest: { index: null, body: null }, }); - await expect( - executeJob('job123', jobParams, cancellationToken) - ).rejects.toMatchInlineSnapshot(`[TypeError: Cannot read property 'indexOf' of undefined]`); + await expect(runTask('job123', jobParams, cancellationToken)).rejects.toMatchInlineSnapshot( + `[TypeError: Cannot read property 'indexOf' of undefined]` + ); const lastCall = callAsCurrentUserStub.getCall(callAsCurrentUserStub.callCount - 1); expect(lastCall.args[0]).toBe('clearScroll'); @@ -318,14 +318,14 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], conflictedTypesFields: [], searchRequest: { index: null, body: null }, }); - const { csv_contains_formulas: csvContainsFormulas } = await executeJob( + const { csv_contains_formulas: csvContainsFormulas } = await runTask( 'job123', jobParams, cancellationToken @@ -343,14 +343,14 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['=SUM(A1:A2)', 'two'], conflictedTypesFields: [], searchRequest: { index: null, body: null }, }); - const { csv_contains_formulas: csvContainsFormulas } = await executeJob( + const { csv_contains_formulas: csvContainsFormulas } = await runTask( 'job123', jobParams, cancellationToken @@ -369,14 +369,14 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], conflictedTypesFields: [], searchRequest: { index: null, body: null }, }); - const { csv_contains_formulas: csvContainsFormulas } = await executeJob( + const { csv_contains_formulas: csvContainsFormulas } = await runTask( 'job123', jobParams, cancellationToken @@ -395,15 +395,15 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['=SUM(A1:A2)', 'two'], conflictedTypesFields: [], searchRequest: { index: null, body: null }, }); - const { csv_contains_formulas: csvContainsFormulas } = await executeJob( + const { csv_contains_formulas: csvContainsFormulas } = await runTask( 'job123', jobParams, cancellationToken @@ -421,14 +421,14 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], conflictedTypesFields: [], searchRequest: { index: null, body: null }, }); - const { csv_contains_formulas: csvContainsFormulas } = await executeJob( + const { csv_contains_formulas: csvContainsFormulas } = await runTask( 'job123', jobParams, cancellationToken @@ -448,14 +448,14 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], conflictedTypesFields: [], searchRequest: { index: null, body: null }, }); - const { content } = await executeJob('job123', jobParams, cancellationToken); + const { content } = await runTask('job123', jobParams, cancellationToken); expect(content).toEqual(`${CSV_BOM_CHARS}one,two\none,bar\n`); }); @@ -469,14 +469,14 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], conflictedTypesFields: [], searchRequest: { index: null, body: null }, }); - const { content } = await executeJob('job123', jobParams, cancellationToken); + const { content } = await runTask('job123', jobParams, cancellationToken); expect(content).toEqual('one,two\none,bar\n'); }); @@ -492,14 +492,14 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], conflictedTypesFields: [], searchRequest: { index: null, body: null }, }); - const { content } = await executeJob('job123', jobParams, cancellationToken); + const { content } = await runTask('job123', jobParams, cancellationToken); expect(content).toEqual("one,two\n\"'=cmd|' /C calc'!A0\",bar\n"); }); @@ -513,14 +513,14 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], conflictedTypesFields: [], searchRequest: { index: null, body: null }, }); - const { content } = await executeJob('job123', jobParams, cancellationToken); + const { content } = await runTask('job123', jobParams, cancellationToken); expect(content).toEqual('one,two\n"=cmd|\' /C calc\'!A0",bar\n'); }); @@ -529,15 +529,15 @@ describe('CSV Execute Job', function () { describe('Elasticsearch call errors', function () { it('should reject Promise if search call errors out', async function () { callAsCurrentUserStub.rejects(new Error()); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null }, }); - await expect( - executeJob('job123', jobParams, cancellationToken) - ).rejects.toMatchInlineSnapshot(`[Error]`); + await expect(runTask('job123', jobParams, cancellationToken)).rejects.toMatchInlineSnapshot( + `[Error]` + ); }); it('should reject Promise if scroll call errors out', async function () { @@ -548,15 +548,15 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); callAsCurrentUserStub.onSecondCall().rejects(new Error()); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null }, }); - await expect( - executeJob('job123', jobParams, cancellationToken) - ).rejects.toMatchInlineSnapshot(`[Error]`); + await expect(runTask('job123', jobParams, cancellationToken)).rejects.toMatchInlineSnapshot( + `[Error]` + ); }); }); @@ -569,15 +569,13 @@ describe('CSV Execute Job', function () { _scroll_id: undefined, }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null }, }); - await expect( - executeJob('job123', jobParams, cancellationToken) - ).rejects.toMatchInlineSnapshot( + await expect(runTask('job123', jobParams, cancellationToken)).rejects.toMatchInlineSnapshot( `[Error: Expected _scroll_id in the following Elasticsearch response: {"hits":{"hits":[{}]}}]` ); }); @@ -590,15 +588,13 @@ describe('CSV Execute Job', function () { _scroll_id: undefined, }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null }, }); - await expect( - executeJob('job123', jobParams, cancellationToken) - ).rejects.toMatchInlineSnapshot( + await expect(runTask('job123', jobParams, cancellationToken)).rejects.toMatchInlineSnapshot( `[Error: Expected _scroll_id in the following Elasticsearch response: {"hits":{"hits":[]}}]` ); }); @@ -618,15 +614,13 @@ describe('CSV Execute Job', function () { _scroll_id: undefined, }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null }, }); - await expect( - executeJob('job123', jobParams, cancellationToken) - ).rejects.toMatchInlineSnapshot( + await expect(runTask('job123', jobParams, cancellationToken)).rejects.toMatchInlineSnapshot( `[Error: Expected _scroll_id in the following Elasticsearch response: {"hits":{"hits":[{}]}}]` ); }); @@ -646,15 +640,13 @@ describe('CSV Execute Job', function () { _scroll_id: undefined, }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null }, }); - await expect( - executeJob('job123', jobParams, cancellationToken) - ).rejects.toMatchInlineSnapshot( + await expect(runTask('job123', jobParams, cancellationToken)).rejects.toMatchInlineSnapshot( `[Error: Expected _scroll_id in the following Elasticsearch response: {"hits":{"hits":[]}}]` ); }); @@ -682,10 +674,10 @@ describe('CSV Execute Job', function () { }); it('should stop calling Elasticsearch when cancellationToken.cancel is called', async function () { - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - executeJob( + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + runTask( 'job345', - getJobDocPayload({ + getScheduledTaskParams({ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null }, @@ -701,10 +693,10 @@ describe('CSV Execute Job', function () { }); it(`shouldn't call clearScroll if it never got a scrollId`, async function () { - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - executeJob( + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + runTask( 'job345', - getJobDocPayload({ + getScheduledTaskParams({ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null }, @@ -719,10 +711,10 @@ describe('CSV Execute Job', function () { }); it('should call clearScroll if it got a scrollId', async function () { - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - executeJob( + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + runTask( 'job345', - getJobDocPayload({ + getScheduledTaskParams({ headers: encryptedHeaders, fields: [], searchRequest: { index: null, body: null }, @@ -741,54 +733,54 @@ describe('CSV Execute Job', function () { describe('csv content', function () { it('should write column headers to output, even if there are no results', async function () { - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], searchRequest: { index: null, body: null }, }); - const { content } = await executeJob('job123', jobParams, cancellationToken); + const { content } = await runTask('job123', jobParams, cancellationToken); expect(content).toBe(`one,two\n`); }); it('should use custom uiSettings csv:separator for header', async function () { mockUiSettingsClient.get.withArgs(CSV_SEPARATOR_SETTING).returns(';'); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], searchRequest: { index: null, body: null }, }); - const { content } = await executeJob('job123', jobParams, cancellationToken); + const { content } = await runTask('job123', jobParams, cancellationToken); expect(content).toBe(`one;two\n`); }); it('should escape column headers if uiSettings csv:quoteValues is true', async function () { mockUiSettingsClient.get.withArgs(CSV_QUOTE_VALUES_SETTING).returns(true); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one and a half', 'two', 'three-and-four', 'five & six'], searchRequest: { index: null, body: null }, }); - const { content } = await executeJob('job123', jobParams, cancellationToken); + const { content } = await runTask('job123', jobParams, cancellationToken); expect(content).toBe(`"one and a half",two,"three-and-four","five & six"\n`); }); it(`shouldn't escape column headers if uiSettings csv:quoteValues is false`, async function () { mockUiSettingsClient.get.withArgs(CSV_QUOTE_VALUES_SETTING).returns(false); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one and a half', 'two', 'three-and-four', 'five & six'], searchRequest: { index: null, body: null }, }); - const { content } = await executeJob('job123', jobParams, cancellationToken); + const { content } = await runTask('job123', jobParams, cancellationToken); expect(content).toBe(`one and a half,two,three-and-four,five & six\n`); }); it('should write column headers to output, when there are results', async function () { - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); callAsCurrentUserStub.onFirstCall().resolves({ hits: { hits: [{ one: '1', two: '2' }], @@ -796,19 +788,19 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const jobParams = getJobDocPayload({ + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], searchRequest: { index: null, body: null }, }); - const { content } = await executeJob('job123', jobParams, cancellationToken); + const { content } = await runTask('job123', jobParams, cancellationToken); const lines = content.split('\n'); const headerLine = lines[0]; expect(headerLine).toBe('one,two'); }); it('should use comma separated values of non-nested fields from _source', async function () { - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); callAsCurrentUserStub.onFirstCall().resolves({ hits: { hits: [{ _source: { one: 'foo', two: 'bar' } }], @@ -816,20 +808,20 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const jobParams = getJobDocPayload({ + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], conflictedTypesFields: [], searchRequest: { index: null, body: null }, }); - const { content } = await executeJob('job123', jobParams, cancellationToken); + const { content } = await runTask('job123', jobParams, cancellationToken); const lines = content.split('\n'); const valuesLine = lines[1]; expect(valuesLine).toBe('foo,bar'); }); it('should concatenate the hits from multiple responses', async function () { - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); callAsCurrentUserStub.onFirstCall().resolves({ hits: { hits: [{ _source: { one: 'foo', two: 'bar' } }], @@ -843,13 +835,13 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const jobParams = getJobDocPayload({ + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], conflictedTypesFields: [], searchRequest: { index: null, body: null }, }); - const { content } = await executeJob('job123', jobParams, cancellationToken); + const { content } = await runTask('job123', jobParams, cancellationToken); const lines = content.split('\n'); expect(lines[1]).toBe('foo,bar'); @@ -857,7 +849,7 @@ describe('CSV Execute Job', function () { }); it('should use field formatters to format fields', async function () { - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); callAsCurrentUserStub.onFirstCall().resolves({ hits: { hits: [{ _source: { one: 'foo', two: 'bar' } }], @@ -865,7 +857,7 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const jobParams = getJobDocPayload({ + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], conflictedTypesFields: [], @@ -880,7 +872,7 @@ describe('CSV Execute Job', function () { }, }, }); - const { content } = await executeJob('job123', jobParams, cancellationToken); + const { content } = await runTask('job123', jobParams, cancellationToken); const lines = content.split('\n'); expect(lines[1]).toBe('FOO,bar'); @@ -899,14 +891,14 @@ describe('CSV Execute Job', function () { beforeEach(async function () { configGetStub.withArgs('csv', 'maxSizeBytes').returns(1); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], searchRequest: { index: null, body: null }, }); - ({ content, max_size_reached: maxSizeReached } = await executeJob( + ({ content, max_size_reached: maxSizeReached } = await runTask( 'job123', jobParams, cancellationToken @@ -929,14 +921,14 @@ describe('CSV Execute Job', function () { beforeEach(async function () { configGetStub.withArgs('csv', 'maxSizeBytes').returns(9); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], searchRequest: { index: null, body: null }, }); - ({ content, max_size_reached: maxSizeReached } = await executeJob( + ({ content, max_size_reached: maxSizeReached } = await runTask( 'job123', jobParams, cancellationToken @@ -966,15 +958,15 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], conflictedTypesFields: [], searchRequest: { index: null, body: null }, }); - ({ content, max_size_reached: maxSizeReached } = await executeJob( + ({ content, max_size_reached: maxSizeReached } = await runTask( 'job123', jobParams, cancellationToken @@ -1005,15 +997,15 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], conflictedTypesFields: [], searchRequest: { index: null, body: null }, }); - ({ content, max_size_reached: maxSizeReached } = await executeJob( + ({ content, max_size_reached: maxSizeReached } = await runTask( 'job123', jobParams, cancellationToken @@ -1042,15 +1034,15 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], conflictedTypesFields: [], searchRequest: { index: null, body: null }, }); - await executeJob('job123', jobParams, cancellationToken); + await runTask('job123', jobParams, cancellationToken); const searchCall = callAsCurrentUserStub.firstCall; expect(searchCall.args[0]).toBe('search'); @@ -1068,15 +1060,15 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], conflictedTypesFields: [], searchRequest: { index: null, body: null }, }); - await executeJob('job123', jobParams, cancellationToken); + await runTask('job123', jobParams, cancellationToken); const searchCall = callAsCurrentUserStub.firstCall; expect(searchCall.args[0]).toBe('search'); @@ -1094,15 +1086,15 @@ describe('CSV Execute Job', function () { _scroll_id: 'scrollId', }); - const executeJob = await executeJobFactory(mockReportingCore, mockLogger); - const jobParams = getJobDocPayload({ + const runTask = await runTaskFnFactory(mockReportingCore, mockLogger); + const jobParams = getScheduledTaskParams({ headers: encryptedHeaders, fields: ['one', 'two'], conflictedTypesFields: [], searchRequest: { index: null, body: null }, }); - await executeJob('job123', jobParams, cancellationToken); + await runTask('job123', jobParams, cancellationToken); const scrollCall = callAsCurrentUserStub.secondCall; expect(scrollCall.args[0]).toBe('scroll'); diff --git a/x-pack/plugins/reporting/server/export_types/csv/server/execute_job.ts b/x-pack/plugins/reporting/server/export_types/csv/server/execute_job.ts index 4b17cc669efe1b8..d40e8a454d43352 100644 --- a/x-pack/plugins/reporting/server/export_types/csv/server/execute_job.ts +++ b/x-pack/plugins/reporting/server/export_types/csv/server/execute_job.ts @@ -8,31 +8,26 @@ import { i18n } from '@kbn/i18n'; import Hapi from 'hapi'; import { IUiSettingsClient, KibanaRequest } from '../../../../../../../src/core/server'; import { - CSV_SEPARATOR_SETTING, CSV_QUOTE_VALUES_SETTING, + CSV_SEPARATOR_SETTING, } from '../../../../../../../src/plugins/share/server'; -import { ReportingCore } from '../../..'; import { CSV_BOM_CHARS, CSV_JOB_TYPE } from '../../../../common/constants'; import { getFieldFormats } from '../../../../server/services'; -import { cryptoFactory, LevelLogger } from '../../../lib'; -import { ESQueueWorkerExecuteFn, ExecuteJobFactory } from '../../../types'; -import { JobDocPayloadDiscoverCsv } from '../types'; +import { cryptoFactory } from '../../../lib'; +import { ESQueueWorkerExecuteFn, RunTaskFnFactory } from '../../../types'; +import { ScheduledTaskParamsCSV } from '../types'; import { fieldFormatMapFactory } from './lib/field_format_map'; import { createGenerateCsv } from './lib/generate_csv'; -export const executeJobFactory: ExecuteJobFactory> = async function executeJobFactoryFn(reporting: ReportingCore, parentLogger: LevelLogger) { +export const runTaskFnFactory: RunTaskFnFactory> = function executeJobFactoryFn(reporting, parentLogger) { const config = reporting.getConfig(); const crypto = cryptoFactory(config.get('encryptionKey')); const logger = parentLogger.clone([CSV_JOB_TYPE, 'execute-job']); const serverBasePath = config.kbnConfig.get('server', 'basePath'); - return async function executeJob( - jobId: string, - job: JobDocPayloadDiscoverCsv, - cancellationToken: any - ) { + return async function runTask(jobId, job, cancellationToken) { const elasticsearch = await reporting.getElasticsearchService(); const jobLogger = logger.clone([jobId]); diff --git a/x-pack/plugins/reporting/server/export_types/csv/types.d.ts b/x-pack/plugins/reporting/server/export_types/csv/types.d.ts index c80cd5fd24fe5b5..ab3e114c7c9952a 100644 --- a/x-pack/plugins/reporting/server/export_types/csv/types.d.ts +++ b/x-pack/plugins/reporting/server/export_types/csv/types.d.ts @@ -5,7 +5,7 @@ */ import { CancellationToken } from '../../../common'; -import { JobParamPostPayload, JobDocPayload, ScrollConfig } from '../../types'; +import { JobParamPostPayload, ScheduledTaskParams, ScrollConfig } from '../../types'; export type RawValue = string | object | null | undefined; @@ -32,7 +32,7 @@ export interface JobParamsDiscoverCsv { post?: JobParamPostPayloadDiscoverCsv; } -export interface JobDocPayloadDiscoverCsv extends JobDocPayload { +export interface ScheduledTaskParamsCSV extends ScheduledTaskParams { basePath: string; searchRequest: any; fields: any; diff --git a/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/index.ts b/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/index.ts index 65802ee5bb7fbb6..961a046c846e4de 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/index.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/index.ts @@ -15,16 +15,16 @@ import { import { CSV_FROM_SAVEDOBJECT_JOB_TYPE } from '../../../constants'; import { ExportTypeDefinition } from '../../types'; import { metadata } from './metadata'; -import { createJobFactory, ImmediateCreateJobFn } from './server/create_job'; -import { executeJobFactory, ImmediateExecuteFn } from './server/execute_job'; +import { ImmediateCreateJobFn, scheduleTaskFnFactory } from './server/create_job'; +import { ImmediateExecuteFn, runTaskFnFactory } from './server/execute_job'; import { JobParamsPanelCsv } from './types'; /* * These functions are exported to share with the API route handler that * generates csv from saved object immediately on request. */ -export { createJobFactory } from './server/create_job'; -export { executeJobFactory } from './server/execute_job'; +export { scheduleTaskFnFactory } from './server/create_job'; +export { runTaskFnFactory } from './server/execute_job'; export const getExportType = (): ExportTypeDefinition< JobParamsPanelCsv, @@ -35,8 +35,8 @@ export const getExportType = (): ExportTypeDefinition< ...metadata, jobType: CSV_FROM_SAVEDOBJECT_JOB_TYPE, jobContentExtension: 'csv', - createJobFactory, - executeJobFactory, + scheduleTaskFnFactory, + runTaskFnFactory, validLicenses: [ LICENSE_TYPE_TRIAL, LICENSE_TYPE_BASIC, diff --git a/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/server/create_job/create_job.ts b/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/server/create_job/create_job.ts deleted file mode 100644 index c187da5104d3f0a..000000000000000 --- a/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/server/create_job/create_job.ts +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { notFound, notImplemented } from 'boom'; -import { get } from 'lodash'; -import { KibanaRequest, RequestHandlerContext } from 'src/core/server'; -import { ReportingCore } from '../../../..'; -import { CSV_FROM_SAVEDOBJECT_JOB_TYPE } from '../../../../../common/constants'; -import { cryptoFactory, LevelLogger } from '../../../../lib'; -import { CreateJobFactory, TimeRangeParams } from '../../../../types'; -import { - JobDocPayloadPanelCsv, - JobParamsPanelCsv, - SavedObject, - SavedObjectServiceError, - SavedSearchObjectAttributesJSON, - SearchPanel, - VisObjectAttributesJSON, -} from '../../types'; -import { createJobSearch } from './create_job_search'; - -export type ImmediateCreateJobFn = ( - jobParams: JobParamsType, - headers: KibanaRequest['headers'], - context: RequestHandlerContext, - req: KibanaRequest -) => Promise<{ - type: string | null; - title: string; - jobParams: JobParamsType; -}>; - -interface VisData { - title: string; - visType: string; - panel: SearchPanel; -} - -export const createJobFactory: CreateJobFactory> = function createJobFactoryFn(reporting: ReportingCore, parentLogger: LevelLogger) { - const config = reporting.getConfig(); - const crypto = cryptoFactory(config.get('encryptionKey')); - const logger = parentLogger.clone([CSV_FROM_SAVEDOBJECT_JOB_TYPE, 'create-job']); - - return async function createJob( - jobParams: JobParamsPanelCsv, - headers: KibanaRequest['headers'], - context: RequestHandlerContext, - req: KibanaRequest - ): Promise { - const { savedObjectType, savedObjectId } = jobParams; - const serializedEncryptedHeaders = await crypto.encrypt(headers); - - const { panel, title, visType }: VisData = await Promise.resolve() - .then(() => context.core.savedObjects.client.get(savedObjectType, savedObjectId)) - .then(async (savedObject: SavedObject) => { - const { attributes, references } = savedObject; - const { - kibanaSavedObjectMeta: kibanaSavedObjectMetaJSON, - } = attributes as SavedSearchObjectAttributesJSON; - const { timerange } = req.body as { timerange: TimeRangeParams }; - - if (!kibanaSavedObjectMetaJSON) { - throw new Error('Could not parse saved object data!'); - } - - const kibanaSavedObjectMeta = { - ...kibanaSavedObjectMetaJSON, - searchSource: JSON.parse(kibanaSavedObjectMetaJSON.searchSourceJSON), - }; - - const { visState: visStateJSON } = attributes as VisObjectAttributesJSON; - if (visStateJSON) { - throw notImplemented('Visualization types are not yet implemented'); - } - - // saved search type - return await createJobSearch(timerange, attributes, references, kibanaSavedObjectMeta); - }) - .catch((err: Error) => { - const boomErr = (err as unknown) as { isBoom: boolean }; - if (boomErr.isBoom) { - throw err; - } - const errPayload: SavedObjectServiceError = get(err, 'output.payload', { statusCode: 0 }); - if (errPayload.statusCode === 404) { - throw notFound(errPayload.message); - } - if (err.stack) { - logger.error(err.stack); - } - throw new Error(`Unable to create a job from saved object data! Error: ${err}`); - }); - - return { - headers: serializedEncryptedHeaders, - jobParams: { ...jobParams, panel, visType }, - type: null, - title, - }; - }; -}; diff --git a/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/server/create_job/index.ts b/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/server/create_job/index.ts index a3674d69ae6a5bb..dafac040176075d 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/server/create_job/index.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/server/create_job/index.ts @@ -4,4 +4,96 @@ * you may not use this file except in compliance with the Elastic License. */ -export { createJobFactory, ImmediateCreateJobFn } from './create_job'; +import { notFound, notImplemented } from 'boom'; +import { get } from 'lodash'; +import { KibanaRequest, RequestHandlerContext } from 'src/core/server'; +import { CSV_FROM_SAVEDOBJECT_JOB_TYPE } from '../../../../../common/constants'; +import { cryptoFactory } from '../../../../lib'; +import { ScheduleTaskFnFactory, TimeRangeParams } from '../../../../types'; +import { + JobParamsPanelCsv, + SavedObject, + SavedObjectServiceError, + SavedSearchObjectAttributesJSON, + SearchPanel, + VisObjectAttributesJSON, +} from '../../types'; +import { createJobSearch } from './create_job_search'; + +export type ImmediateCreateJobFn = ( + jobParams: JobParamsType, + headers: KibanaRequest['headers'], + context: RequestHandlerContext, + req: KibanaRequest +) => Promise<{ + type: string | null; + title: string; + jobParams: JobParamsType; +}>; + +interface VisData { + title: string; + visType: string; + panel: SearchPanel; +} + +export const scheduleTaskFnFactory: ScheduleTaskFnFactory> = function createJobFactoryFn(reporting, parentLogger) { + const config = reporting.getConfig(); + const crypto = cryptoFactory(config.get('encryptionKey')); + const logger = parentLogger.clone([CSV_FROM_SAVEDOBJECT_JOB_TYPE, 'create-job']); + + return async function scheduleTask(jobParams, headers, context, req) { + const { savedObjectType, savedObjectId } = jobParams; + const serializedEncryptedHeaders = await crypto.encrypt(headers); + + const { panel, title, visType }: VisData = await Promise.resolve() + .then(() => context.core.savedObjects.client.get(savedObjectType, savedObjectId)) + .then(async (savedObject: SavedObject) => { + const { attributes, references } = savedObject; + const { + kibanaSavedObjectMeta: kibanaSavedObjectMetaJSON, + } = attributes as SavedSearchObjectAttributesJSON; + const { timerange } = req.body as { timerange: TimeRangeParams }; + + if (!kibanaSavedObjectMetaJSON) { + throw new Error('Could not parse saved object data!'); + } + + const kibanaSavedObjectMeta = { + ...kibanaSavedObjectMetaJSON, + searchSource: JSON.parse(kibanaSavedObjectMetaJSON.searchSourceJSON), + }; + + const { visState: visStateJSON } = attributes as VisObjectAttributesJSON; + if (visStateJSON) { + throw notImplemented('Visualization types are not yet implemented'); + } + + // saved search type + return await createJobSearch(timerange, attributes, references, kibanaSavedObjectMeta); + }) + .catch((err: Error) => { + const boomErr = (err as unknown) as { isBoom: boolean }; + if (boomErr.isBoom) { + throw err; + } + const errPayload: SavedObjectServiceError = get(err, 'output.payload', { statusCode: 0 }); + if (errPayload.statusCode === 404) { + throw notFound(errPayload.message); + } + if (err.stack) { + logger.error(err.stack); + } + throw new Error(`Unable to create a job from saved object data! Error: ${err}`); + }); + + return { + headers: serializedEncryptedHeaders, + jobParams: { ...jobParams, panel, visType }, + type: null, + title, + }; + }; +}; diff --git a/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/server/execute_job.ts b/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/server/execute_job.ts index d555100b6320d39..42820752a9db5f5 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/server/execute_job.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/server/execute_job.ts @@ -6,12 +6,11 @@ import { i18n } from '@kbn/i18n'; import { KibanaRequest, RequestHandlerContext } from 'src/core/server'; -import { ReportingCore } from '../../..'; import { CONTENT_TYPE_CSV, CSV_FROM_SAVEDOBJECT_JOB_TYPE } from '../../../../common/constants'; -import { cryptoFactory, LevelLogger } from '../../../lib'; -import { ExecuteJobFactory, JobDocOutput, JobDocPayload } from '../../../types'; +import { cryptoFactory } from '../../../lib'; +import { RunTaskFnFactory, ScheduledTaskParams, TaskRunResult } from '../../../types'; import { CsvResultFromSearch } from '../../csv/types'; -import { FakeRequest, JobDocPayloadPanelCsv, JobParamsPanelCsv, SearchPanel } from '../types'; +import { FakeRequest, JobParamsPanelCsv, SearchPanel } from '../types'; import { createGenerateCsv } from './lib'; /* @@ -20,25 +19,20 @@ import { createGenerateCsv } from './lib'; */ export type ImmediateExecuteFn = ( jobId: null, - job: JobDocPayload, + job: ScheduledTaskParams, context: RequestHandlerContext, req: KibanaRequest -) => Promise; +) => Promise; -export const executeJobFactory: ExecuteJobFactory> = async function executeJobFactoryFn(reporting: ReportingCore, parentLogger: LevelLogger) { +>> = function executeJobFactoryFn(reporting, parentLogger) { const config = reporting.getConfig(); const crypto = cryptoFactory(config.get('encryptionKey')); const logger = parentLogger.clone([CSV_FROM_SAVEDOBJECT_JOB_TYPE, 'execute-job']); const generateCsv = createGenerateCsv(reporting, parentLogger); - return async function executeJob( - jobId: string | null, - job: JobDocPayloadPanelCsv, - context, - req - ): Promise { + return async function runTask(jobId: string | null, job, context, req) { // There will not be a jobID for "immediate" generation. // jobID is only for "queued" jobs // Use the jobID as a logging tag or "immediate" diff --git a/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/types.d.ts b/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/types.d.ts index 36ae5b1dac05ebf..835b352953dfeb0 100644 --- a/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/types.d.ts +++ b/x-pack/plugins/reporting/server/export_types/csv_from_savedobject/types.d.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { JobParamPostPayload, JobDocPayload, TimeRangeParams } from '../../types'; +import { JobParamPostPayload, ScheduledTaskParams, TimeRangeParams } from '../../types'; export interface FakeRequest { headers: Record; @@ -23,7 +23,7 @@ export interface JobParamsPanelCsv { visType?: string; } -export interface JobDocPayloadPanelCsv extends JobDocPayload { +export interface ScheduledTaskParamsPanelCsv extends ScheduledTaskParams { jobParams: JobParamsPanelCsv; } diff --git a/x-pack/plugins/reporting/server/export_types/png/index.ts b/x-pack/plugins/reporting/server/export_types/png/index.ts index a3b51e365e77273..b708448b0f8b24e 100644 --- a/x-pack/plugins/reporting/server/export_types/png/index.ts +++ b/x-pack/plugins/reporting/server/export_types/png/index.ts @@ -14,22 +14,22 @@ import { } from '../../../common/constants'; import { ESQueueCreateJobFn, ESQueueWorkerExecuteFn, ExportTypeDefinition } from '../..//types'; import { metadata } from './metadata'; -import { createJobFactory } from './server/create_job'; -import { executeJobFactory } from './server/execute_job'; -import { JobDocPayloadPNG, JobParamsPNG } from './types'; +import { scheduleTaskFnFactory } from './server/create_job'; +import { runTaskFnFactory } from './server/execute_job'; +import { JobParamsPNG, ScheduledTaskParamsPNG } from './types'; export const getExportType = (): ExportTypeDefinition< JobParamsPNG, ESQueueCreateJobFn, - JobDocPayloadPNG, - ESQueueWorkerExecuteFn + ScheduledTaskParamsPNG, + ESQueueWorkerExecuteFn > => ({ ...metadata, jobType, jobContentEncoding: 'base64', jobContentExtension: 'PNG', - createJobFactory, - executeJobFactory, + scheduleTaskFnFactory, + runTaskFnFactory, validLicenses: [ LICENSE_TYPE_TRIAL, LICENSE_TYPE_STANDARD, diff --git a/x-pack/plugins/reporting/server/export_types/png/server/create_job/index.ts b/x-pack/plugins/reporting/server/export_types/png/server/create_job/index.ts index 3f1556fb2978270..f459b8f249c7060 100644 --- a/x-pack/plugins/reporting/server/export_types/png/server/create_job/index.ts +++ b/x-pack/plugins/reporting/server/export_types/png/server/create_job/index.ts @@ -6,17 +6,17 @@ import { validateUrls } from '../../../../../common/validate_urls'; import { cryptoFactory } from '../../../../lib'; -import { CreateJobFactory, ESQueueCreateJobFn } from '../../../../types'; +import { ESQueueCreateJobFn, ScheduleTaskFnFactory } from '../../../../types'; import { JobParamsPNG } from '../../types'; -export const createJobFactory: CreateJobFactory> = function createJobFactoryFn(reporting) { const config = reporting.getConfig(); const setupDeps = reporting.getPluginSetupDeps(); const crypto = cryptoFactory(config.get('encryptionKey')); - return async function createJob( + return async function scheduleTask( { objectType, title, relativeUrl, browserTimezone, layout }, context, req diff --git a/x-pack/plugins/reporting/server/export_types/png/server/execute_job/index.test.ts b/x-pack/plugins/reporting/server/export_types/png/server/execute_job/index.test.ts index b92f53ff6563f56..3d3f156aeef024a 100644 --- a/x-pack/plugins/reporting/server/export_types/png/server/execute_job/index.test.ts +++ b/x-pack/plugins/reporting/server/export_types/png/server/execute_job/index.test.ts @@ -9,9 +9,9 @@ import { ReportingCore } from '../../../../'; import { CancellationToken } from '../../../../../common'; import { cryptoFactory, LevelLogger } from '../../../../lib'; import { createMockReportingCore } from '../../../../test_helpers'; -import { JobDocPayloadPNG } from '../../types'; +import { ScheduledTaskParamsPNG } from '../../types'; import { generatePngObservableFactory } from '../lib/generate_png'; -import { executeJobFactory } from './'; +import { runTaskFnFactory } from './'; jest.mock('../lib/generate_png', () => ({ generatePngObservableFactory: jest.fn() })); @@ -36,7 +36,7 @@ const encryptHeaders = async (headers: Record) => { return await crypto.encrypt(headers); }; -const getJobDocPayload = (baseObj: any) => baseObj as JobDocPayloadPNG; +const getScheduledTaskParams = (baseObj: any) => baseObj as ScheduledTaskParamsPNG; beforeEach(async () => { const kbnConfig = { @@ -81,11 +81,11 @@ test(`passes browserTimezone to generatePng`, async () => { const generatePngObservable = (await generatePngObservableFactory(mockReporting)) as jest.Mock; generatePngObservable.mockReturnValue(Rx.of(Buffer.from(''))); - const executeJob = await executeJobFactory(mockReporting, getMockLogger()); + const runTask = await runTaskFnFactory(mockReporting, getMockLogger()); const browserTimezone = 'UTC'; - await executeJob( + await runTask( 'pngJobId', - getJobDocPayload({ + getScheduledTaskParams({ relativeUrl: '/app/kibana#/something', browserTimezone, headers: encryptedHeaders, @@ -125,15 +125,15 @@ test(`passes browserTimezone to generatePng`, async () => { }); test(`returns content_type of application/png`, async () => { - const executeJob = await executeJobFactory(mockReporting, getMockLogger()); + const runTask = await runTaskFnFactory(mockReporting, getMockLogger()); const encryptedHeaders = await encryptHeaders({}); const generatePngObservable = await generatePngObservableFactory(mockReporting); (generatePngObservable as jest.Mock).mockReturnValue(Rx.of('foo')); - const { content_type: contentType } = await executeJob( + const { content_type: contentType } = await runTask( 'pngJobId', - getJobDocPayload({ relativeUrl: '/app/kibana#/something', headers: encryptedHeaders }), + getScheduledTaskParams({ relativeUrl: '/app/kibana#/something', headers: encryptedHeaders }), cancellationToken ); expect(contentType).toBe('image/png'); @@ -144,11 +144,11 @@ test(`returns content of generatePng getBuffer base64 encoded`, async () => { const generatePngObservable = await generatePngObservableFactory(mockReporting); (generatePngObservable as jest.Mock).mockReturnValue(Rx.of({ base64: testContent })); - const executeJob = await executeJobFactory(mockReporting, getMockLogger()); + const runTask = await runTaskFnFactory(mockReporting, getMockLogger()); const encryptedHeaders = await encryptHeaders({}); - const { content } = await executeJob( + const { content } = await runTask( 'pngJobId', - getJobDocPayload({ relativeUrl: '/app/kibana#/something', headers: encryptedHeaders }), + getScheduledTaskParams({ relativeUrl: '/app/kibana#/something', headers: encryptedHeaders }), cancellationToken ); diff --git a/x-pack/plugins/reporting/server/export_types/png/server/execute_job/index.ts b/x-pack/plugins/reporting/server/export_types/png/server/execute_job/index.ts index ea4c4b1d106ae5d..c9ab890dc8a5027 100644 --- a/x-pack/plugins/reporting/server/export_types/png/server/execute_job/index.ts +++ b/x-pack/plugins/reporting/server/export_types/png/server/execute_job/index.ts @@ -7,37 +7,35 @@ import apm from 'elastic-apm-node'; import * as Rx from 'rxjs'; import { catchError, map, mergeMap, takeUntil } from 'rxjs/operators'; -import { ReportingCore } from '../../../..'; import { PNG_JOB_TYPE } from '../../../../../common/constants'; -import { ESQueueWorkerExecuteFn, ExecuteJobFactory, JobDocOutput } from '../../../..//types'; -import { LevelLogger } from '../../../../lib'; +import { ESQueueWorkerExecuteFn, RunTaskFnFactory, TaskRunResult } from '../../../..//types'; import { decryptJobHeaders, getConditionalHeaders, getFullUrls, omitBlacklistedHeaders, } from '../../../common/execute_job/'; -import { JobDocPayloadPNG } from '../../types'; +import { ScheduledTaskParamsPNG } from '../../types'; import { generatePngObservableFactory } from '../lib/generate_png'; -type QueuedPngExecutorFactory = ExecuteJobFactory>; +type QueuedPngExecutorFactory = RunTaskFnFactory>; -export const executeJobFactory: QueuedPngExecutorFactory = async function executeJobFactoryFn( - reporting: ReportingCore, - parentLogger: LevelLogger +export const runTaskFnFactory: QueuedPngExecutorFactory = function executeJobFactoryFn( + reporting, + parentLogger ) { const config = reporting.getConfig(); const encryptionKey = config.get('encryptionKey'); const logger = parentLogger.clone([PNG_JOB_TYPE, 'execute']); - return async function executeJob(jobId: string, job: JobDocPayloadPNG, cancellationToken: any) { + return async function runTask(jobId, job, cancellationToken) { const apmTrans = apm.startTransaction('reporting execute_job png', 'reporting'); const apmGetAssets = apmTrans?.startSpan('get_assets', 'setup'); let apmGeneratePng: { end: () => void } | null | undefined; const generatePngObservable = await generatePngObservableFactory(reporting); const jobLogger = logger.clone([jobId]); - const process$: Rx.Observable = Rx.of(1).pipe( + const process$: Rx.Observable = Rx.of(1).pipe( mergeMap(() => decryptJobHeaders({ encryptionKey, job, logger })), map((decryptedHeaders) => omitBlacklistedHeaders({ job, decryptedHeaders })), map((filteredHeaders) => getConditionalHeaders({ config, job, filteredHeaders })), diff --git a/x-pack/plugins/reporting/server/export_types/png/types.d.ts b/x-pack/plugins/reporting/server/export_types/png/types.d.ts index 486a8e91a722f7c..7a25f4ed8fe7357 100644 --- a/x-pack/plugins/reporting/server/export_types/png/types.d.ts +++ b/x-pack/plugins/reporting/server/export_types/png/types.d.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { JobDocPayload } from '../../../server/types'; +import { ScheduledTaskParams } from '../../../server/types'; import { LayoutInstance, LayoutParams } from '../common/layouts'; // Job params: structure of incoming user request data @@ -17,7 +17,7 @@ export interface JobParamsPNG { } // Job payload: structure of stored job data provided by create_job -export interface JobDocPayloadPNG extends JobDocPayload { +export interface ScheduledTaskParamsPNG extends ScheduledTaskParams { basePath?: string; browserTimezone: string; forceNow?: string; diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf/index.ts b/x-pack/plugins/reporting/server/export_types/printable_pdf/index.ts index 39a0cbd5270a188..073bd38b538fbed 100644 --- a/x-pack/plugins/reporting/server/export_types/printable_pdf/index.ts +++ b/x-pack/plugins/reporting/server/export_types/printable_pdf/index.ts @@ -14,22 +14,22 @@ import { } from '../../../common/constants'; import { ESQueueCreateJobFn, ESQueueWorkerExecuteFn, ExportTypeDefinition } from '../../types'; import { metadata } from './metadata'; -import { createJobFactory } from './server/create_job'; -import { executeJobFactory } from './server/execute_job'; -import { JobDocPayloadPDF, JobParamsPDF } from './types'; +import { scheduleTaskFnFactory } from './server/create_job'; +import { runTaskFnFactory } from './server/execute_job'; +import { JobParamsPDF, ScheduledTaskParamsPDF } from './types'; export const getExportType = (): ExportTypeDefinition< JobParamsPDF, ESQueueCreateJobFn, - JobDocPayloadPDF, - ESQueueWorkerExecuteFn + ScheduledTaskParamsPDF, + ESQueueWorkerExecuteFn > => ({ ...metadata, jobType, jobContentEncoding: 'base64', jobContentExtension: 'pdf', - createJobFactory, - executeJobFactory, + scheduleTaskFnFactory, + runTaskFnFactory, validLicenses: [ LICENSE_TYPE_TRIAL, LICENSE_TYPE_STANDARD, diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf/server/create_job/index.ts b/x-pack/plugins/reporting/server/export_types/printable_pdf/server/create_job/index.ts index 06a0902a56954ab..996c4363e7774a8 100644 --- a/x-pack/plugins/reporting/server/export_types/printable_pdf/server/create_job/index.ts +++ b/x-pack/plugins/reporting/server/export_types/printable_pdf/server/create_job/index.ts @@ -6,10 +6,10 @@ import { validateUrls } from '../../../../../common/validate_urls'; import { cryptoFactory } from '../../../../lib'; -import { CreateJobFactory, ESQueueCreateJobFn } from '../../../../types'; +import { ESQueueCreateJobFn, ScheduleTaskFnFactory } from '../../../../types'; import { JobParamsPDF } from '../../types'; -export const createJobFactory: CreateJobFactory> = function createJobFactoryFn(reporting) { const config = reporting.getConfig(); @@ -17,7 +17,7 @@ export const createJobFactory: CreateJobFactory) => { return await crypto.encrypt(headers); }; -const getJobDocPayload = (baseObj: any) => baseObj as JobDocPayloadPDF; +const getScheduledTaskParams = (baseObj: any) => baseObj as ScheduledTaskParamsPDF; beforeEach(async () => { const kbnConfig = { @@ -79,11 +79,11 @@ test(`passes browserTimezone to generatePdf`, async () => { const generatePdfObservable = (await generatePdfObservableFactory(mockReporting)) as jest.Mock; generatePdfObservable.mockReturnValue(Rx.of(Buffer.from(''))); - const executeJob = await executeJobFactory(mockReporting, getMockLogger()); + const runTask = await runTaskFnFactory(mockReporting, getMockLogger()); const browserTimezone = 'UTC'; - await executeJob( + await runTask( 'pdfJobId', - getJobDocPayload({ + getScheduledTaskParams({ relativeUrl: '/app/kibana#/something', browserTimezone, headers: encryptedHeaders, @@ -128,15 +128,15 @@ test(`passes browserTimezone to generatePdf`, async () => { test(`returns content_type of application/pdf`, async () => { const logger = getMockLogger(); - const executeJob = await executeJobFactory(mockReporting, logger); + const runTask = await runTaskFnFactory(mockReporting, logger); const encryptedHeaders = await encryptHeaders({}); const generatePdfObservable = await generatePdfObservableFactory(mockReporting); (generatePdfObservable as jest.Mock).mockReturnValue(Rx.of(Buffer.from(''))); - const { content_type: contentType } = await executeJob( + const { content_type: contentType } = await runTask( 'pdfJobId', - getJobDocPayload({ relativeUrls: [], headers: encryptedHeaders }), + getScheduledTaskParams({ relativeUrls: [], headers: encryptedHeaders }), cancellationToken ); expect(contentType).toBe('application/pdf'); @@ -147,11 +147,11 @@ test(`returns content of generatePdf getBuffer base64 encoded`, async () => { const generatePdfObservable = await generatePdfObservableFactory(mockReporting); (generatePdfObservable as jest.Mock).mockReturnValue(Rx.of({ buffer: Buffer.from(testContent) })); - const executeJob = await executeJobFactory(mockReporting, getMockLogger()); + const runTask = await runTaskFnFactory(mockReporting, getMockLogger()); const encryptedHeaders = await encryptHeaders({}); - const { content } = await executeJob( + const { content } = await runTask( 'pdfJobId', - getJobDocPayload({ relativeUrls: [], headers: encryptedHeaders }), + getScheduledTaskParams({ relativeUrls: [], headers: encryptedHeaders }), cancellationToken ); diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf/server/execute_job/index.ts b/x-pack/plugins/reporting/server/export_types/printable_pdf/server/execute_job/index.ts index a4d84b2f9f1e04f..7f8f2f4f6906ae1 100644 --- a/x-pack/plugins/reporting/server/export_types/printable_pdf/server/execute_job/index.ts +++ b/x-pack/plugins/reporting/server/export_types/printable_pdf/server/execute_job/index.ts @@ -7,10 +7,8 @@ import apm from 'elastic-apm-node'; import * as Rx from 'rxjs'; import { catchError, map, mergeMap, takeUntil } from 'rxjs/operators'; -import { ReportingCore } from '../../../..'; import { PDF_JOB_TYPE } from '../../../../../common/constants'; -import { LevelLogger } from '../../../../lib'; -import { ESQueueWorkerExecuteFn, ExecuteJobFactory, JobDocOutput } from '../../../../types'; +import { ESQueueWorkerExecuteFn, RunTaskFnFactory, TaskRunResult } from '../../../../types'; import { decryptJobHeaders, getConditionalHeaders, @@ -18,21 +16,21 @@ import { getFullUrls, omitBlacklistedHeaders, } from '../../../common/execute_job'; -import { JobDocPayloadPDF } from '../../types'; +import { ScheduledTaskParamsPDF } from '../../types'; import { generatePdfObservableFactory } from '../lib/generate_pdf'; -type QueuedPdfExecutorFactory = ExecuteJobFactory>; +type QueuedPdfExecutorFactory = RunTaskFnFactory>; -export const executeJobFactory: QueuedPdfExecutorFactory = async function executeJobFactoryFn( - reporting: ReportingCore, - parentLogger: LevelLogger +export const runTaskFnFactory: QueuedPdfExecutorFactory = function executeJobFactoryFn( + reporting, + parentLogger ) { const config = reporting.getConfig(); const encryptionKey = config.get('encryptionKey'); const logger = parentLogger.clone([PDF_JOB_TYPE, 'execute']); - return async function executeJob(jobId: string, job: JobDocPayloadPDF, cancellationToken: any) { + return async function runTask(jobId, job, cancellationToken) { const apmTrans = apm.startTransaction('reporting execute_job pdf', 'reporting'); const apmGetAssets = apmTrans?.startSpan('get_assets', 'setup'); let apmGeneratePdf: { end: () => void } | null | undefined; @@ -40,7 +38,7 @@ export const executeJobFactory: QueuedPdfExecutorFactory = async function execut const generatePdfObservable = await generatePdfObservableFactory(reporting); const jobLogger = logger.clone([jobId]); - const process$: Rx.Observable = Rx.of(1).pipe( + const process$: Rx.Observable = Rx.of(1).pipe( mergeMap(() => decryptJobHeaders({ encryptionKey, job, logger })), map((decryptedHeaders) => omitBlacklistedHeaders({ job, decryptedHeaders })), map((filteredHeaders) => getConditionalHeaders({ config, job, filteredHeaders })), diff --git a/x-pack/plugins/reporting/server/export_types/printable_pdf/types.d.ts b/x-pack/plugins/reporting/server/export_types/printable_pdf/types.d.ts index 087ef5a6ca82c70..5399781a77753ed 100644 --- a/x-pack/plugins/reporting/server/export_types/printable_pdf/types.d.ts +++ b/x-pack/plugins/reporting/server/export_types/printable_pdf/types.d.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { JobDocPayload } from '../../../server/types'; +import { ScheduledTaskParams } from '../../../server/types'; import { LayoutInstance, LayoutParams } from '../common/layouts'; // Job params: structure of incoming user request data, after being parsed from RISON @@ -17,7 +17,7 @@ export interface JobParamsPDF { } // Job payload: structure of stored job data provided by create_job -export interface JobDocPayloadPDF extends JobDocPayload { +export interface ScheduledTaskParamsPDF extends ScheduledTaskParams { basePath?: string; browserTimezone: string; forceNow?: string; diff --git a/x-pack/plugins/reporting/server/lib/create_queue.ts b/x-pack/plugins/reporting/server/lib/create_queue.ts index d993a17c0b3146c..5d09af312a41b45 100644 --- a/x-pack/plugins/reporting/server/lib/create_queue.ts +++ b/x-pack/plugins/reporting/server/lib/create_queue.ts @@ -5,7 +5,7 @@ */ import { ReportingCore } from '../core'; -import { JobDocOutput, JobSource } from '../types'; +import { JobSource, TaskRunResult } from '../types'; import { createTaggedLogger } from './create_tagged_logger'; // TODO remove createTaggedLogger once esqueue is removed import { createWorkerFactory } from './create_worker'; import { Job } from './enqueue_job'; @@ -31,11 +31,11 @@ export interface ESQueueInstance { ) => ESQueueWorker; } -// GenericWorkerFn is a generic for ImmediateExecuteFn | ESQueueWorkerExecuteFn, +// GenericWorkerFn is a generic for ImmediateExecuteFn | ESQueueWorkerExecuteFn, type GenericWorkerFn = ( jobSource: JobSource, ...workerRestArgs: any[] -) => void | Promise; +) => void | Promise; export async function createQueueFactory( reporting: ReportingCore, diff --git a/x-pack/plugins/reporting/server/lib/create_worker.test.ts b/x-pack/plugins/reporting/server/lib/create_worker.test.ts index 8e1174e01aa7fea..85188c07eeb2074 100644 --- a/x-pack/plugins/reporting/server/lib/create_worker.test.ts +++ b/x-pack/plugins/reporting/server/lib/create_worker.test.ts @@ -26,7 +26,7 @@ const executeJobFactoryStub = sinon.stub(); const getMockLogger = sinon.stub(); const getMockExportTypesRegistry = ( - exportTypes: any[] = [{ executeJobFactory: executeJobFactoryStub }] + exportTypes: any[] = [{ runTaskFnFactory: executeJobFactoryStub }] ) => ({ getAll: () => exportTypes, @@ -75,11 +75,11 @@ Object { test('Creates a single Esqueue worker for Reporting, even if there are multiple export types', async () => { const exportTypesRegistry = getMockExportTypesRegistry([ - { executeJobFactory: executeJobFactoryStub }, - { executeJobFactory: executeJobFactoryStub }, - { executeJobFactory: executeJobFactoryStub }, - { executeJobFactory: executeJobFactoryStub }, - { executeJobFactory: executeJobFactoryStub }, + { runTaskFnFactory: executeJobFactoryStub }, + { runTaskFnFactory: executeJobFactoryStub }, + { runTaskFnFactory: executeJobFactoryStub }, + { runTaskFnFactory: executeJobFactoryStub }, + { runTaskFnFactory: executeJobFactoryStub }, ]); mockReporting.getExportTypesRegistry = () => exportTypesRegistry; const createWorker = createWorkerFactory(mockReporting, getMockLogger()); diff --git a/x-pack/plugins/reporting/server/lib/create_worker.ts b/x-pack/plugins/reporting/server/lib/create_worker.ts index c9e865668bb301e..837be1f44a09304 100644 --- a/x-pack/plugins/reporting/server/lib/create_worker.ts +++ b/x-pack/plugins/reporting/server/lib/create_worker.ts @@ -27,7 +27,7 @@ export function createWorkerFactory(reporting: ReportingCore, log for (const exportType of reporting.getExportTypesRegistry().getAll() as Array< ExportTypeDefinition> >) { - const jobExecutor = await exportType.executeJobFactory(reporting, logger); // FIXME: does not "need" to be async + const jobExecutor = exportType.runTaskFnFactory(reporting, logger); jobExecutors.set(exportType.jobType, jobExecutor); } diff --git a/x-pack/plugins/reporting/server/lib/enqueue_job.ts b/x-pack/plugins/reporting/server/lib/enqueue_job.ts index 3837f593df5b272..625da90f3b4f235 100644 --- a/x-pack/plugins/reporting/server/lib/enqueue_job.ts +++ b/x-pack/plugins/reporting/server/lib/enqueue_job.ts @@ -52,7 +52,7 @@ export function enqueueJobFactory( context: RequestHandlerContext, request: KibanaRequest ): Promise { - type CreateJobFn = ESQueueCreateJobFn; + type ScheduleTaskFnType = ESQueueCreateJobFn; const username = user ? user.username : false; const esqueue = await reporting.getEsqueue(); const exportType = reporting.getExportTypesRegistry().getById(exportTypeId); @@ -61,8 +61,8 @@ export function enqueueJobFactory( throw new Error(`Export type ${exportTypeId} does not exist in the registry!`); } - const createJob = exportType.createJobFactory(reporting, logger) as CreateJobFn; - const payload = await createJob(jobParams, context, request); + const scheduleTask = exportType.scheduleTaskFnFactory(reporting, logger) as ScheduleTaskFnType; + const payload = await scheduleTask(jobParams, context, request); const options = { timeout: queueTimeout, diff --git a/x-pack/plugins/reporting/server/lib/export_types_registry.ts b/x-pack/plugins/reporting/server/lib/export_types_registry.ts index 893a2635561ff45..501989f21103e74 100644 --- a/x-pack/plugins/reporting/server/lib/export_types_registry.ts +++ b/x-pack/plugins/reporting/server/lib/export_types_registry.ts @@ -5,15 +5,14 @@ */ import { isString } from 'lodash'; -import memoizeOne from 'memoize-one'; import { getExportType as getTypeCsv } from '../export_types/csv'; import { getExportType as getTypeCsvFromSavedObject } from '../export_types/csv_from_savedobject'; import { getExportType as getTypePng } from '../export_types/png'; import { getExportType as getTypePrintablePdf } from '../export_types/printable_pdf'; import { ExportTypeDefinition } from '../types'; -type GetCallbackFn = ( - item: ExportTypeDefinition +type GetCallbackFn = ( + item: ExportTypeDefinition ) => boolean; // => ExportTypeDefinition @@ -22,8 +21,8 @@ export class ExportTypesRegistry { constructor() {} - register( - item: ExportTypeDefinition + register( + item: ExportTypeDefinition ): void { if (!isString(item.id)) { throw new Error(`'item' must have a String 'id' property `); @@ -33,8 +32,6 @@ export class ExportTypesRegistry { throw new Error(`'item' with id ${item.id} has already been registered`); } - // TODO: Unwrap the execute function from the item's executeJobFactory - // Move that work out of server/lib/create_worker to reduce dependence on ESQueue this._map.set(item.id, item); } @@ -46,24 +43,24 @@ export class ExportTypesRegistry { return this._map.size; } - getById( + getById( id: string - ): ExportTypeDefinition { + ): ExportTypeDefinition { if (!this._map.has(id)) { throw new Error(`Unknown id ${id}`); } return this._map.get(id) as ExportTypeDefinition< JobParamsType, - CreateJobFnType, + ScheduleTaskFnType, JobPayloadType, - ExecuteJobFnType + RunTaskFnType >; } - get( - findType: GetCallbackFn - ): ExportTypeDefinition { + get( + findType: GetCallbackFn + ): ExportTypeDefinition { let result; for (const value of this._map.values()) { if (!findType(value)) { @@ -71,9 +68,9 @@ export class ExportTypesRegistry { } const foundResult: ExportTypeDefinition< JobParamsType, - CreateJobFnType, + ScheduleTaskFnType, JobPayloadType, - ExecuteJobFnType + RunTaskFnType > = value; if (result) { @@ -91,7 +88,7 @@ export class ExportTypesRegistry { } } -function getExportTypesRegistryFn(): ExportTypesRegistry { +export function getExportTypesRegistry(): ExportTypesRegistry { const registry = new ExportTypesRegistry(); /* this replaces the previously async method of registering export types, @@ -108,6 +105,3 @@ function getExportTypesRegistryFn(): ExportTypesRegistry { }); return registry; } - -// FIXME: is this the best way to return a singleton? -export const getExportTypesRegistry = memoizeOne(getExportTypesRegistryFn); diff --git a/x-pack/plugins/reporting/server/routes/generate_from_savedobject_immediate.ts b/x-pack/plugins/reporting/server/routes/generate_from_savedobject_immediate.ts index 1221f67855410e0..74e4ba4390d7e1b 100644 --- a/x-pack/plugins/reporting/server/routes/generate_from_savedobject_immediate.ts +++ b/x-pack/plugins/reporting/server/routes/generate_from_savedobject_immediate.ts @@ -7,12 +7,12 @@ import { schema } from '@kbn/config-schema'; import { ReportingCore } from '../'; import { API_BASE_GENERATE_V1 } from '../../common/constants'; -import { createJobFactory } from '../export_types/csv_from_savedobject/server/create_job'; -import { executeJobFactory } from '../export_types/csv_from_savedobject/server/execute_job'; +import { scheduleTaskFnFactory } from '../export_types/csv_from_savedobject/server/create_job'; +import { runTaskFnFactory } from '../export_types/csv_from_savedobject/server/execute_job'; import { getJobParamsFromRequest } from '../export_types/csv_from_savedobject/server/lib/get_job_params_from_request'; -import { JobDocPayloadPanelCsv } from '../export_types/csv_from_savedobject/types'; +import { ScheduledTaskParamsPanelCsv } from '../export_types/csv_from_savedobject/types'; import { LevelLogger as Logger } from '../lib'; -import { JobDocOutput } from '../types'; +import { TaskRunResult } from '../types'; import { authorizedUserPreRoutingFactory } from './lib/authorized_user_pre_routing'; import { HandlerErrorFunction } from './types'; @@ -36,8 +36,8 @@ export function registerGenerateCsvFromSavedObjectImmediate( /* * CSV export with the `immediate` option does not queue a job with Reporting's ESQueue to run the job async. Instead, this does: - * - re-use the createJob function to build up es query config - * - re-use the executeJob function to run the scan and scroll queries and capture the entire CSV in a result object. + * - re-use the scheduleTask function to build up es query config + * - re-use the runTask function to run the scan and scroll queries and capture the entire CSV in a result object. */ router.post( { @@ -60,11 +60,11 @@ export function registerGenerateCsvFromSavedObjectImmediate( userHandler(async (user, context, req, res) => { const logger = parentLogger.clone(['savedobject-csv']); const jobParams = getJobParamsFromRequest(req, { isImmediate: true }); - const createJobFn = createJobFactory(reporting, logger); - const executeJobFn = await executeJobFactory(reporting, logger); // FIXME: does not "need" to be async + const createJobFn = scheduleTaskFnFactory(reporting, logger); + const executeJobFn = await runTaskFnFactory(reporting, logger); // FIXME: does not "need" to be async try { - const jobDocPayload: JobDocPayloadPanelCsv = await createJobFn( + const jobDocPayload: ScheduledTaskParamsPanelCsv = await createJobFn( jobParams, req.headers, context, @@ -74,13 +74,13 @@ export function registerGenerateCsvFromSavedObjectImmediate( content_type: jobOutputContentType, content: jobOutputContent, size: jobOutputSize, - }: JobDocOutput = await executeJobFn(null, jobDocPayload, context, req); + }: TaskRunResult = await executeJobFn(null, jobDocPayload, context, req); logger.info(`Job output size: ${jobOutputSize} bytes`); /* * ESQueue worker function defaults `content` to null, even if the - * executeJob returned undefined. + * runTask returned undefined. * * This converts null to undefined so the value can be sent to h.response() */ diff --git a/x-pack/plugins/reporting/server/routes/lib/get_document_payload.ts b/x-pack/plugins/reporting/server/routes/lib/get_document_payload.ts index e16f5278c8cc715..93f79bfd892b995 100644 --- a/x-pack/plugins/reporting/server/routes/lib/get_document_payload.ts +++ b/x-pack/plugins/reporting/server/routes/lib/get_document_payload.ts @@ -10,7 +10,7 @@ import * as _ from 'lodash'; import { CSV_JOB_TYPE } from '../../../common/constants'; import { statuses } from '../../lib/esqueue/constants/statuses'; import { ExportTypesRegistry } from '../../lib/export_types_registry'; -import { ExportTypeDefinition, JobDocOutput, JobSource } from '../../types'; +import { ExportTypeDefinition, JobSource, TaskRunResult } from '../../types'; type ExportTypeType = ExportTypeDefinition; @@ -18,7 +18,7 @@ interface ErrorFromPayload { message: string; } -// A camelCase version of JobDocOutput +// A camelCase version of TaskRunResult interface Payload { statusCode: number; content: string | Buffer | ErrorFromPayload; @@ -31,7 +31,7 @@ const DEFAULT_TITLE = 'report'; const getTitle = (exportType: ExportTypeType, title?: string): string => `${title || DEFAULT_TITLE}.${exportType.jobContentExtension}`; -const getReportingHeaders = (output: JobDocOutput, exportType: ExportTypeType) => { +const getReportingHeaders = (output: TaskRunResult, exportType: ExportTypeType) => { const metaDataHeaders: Record = {}; if (exportType.jobType === CSV_JOB_TYPE) { @@ -55,7 +55,7 @@ export function getDocumentPayloadFactory(exportTypesRegistry: ExportTypesRegist } } - function getCompleted(output: JobDocOutput, jobType: string, title: string): Payload { + function getCompleted(output: TaskRunResult, jobType: string, title: string): Payload { const exportType = exportTypesRegistry.get((item: ExportTypeType) => item.jobType === jobType); const filename = getTitle(exportType, title); const headers = getReportingHeaders(output, exportType); @@ -73,7 +73,7 @@ export function getDocumentPayloadFactory(exportTypesRegistry: ExportTypesRegist // @TODO: These should be semantic HTTP codes as 500/503's indicate // error then these are really operating properly. - function getFailure(output: JobDocOutput): Payload { + function getFailure(output: TaskRunResult): Payload { return { statusCode: 500, content: { diff --git a/x-pack/plugins/reporting/server/routes/types.d.ts b/x-pack/plugins/reporting/server/routes/types.d.ts index 5eceed0a7f2ab4e..607ce34ab94652d 100644 --- a/x-pack/plugins/reporting/server/routes/types.d.ts +++ b/x-pack/plugins/reporting/server/routes/types.d.ts @@ -6,7 +6,7 @@ import { KibanaRequest, KibanaResponseFactory, RequestHandlerContext } from 'src/core/server'; import { AuthenticatedUser } from '../../../security/server'; -import { JobDocPayload } from '../types'; +import { ScheduledTaskParams } from '../types'; export type HandlerFunction = ( user: AuthenticatedUser | null, @@ -23,7 +23,7 @@ export interface QueuedJobPayload { error?: boolean; source: { job: { - payload: JobDocPayload; + payload: ScheduledTaskParams; }; }; } diff --git a/x-pack/plugins/reporting/server/types.ts b/x-pack/plugins/reporting/server/types.ts index 409a89899bee003..96eef81672610d8 100644 --- a/x-pack/plugins/reporting/server/types.ts +++ b/x-pack/plugins/reporting/server/types.ts @@ -58,7 +58,7 @@ export interface JobParamPostPayload { timerange: TimeRangeParams; } -export interface JobDocPayload { +export interface ScheduledTaskParams { headers?: string; // serialized encrypted headers jobParams: JobParamsType; title: string; @@ -70,13 +70,13 @@ export interface JobSource { _index: string; _source: { jobtype: string; - output: JobDocOutput; - payload: JobDocPayload; + output: TaskRunResult; + payload: ScheduledTaskParams; status: JobStatus; }; } -export interface JobDocOutput { +export interface TaskRunResult { content_type: string; content: string | null; size: number; @@ -173,43 +173,43 @@ export type ReportingSetup = object; * Internal Types */ +export type CaptureConfig = ReportingConfigType['capture']; +export type ScrollConfig = ReportingConfigType['csv']['scroll']; + export type ESQueueCreateJobFn = ( jobParams: JobParamsType, context: RequestHandlerContext, request: KibanaRequest ) => Promise; -export type ESQueueWorkerExecuteFn = ( +export type ESQueueWorkerExecuteFn = ( jobId: string, - job: JobDocPayloadType, - cancellationToken?: CancellationToken + job: ScheduledTaskParamsType, + cancellationToken: CancellationToken ) => Promise; -export type CaptureConfig = ReportingConfigType['capture']; -export type ScrollConfig = ReportingConfigType['csv']['scroll']; - -export type CreateJobFactory = ( +export type ScheduleTaskFnFactory = ( reporting: ReportingCore, logger: LevelLogger -) => CreateJobFnType; +) => ScheduleTaskFnType; -export type ExecuteJobFactory = ( +export type RunTaskFnFactory = ( reporting: ReportingCore, logger: LevelLogger -) => Promise; // FIXME: does not "need" to be async +) => RunTaskFnType; export interface ExportTypeDefinition< JobParamsType, - CreateJobFnType, + ScheduleTaskFnType, JobPayloadType, - ExecuteJobFnType + RunTaskFnType > { id: string; name: string; jobType: string; jobContentEncoding?: string; jobContentExtension: string; - createJobFactory: CreateJobFactory; - executeJobFactory: ExecuteJobFactory; + scheduleTaskFnFactory: ScheduleTaskFnFactory; + runTaskFnFactory: RunTaskFnFactory; validLicenses: string[]; }