diff --git a/x-pack/plugins/reporting/server/routes/common/jobs/constants.ts b/x-pack/plugins/reporting/server/routes/common/jobs/constants.ts new file mode 100644 index 00000000000000..13c2c7ee50bac4 --- /dev/null +++ b/x-pack/plugins/reporting/server/routes/common/jobs/constants.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const STATUS_CODES = { + COMPLETED: 200, + PENDING: { + INTERNAL: 202, + PUBLIC: 503, + }, + FAILED: { + INTERNAL: 202, + PUBLIC: 500, + }, +}; diff --git a/x-pack/plugins/reporting/server/routes/common/jobs/get_document_payload.test.ts b/x-pack/plugins/reporting/server/routes/common/jobs/get_document_payload.test.ts index cbd5f934258475..12de35cd9f32db 100644 --- a/x-pack/plugins/reporting/server/routes/common/jobs/get_document_payload.test.ts +++ b/x-pack/plugins/reporting/server/routes/common/jobs/get_document_payload.test.ts @@ -13,8 +13,10 @@ import { CSV_JOB_TYPE } from '@kbn/reporting-export-types-csv-common'; import { PDF_JOB_TYPE, PDF_JOB_TYPE_V2 } from '@kbn/reporting-export-types-pdf-common'; import { createMockConfigSchema } from '@kbn/reporting-mocks-server'; +import { ReportingCore } from '../../..'; import { ContentStream, getContentStream } from '../../../lib'; import { createMockReportingCore } from '../../../test_helpers'; +import { STATUS_CODES } from './constants'; import { getDocumentPayloadFactory } from './get_document_payload'; import { jobsQueryFactory } from './jobs_query'; @@ -22,13 +24,14 @@ jest.mock('../../../lib/content_stream'); jest.mock('./jobs_query'); describe('getDocumentPayload', () => { + let core: ReportingCore; let getDocumentPayload: ReturnType; beforeEach(async () => { const schema = createMockConfigSchema(); - const core = await createMockReportingCore(schema); + core = await createMockReportingCore(schema); - getDocumentPayload = getDocumentPayloadFactory(core); + getDocumentPayload = getDocumentPayloadFactory(core, { isInternal: false }); (getContentStream as jest.MockedFunction).mockResolvedValue( new Readable({ @@ -66,7 +69,7 @@ describe('getDocumentPayload', () => { headers: expect.objectContaining({ 'Content-Length': '1024', }), - statusCode: 200, + statusCode: STATUS_CODES.COMPLETED, }) ); }); @@ -96,57 +99,115 @@ describe('getDocumentPayload', () => { 'kbn-csv-contains-formulas': true, 'kbn-max-size-reached': true, }), - statusCode: 200, + statusCode: STATUS_CODES.COMPLETED, }) ); }); }); - describe('when the report is failed', () => { - it('should return payload for the failed report', async () => { - await expect( - getDocumentPayload({ - id: 'id1', - index: '.reporting-12345', - status: JOB_STATUS.FAILED, - jobtype: PDF_JOB_TYPE_V2, - output: {}, - payload: {}, - } as ReportApiJSON) - ).resolves.toEqual( - expect.objectContaining({ - contentType: 'application/json', - content: { - message: expect.stringContaining('Some error'), - }, - headers: {}, - statusCode: 500, - }) - ); + describe('public API behavior', () => { + beforeEach(() => { + getDocumentPayload = getDocumentPayloadFactory(core, { isInternal: false }); + }); + + describe('when the report is failed', () => { + it('should return payload for the failed report', async () => { + await expect( + getDocumentPayload({ + id: 'id1', + index: '.reporting-12345', + status: JOB_STATUS.FAILED, + jobtype: PDF_JOB_TYPE_V2, + output: {}, + payload: {}, + } as ReportApiJSON) + ).resolves.toEqual( + expect.objectContaining({ + contentType: 'application/json', + content: { + message: expect.stringContaining('Some error'), + }, + headers: {}, + statusCode: STATUS_CODES.FAILED.PUBLIC, + }) + ); + }); + }); + + describe('when the report is incomplete', () => { + it('should return payload for the pending report', async () => { + await expect( + getDocumentPayload({ + id: 'id1', + index: '.reporting-12345', + status: JOB_STATUS.PENDING, + jobtype: PDF_JOB_TYPE_V2, + output: {}, + payload: {}, + } as ReportApiJSON) + ).resolves.toEqual( + expect.objectContaining({ + contentType: 'text/plain', + content: 'pending', + headers: { + 'retry-after': '30', + }, + statusCode: STATUS_CODES.PENDING.PUBLIC, + }) + ); + }); }); }); - describe('when the report is incomplete', () => { - it('should return payload for the pending report', async () => { - await expect( - getDocumentPayload({ - id: 'id1', - index: '.reporting-12345', - status: JOB_STATUS.PENDING, - jobtype: PDF_JOB_TYPE_V2, - output: {}, - payload: {}, - } as ReportApiJSON) - ).resolves.toEqual( - expect.objectContaining({ - contentType: 'text/plain', - content: 'pending', - headers: { - 'retry-after': '30', - }, - statusCode: 503, - }) - ); + describe('internal API behavior', () => { + beforeEach(() => { + getDocumentPayload = getDocumentPayloadFactory(core, { isInternal: true }); + }); + + describe('when the report is failed', () => { + it('should return payload for the failed report', async () => { + await expect( + getDocumentPayload({ + id: 'id1', + index: '.reporting-12345', + status: JOB_STATUS.FAILED, + jobtype: PDF_JOB_TYPE_V2, + output: {}, + payload: {}, + } as ReportApiJSON) + ).resolves.toEqual( + expect.objectContaining({ + contentType: 'application/json', + content: { + message: expect.stringContaining('Some error'), + }, + headers: {}, + statusCode: STATUS_CODES.FAILED.INTERNAL, + }) + ); + }); + }); + + describe('when the report is incomplete', () => { + it('should return payload for the pending report', async () => { + await expect( + getDocumentPayload({ + id: 'id1', + index: '.reporting-12345', + status: JOB_STATUS.PENDING, + jobtype: PDF_JOB_TYPE_V2, + output: {}, + payload: {}, + } as ReportApiJSON) + ).resolves.toEqual( + expect.objectContaining({ + contentType: 'text/plain', + content: 'pending', + headers: { 'retry-after': '30' }, + statusCode: STATUS_CODES.PENDING.INTERNAL, + }) + ); + }); }); }); }); diff --git a/x-pack/plugins/reporting/server/routes/common/jobs/get_document_payload.ts b/x-pack/plugins/reporting/server/routes/common/jobs/get_document_payload.ts index c77e04ec66c22e..2a20fa0b475c4e 100644 --- a/x-pack/plugins/reporting/server/routes/common/jobs/get_document_payload.ts +++ b/x-pack/plugins/reporting/server/routes/common/jobs/get_document_payload.ts @@ -8,13 +8,14 @@ import { Stream } from 'stream'; import { ResponseHeaders } from '@kbn/core-http-server'; +import { JOB_STATUS } from '@kbn/reporting-common'; import { ReportApiJSON } from '@kbn/reporting-common/types'; import { CSV_JOB_TYPE, CSV_JOB_TYPE_DEPRECATED } from '@kbn/reporting-export-types-csv-common'; -import { JOB_STATUS } from '@kbn/reporting-common'; import { ExportType } from '@kbn/reporting-server'; import { ReportingCore } from '../../..'; import { getContentStream } from '../../../lib'; +import { STATUS_CODES } from './constants'; import { jobsQueryFactory } from './jobs_query'; export interface ErrorFromPayload { @@ -53,7 +54,10 @@ const getReportingHeaders = (output: TaskRunResult, exportType: ExportType) => { return metaDataHeaders; }; -export function getDocumentPayloadFactory(reporting: ReportingCore) { +export function getDocumentPayloadFactory( + reporting: ReportingCore, + { isInternal }: { isInternal: boolean } +) { const { logger: _logger } = reporting.getPluginSetupDeps(); const logger = _logger.get('download-report'); const exportTypesRegistry = reporting.getExportTypesRegistry(); @@ -75,7 +79,7 @@ export function getDocumentPayloadFactory(reporting: ReportingCore) { return { filename, content, - statusCode: 200, + statusCode: STATUS_CODES.COMPLETED, contentType, headers: { ...headers, @@ -84,29 +88,29 @@ export function getDocumentPayloadFactory(reporting: ReportingCore) { }; } - // @TODO: These should be semantic HTTP codes as 500/503's indicate - // error then these are really operating properly. async function getFailure({ id }: ReportApiJSON): Promise { - const jobsQuery = jobsQueryFactory(reporting); + const jobsQuery = jobsQueryFactory(reporting, { isInternal }); const error = await jobsQuery.getError(id); - logger.debug(`Report job ${id} has failed. Sending statusCode: 500`); + // For download requested over public API, status code for failed job must be 500 to integrate with Watcher + const statusCode = isInternal ? STATUS_CODES.FAILED.INTERNAL : STATUS_CODES.FAILED.PUBLIC; + logger.debug(`Report job ${id} has failed. Sending statusCode: ${statusCode}`); return { - statusCode: 500, - content: { - message: `Reporting generation failed: ${error}`, - }, + statusCode, + content: { message: `Reporting generation failed: ${error}` }, contentType: 'application/json', headers: {}, }; } function getIncomplete({ id, status }: ReportApiJSON): Payload { - logger.debug(`Report job ${id} is processing. Sending statusCode: 503`); + // For download requested over public API, status code for processing/pending job must be 503 to integrate with Watcher + const statusCode = isInternal ? STATUS_CODES.PENDING.INTERNAL : STATUS_CODES.PENDING.PUBLIC; + logger.debug(`Report job ${id} is processing. Sending statusCode: ${statusCode}`); return { - statusCode: 503, + statusCode, content: status, contentType: 'text/plain', headers: { 'retry-after': '30' }, @@ -124,7 +128,6 @@ export function getDocumentPayloadFactory(reporting: ReportingCore) { } } - // send a 503 indicating that the report isn't completed yet return getIncomplete(report); }; } diff --git a/x-pack/plugins/reporting/server/routes/common/jobs/get_job_routes.ts b/x-pack/plugins/reporting/server/routes/common/jobs/get_job_routes.ts index 64a3b0224ad712..dc01a29db780ae 100644 --- a/x-pack/plugins/reporting/server/routes/common/jobs/get_job_routes.ts +++ b/x-pack/plugins/reporting/server/routes/common/jobs/get_job_routes.ts @@ -30,8 +30,11 @@ interface HandlerOpts { res: KibanaResponseFactory; } -export const commonJobsRouteHandlerFactory = (reporting: ReportingCore) => { - const jobsQuery = jobsQueryFactory(reporting); +export const commonJobsRouteHandlerFactory = ( + reporting: ReportingCore, + { isInternal }: { isInternal: boolean } +) => { + const jobsQuery = jobsQueryFactory(reporting, { isInternal }); const handleDownloadReport = ({ path, user, context, req, res }: HandlerOpts) => { const counters = getCounters(req.route.method, path, reporting.getUsageCounter()); @@ -43,36 +46,48 @@ export const commonJobsRouteHandlerFactory = (reporting: ReportingCore) => { const { docId } = req.params; - return jobManagementPreRouting(reporting, res, docId, user, counters, async (doc) => { - const payload = await jobsQuery.getDocumentPayload(doc); - const { contentType, content, filename, statusCode } = payload; - - if (!contentType || !ALLOWED_JOB_CONTENT_TYPES.includes(contentType)) { - return res.badRequest({ - body: `Unsupported content-type of ${contentType} specified by job output`, - }); - } - - const body = typeof content === 'string' ? Buffer.from(content) : content; - - const headers = { - ...payload.headers, - 'content-type': contentType, - }; - - if (filename) { - // event tracking of the downloaded file, if - // the report job was completed successfully - // and a file is available - const eventTracker = reporting.getEventTracker(docId, doc.jobtype, doc.payload.objectType); - const timeSinceCreation = Date.now() - new Date(doc.created_at).valueOf(); - eventTracker?.downloadReport({ timeSinceCreation }); - - return res.file({ body, headers, filename }); + return jobManagementPreRouting( + reporting, + res, + docId, + user, + counters, + { isInternal }, + async (doc) => { + const payload = await jobsQuery.getDocumentPayload(doc); + const { contentType, content, filename, statusCode } = payload; + + if (!contentType || !ALLOWED_JOB_CONTENT_TYPES.includes(contentType)) { + return res.badRequest({ + body: `Unsupported content-type of ${contentType} specified by job output`, + }); + } + + const body = typeof content === 'string' ? Buffer.from(content) : content; + + const headers = { + ...payload.headers, + 'content-type': contentType, + }; + + if (filename) { + // event tracking of the downloaded file, if + // the report job was completed successfully + // and a file is available + const eventTracker = reporting.getEventTracker( + docId, + doc.jobtype, + doc.payload.objectType + ); + const timeSinceCreation = Date.now() - new Date(doc.created_at).valueOf(); + eventTracker?.downloadReport({ timeSinceCreation }); + + return res.file({ body, headers, filename }); + } + + return res.custom({ body, headers, statusCode }); } - - return res.custom({ body, headers, statusCode }); - }); + ); }; const handleDeleteReport = ({ path, user, context, req, res }: HandlerOpts) => { @@ -85,52 +100,64 @@ export const commonJobsRouteHandlerFactory = (reporting: ReportingCore) => { const { docId } = req.params; - return jobManagementPreRouting(reporting, res, docId, user, counters, async (doc) => { - const docIndex = doc.index; - const stream = await getContentStream(reporting, { id: docId, index: docIndex }); - const reportingSetup = reporting.getPluginSetupDeps(); - const logger = reportingSetup.logger.get('delete-report'); - - // An "error" event is emitted if an error is - // passed to the `stream.end` callback from - // the _final method of the ContentStream. - // This event must be handled. - stream.on('error', (err) => { - logger.error(err); - }); - - try { - // Overwriting existing content with an - // empty buffer to remove all the chunks. - await new Promise((resolve, reject) => { - stream.end('', 'utf8', (error?: Error) => { - if (error) { - // handle error that could be thrown - // from the _write method of the ContentStream - reject(error); - } else { - resolve(); - } - }); + return jobManagementPreRouting( + reporting, + res, + docId, + user, + counters, + { isInternal }, + async (doc) => { + const docIndex = doc.index; + const stream = await getContentStream(reporting, { id: docId, index: docIndex }); + const reportingSetup = reporting.getPluginSetupDeps(); + const logger = reportingSetup.logger.get('delete-report'); + + // An "error" event is emitted if an error is + // passed to the `stream.end` callback from + // the _final method of the ContentStream. + // This event must be handled. + stream.on('error', (err) => { + logger.error(err); }); - await jobsQuery.delete(docIndex, docId); + try { + // Overwriting existing content with an + // empty buffer to remove all the chunks. + await new Promise((resolve, reject) => { + stream.end('', 'utf8', (error?: Error) => { + if (error) { + // handle error that could be thrown + // from the _write method of the ContentStream + reject(error); + } else { + resolve(); + } + }); + }); - // event tracking of the deleted report - const eventTracker = reporting.getEventTracker(docId, doc.jobtype, doc.payload.objectType); - const timeSinceCreation = Date.now() - new Date(doc.created_at).valueOf(); - eventTracker?.deleteReport({ timeSinceCreation }); + await jobsQuery.delete(docIndex, docId); - return res.ok({ - body: { deleted: true }, - }); - } catch (error) { - logger.error(error); - return res.customError({ - statusCode: 500, - }); + // event tracking of the deleted report + const eventTracker = reporting.getEventTracker( + docId, + doc.jobtype, + doc.payload.objectType + ); + const timeSinceCreation = Date.now() - new Date(doc.created_at).valueOf(); + eventTracker?.deleteReport({ timeSinceCreation }); + + return res.ok({ + body: { deleted: true }, + }); + } catch (error) { + logger.error(error); + return res.customError({ + statusCode: 500, + }); + } } - }); + ); }; return { diff --git a/x-pack/plugins/reporting/server/routes/common/jobs/job_management_pre_routing.test.ts b/x-pack/plugins/reporting/server/routes/common/jobs/job_management_pre_routing.test.ts index cc06ef2e0826ca..2f796fd83fbe0e 100644 --- a/x-pack/plugins/reporting/server/routes/common/jobs/job_management_pre_routing.test.ts +++ b/x-pack/plugins/reporting/server/routes/common/jobs/job_management_pre_routing.test.ts @@ -31,6 +31,7 @@ const mockCounters = { errorCounter: jest.fn(), }; const mockUser = { username: 'joeuser' }; +const options = { isInternal: false }; beforeEach(async () => { mockSetupDeps = createMockPluginSetup({ @@ -70,6 +71,7 @@ it(`should return 404 if the docId isn't resolve`, async function () { 'doc123', mockUser, mockCounters, + options, handler ); @@ -97,6 +99,7 @@ it(`should return forbidden if job type is unrecognized`, async function () { 'doc123', mockUser, mockCounters, + options, handler ); @@ -124,6 +127,7 @@ it(`should call callback when document is available`, async function () { 'doc123', mockUser, mockCounters, + options, handler ); @@ -154,6 +158,7 @@ describe('usage counters', () => { 'doc123', mockUser, mockCounters, + options, handler ); @@ -177,6 +182,7 @@ describe('usage counters', () => { 'doc123', mockUser, mockCounters, + options, handler ); diff --git a/x-pack/plugins/reporting/server/routes/common/jobs/job_management_pre_routing.ts b/x-pack/plugins/reporting/server/routes/common/jobs/job_management_pre_routing.ts index e9e89c61289b73..e42874468cccf4 100644 --- a/x-pack/plugins/reporting/server/routes/common/jobs/job_management_pre_routing.ts +++ b/x-pack/plugins/reporting/server/routes/common/jobs/job_management_pre_routing.ts @@ -29,6 +29,7 @@ export const jobManagementPreRouting = async ( jobId: JobId, user: ReportingUser, counters: Counters, + { isInternal }: { isInternal: boolean }, cb: JobManagementResponseHandler ) => { const licenseInfo = await reporting.getLicenseInfo(); @@ -36,7 +37,7 @@ export const jobManagementPreRouting = async ( management: { jobTypes = [] }, } = licenseInfo; - const jobsQuery = jobsQueryFactory(reporting); + const jobsQuery = jobsQueryFactory(reporting, { isInternal }); const doc = await jobsQuery.get(user, jobId); if (!doc) { diff --git a/x-pack/plugins/reporting/server/routes/common/jobs/jobs_query.test.ts b/x-pack/plugins/reporting/server/routes/common/jobs/jobs_query.test.ts index 616079c0aa27eb..8875c7eb874c75 100644 --- a/x-pack/plugins/reporting/server/routes/common/jobs/jobs_query.test.ts +++ b/x-pack/plugins/reporting/server/routes/common/jobs/jobs_query.test.ts @@ -23,7 +23,7 @@ describe('jobsQuery', () => { const core = await createMockReportingCore(schema); client = (await core.getEsClient()).asInternalUser as typeof client; - jobsQuery = jobsQueryFactory(core); + jobsQuery = jobsQueryFactory(core, { isInternal: false }); }); describe('list', () => { diff --git a/x-pack/plugins/reporting/server/routes/common/jobs/jobs_query.ts b/x-pack/plugins/reporting/server/routes/common/jobs/jobs_query.ts index 56b0ac4677449e..3d602bf81f44fa 100644 --- a/x-pack/plugins/reporting/server/routes/common/jobs/jobs_query.ts +++ b/x-pack/plugins/reporting/server/routes/common/jobs/jobs_query.ts @@ -53,7 +53,10 @@ export interface JobsQueryFactory { delete(deleteIndex: string, id: string): Promise>; } -export function jobsQueryFactory(reportingCore: ReportingCore): JobsQueryFactory { +export function jobsQueryFactory( + reportingCore: ReportingCore, + { isInternal }: { isInternal: boolean } +): JobsQueryFactory { async function execQuery< T extends (client: ElasticsearchClient) => Promise> | undefined> >(callback: T): Promise> | undefined> { @@ -202,7 +205,7 @@ export function jobsQueryFactory(reportingCore: ReportingCore): JobsQueryFactory }, async getDocumentPayload(doc: ReportApiJSON) { - const getDocumentPayload = getDocumentPayloadFactory(reportingCore); + const getDocumentPayload = getDocumentPayloadFactory(reportingCore, { isInternal }); return await getDocumentPayload(doc); }, diff --git a/x-pack/plugins/reporting/server/routes/internal/management/integration_tests/jobs.test.ts b/x-pack/plugins/reporting/server/routes/internal/management/integration_tests/jobs.test.ts index e145598eb7d761..143922d2cfeddd 100644 --- a/x-pack/plugins/reporting/server/routes/internal/management/integration_tests/jobs.test.ts +++ b/x-pack/plugins/reporting/server/routes/internal/management/integration_tests/jobs.test.ts @@ -34,6 +34,7 @@ import { } from '../../../../test_helpers'; import { ReportingRequestHandlerContext } from '../../../../types'; import { EventTracker } from '../../../../usage'; +import { STATUS_CODES } from '../../../common/jobs/constants'; import { registerJobInfoRoutesInternal as registerJobInfoRoutes } from '../jobs'; type SetupServerReturn = Awaited>; @@ -254,7 +255,7 @@ describe(`Reporting Job Management Routes: Internal`, () => { .expect(403); }); - it('when a job is incomplete', async () => { + it('when a job is incomplete, "internal" API endpoint should return appropriate response', async () => { mockEsClient.search.mockResponseOnce( getHits({ jobtype: mockJobTypeUnencoded, @@ -267,13 +268,13 @@ describe(`Reporting Job Management Routes: Internal`, () => { await server.start(); await supertest(httpSetup.server.listener) .get(`${INTERNAL_ROUTES.JOBS.DOWNLOAD_PREFIX}/dank`) - .expect(503) + .expect(STATUS_CODES.PENDING.INTERNAL) .expect('Content-Type', 'text/plain; charset=utf-8') .expect('Retry-After', '30') .then(({ text }) => expect(text).toEqual('pending')); }); - it('when a job fails', async () => { + it('when a job fails, "internal" API endpoint should return appropriate response', async () => { mockEsClient.search.mockResponse( getHits({ jobtype: mockJobTypeUnencoded, @@ -287,7 +288,7 @@ describe(`Reporting Job Management Routes: Internal`, () => { await server.start(); await supertest(httpSetup.server.listener) .get(`${INTERNAL_ROUTES.JOBS.DOWNLOAD_PREFIX}/dank`) - .expect(500) + .expect(STATUS_CODES.FAILED.INTERNAL) .expect('Content-Type', 'application/json; charset=utf-8') .then(({ body }) => expect(body.message).toEqual('Reporting generation failed: job failure message') @@ -301,7 +302,7 @@ describe(`Reporting Job Management Routes: Internal`, () => { await server.start(); await supertest(httpSetup.server.listener) .get(`${INTERNAL_ROUTES.JOBS.DOWNLOAD_PREFIX}/dank`) - .expect(200) + .expect(STATUS_CODES.COMPLETED) .expect('Content-Type', 'text/csv; charset=utf-8') .expect('content-disposition', 'attachment; filename=report.csv'); }); @@ -318,7 +319,7 @@ describe(`Reporting Job Management Routes: Internal`, () => { await supertest(httpSetup.server.listener) .get(`${INTERNAL_ROUTES.JOBS.DOWNLOAD_PREFIX}/dope`) - .expect(200) + .expect(STATUS_CODES.COMPLETED) .expect('Content-Type', 'text/csv; charset=utf-8') .expect('content-disposition', 'attachment; filename=report.csv'); }); @@ -334,7 +335,7 @@ describe(`Reporting Job Management Routes: Internal`, () => { await server.start(); await supertest(httpSetup.server.listener) .get(`${INTERNAL_ROUTES.JOBS.DOWNLOAD_PREFIX}/dank`) - .expect(200) + .expect(STATUS_CODES.COMPLETED) .expect('Content-Type', 'text/csv; charset=utf-8') .then(({ text }) => expect(text).toEqual('test')); }); @@ -373,7 +374,7 @@ describe(`Reporting Job Management Routes: Internal`, () => { await server.start(); await supertest(httpSetup.server.listener) .get(`${INTERNAL_ROUTES.JOBS.DOWNLOAD_PREFIX}/japanese-dashboard`) - .expect(200) + .expect(STATUS_CODES.COMPLETED) .expect('Content-Type', 'application/pdf') .expect( 'content-disposition', @@ -446,7 +447,7 @@ describe(`Reporting Job Management Routes: Internal`, () => { await server.start(); await supertest(httpSetup.server.listener) .get(`${INTERNAL_ROUTES.JOBS.DOWNLOAD_PREFIX}/dank`) - .expect(200) + .expect(STATUS_CODES.COMPLETED) .expect('Content-Type', 'text/csv; charset=utf-8') .expect('content-disposition', 'attachment; filename=report.csv'); diff --git a/x-pack/plugins/reporting/server/routes/internal/management/jobs.ts b/x-pack/plugins/reporting/server/routes/internal/management/jobs.ts index 44a085a76dd916..21e7b92cc4b8f1 100644 --- a/x-pack/plugins/reporting/server/routes/internal/management/jobs.ts +++ b/x-pack/plugins/reporting/server/routes/internal/management/jobs.ts @@ -22,7 +22,7 @@ const { JOBS } = INTERNAL_ROUTES; export function registerJobInfoRoutesInternal(reporting: ReportingCore) { const setupDeps = reporting.getPluginSetupDeps(); const { router } = setupDeps; - const jobsQuery = jobsQueryFactory(reporting); + const jobsQuery = jobsQueryFactory(reporting, { isInternal: true }); const registerInternalGetList = () => { // list jobs in the queue, paginated @@ -105,7 +105,7 @@ export function registerJobInfoRoutesInternal(reporting: ReportingCore) { }; // use common route handlers that are shared for public and internal routes - const jobHandlers = commonJobsRouteHandlerFactory(reporting); + const jobHandlers = commonJobsRouteHandlerFactory(reporting, { isInternal: true }); const registerInternalGetInfo = () => { // return some info about the job @@ -126,13 +126,20 @@ export function registerJobInfoRoutesInternal(reporting: ReportingCore) { } const { docId } = req.params; - return jobManagementPreRouting(reporting, res, docId, user, counters, async (doc) => - res.ok({ - body: doc, - headers: { - 'content-type': 'application/json', - }, - }) + return jobManagementPreRouting( + reporting, + res, + docId, + user, + counters, + { isInternal: true }, + async (doc) => + res.ok({ + body: doc, + headers: { + 'content-type': 'application/json', + }, + }) ); }) ); diff --git a/x-pack/plugins/reporting/server/routes/public/jobs.ts b/x-pack/plugins/reporting/server/routes/public/jobs.ts index 54ebf3d4e0c1c4..04d417c4eb89fb 100644 --- a/x-pack/plugins/reporting/server/routes/public/jobs.ts +++ b/x-pack/plugins/reporting/server/routes/public/jobs.ts @@ -16,7 +16,7 @@ export function registerJobInfoRoutesPublic(reporting: ReportingCore) { const { router } = setupDeps; // use common route handlers that are shared for public and internal routes - const jobHandlers = commonJobsRouteHandlerFactory(reporting); + const jobHandlers = commonJobsRouteHandlerFactory(reporting, { isInternal: false }); const registerPublicDownloadReport = () => { // trigger a download of the output from a job