Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[7.x] [Reporting] remove async execution from csv_from_savedobject (#71031) #71281

Merged
merged 2 commits into from
Jul 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ export { runTaskFnFactory } from './server/execute_job';

export const getExportType = (): ExportTypeDefinition<
JobParamsPanelCsv,
ImmediateCreateJobFn<JobParamsPanelCsv>,
ImmediateCreateJobFn,
JobParamsPanelCsv,
ImmediateExecuteFn<JobParamsPanelCsv>
ImmediateExecuteFn
> => ({
...metadata,
jobType: CSV_FROM_SAVEDOBJECT_JOB_TYPE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ import {
} from '../../types';
import { createJobSearch } from './create_job_search';

export type ImmediateCreateJobFn<JobParamsType> = (
jobParams: JobParamsType,
export type ImmediateCreateJobFn = (
jobParams: JobParamsPanelCsv,
headers: KibanaRequest['headers'],
context: RequestHandlerContext,
req: KibanaRequest
) => Promise<{
type: string | null;
title: string;
jobParams: JobParamsType;
jobParams: JobParamsPanelCsv;
}>;

interface VisData {
Expand All @@ -37,9 +37,10 @@ interface VisData {
panel: SearchPanel;
}

export const scheduleTaskFnFactory: ScheduleTaskFnFactory<ImmediateCreateJobFn<
JobParamsPanelCsv
>> = function createJobFactoryFn(reporting, parentLogger) {
export const scheduleTaskFnFactory: ScheduleTaskFnFactory<ImmediateCreateJobFn> = 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']);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,43 @@
import { i18n } from '@kbn/i18n';
import { KibanaRequest, RequestHandlerContext } from 'src/core/server';
import { CONTENT_TYPE_CSV, CSV_FROM_SAVEDOBJECT_JOB_TYPE } from '../../../../common/constants';
import { cryptoFactory } from '../../../lib';
import { RunTaskFnFactory, ScheduledTaskParams, TaskRunResult } from '../../../types';
import { CsvResultFromSearch } from '../../csv/types';
import { FakeRequest, JobParamsPanelCsv, SearchPanel } from '../types';
import { JobParamsPanelCsv, SearchPanel } from '../types';
import { createGenerateCsv } from './lib';

/*
* The run function receives the full request which provides the un-encrypted
* headers, so encrypted headers are not part of these kind of job params
*/
type ImmediateJobParams = Omit<ScheduledTaskParams<JobParamsPanelCsv>, 'headers'>;

/*
* ImmediateExecuteFn receives the job doc payload because the payload was
* generated in the ScheduleFn
*/
export type ImmediateExecuteFn<JobParamsType> = (
export type ImmediateExecuteFn = (
jobId: null,
job: ScheduledTaskParams<JobParamsType>,
job: ImmediateJobParams,
context: RequestHandlerContext,
req: KibanaRequest
) => Promise<TaskRunResult>;

export const runTaskFnFactory: RunTaskFnFactory<ImmediateExecuteFn<
JobParamsPanelCsv
>> = function executeJobFactoryFn(reporting, parentLogger) {
const config = reporting.getConfig();
const crypto = cryptoFactory(config.get('encryptionKey'));
export const runTaskFnFactory: RunTaskFnFactory<ImmediateExecuteFn> = function executeJobFactoryFn(
reporting,
parentLogger
) {
const logger = parentLogger.clone([CSV_FROM_SAVEDOBJECT_JOB_TYPE, 'execute-job']);
const generateCsv = createGenerateCsv(reporting, parentLogger);

return async function runTask(jobId: string | null, job, context, req) {
return async function runTask(jobId: string | null, job, context, request) {
// There will not be a jobID for "immediate" generation.
// jobID is only for "queued" jobs
// Use the jobID as a logging tag or "immediate"
const jobLogger = logger.clone([jobId === null ? 'immediate' : jobId]);

const { jobParams } = job;
const { isImmediate, panel, visType } = jobParams as JobParamsPanelCsv & { panel: SearchPanel };
const { panel, visType } = jobParams as JobParamsPanelCsv & { panel: SearchPanel };

if (!panel) {
i18n.translate(
Expand All @@ -50,54 +54,13 @@ export const runTaskFnFactory: RunTaskFnFactory<ImmediateExecuteFn<

jobLogger.debug(`Execute job generating [${visType}] csv`);

let requestObject: KibanaRequest | FakeRequest;

if (isImmediate && req) {
jobLogger.info(`Executing job from Immediate API using request context`);
requestObject = req;
} else {
jobLogger.info(`Executing job async using encrypted headers`);
let decryptedHeaders: Record<string, unknown>;
const serializedEncryptedHeaders = job.headers;
try {
if (typeof serializedEncryptedHeaders !== 'string') {
throw new Error(
i18n.translate(
'xpack.reporting.exportTypes.csv_from_savedobject.executeJob.missingJobHeadersErrorMessage',
{
defaultMessage: 'Job headers are missing',
}
)
);
}
decryptedHeaders = (await crypto.decrypt(serializedEncryptedHeaders)) as Record<
string,
unknown
>;
} catch (err) {
jobLogger.error(err);
throw new Error(
i18n.translate(
'xpack.reporting.exportTypes.csv_from_savedobject.executeJob.failedToDecryptReportJobDataErrorMessage',
{
defaultMessage:
'Failed to decrypt report job data. Please ensure that {encryptionKey} is set and re-generate this report. {err}',
values: { encryptionKey: 'xpack.reporting.encryptionKey', err },
}
)
);
}

requestObject = { headers: decryptedHeaders };
}

let content: string;
let maxSizeReached = false;
let size = 0;
try {
const generateResults: CsvResultFromSearch = await generateCsv(
context,
requestObject,
request,
visType as string,
panel,
jobParams
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ export interface JobParamsPanelCsv {
visType?: string;
}

export interface ScheduledTaskParamsPanelCsv extends ScheduledTaskParams<JobParamsPanelCsv> {
jobParams: JobParamsPanelCsv;
}

export interface SavedObjectServiceError {
statusCode: number;
error?: string;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { API_BASE_GENERATE_V1 } from '../../common/constants';
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 { ScheduledTaskParamsPanelCsv } from '../export_types/csv_from_savedobject/types';
import { LevelLogger as Logger } from '../lib';
import { TaskRunResult } from '../types';
import { authorizedUserPreRoutingFactory } from './lib/authorized_user_pre_routing';
Expand Down Expand Up @@ -64,12 +63,8 @@ export function registerGenerateCsvFromSavedObjectImmediate(
const runTaskFn = runTaskFnFactory(reporting, logger);

try {
const jobDocPayload: ScheduledTaskParamsPanelCsv = await scheduleTaskFn(
jobParams,
req.headers,
context,
req
);
// FIXME: no scheduleTaskFn for immediate download
const jobDocPayload = await scheduleTaskFn(jobParams, req.headers, context, req);
const {
content_type: jobOutputContentType,
content: jobOutputContent,
Expand All @@ -91,11 +86,12 @@ export function registerGenerateCsvFromSavedObjectImmediate(
return res.ok({
body: jobOutputContent || '',
headers: {
'content-type': jobOutputContentType,
'content-type': jobOutputContentType ? jobOutputContentType : [],
'accept-ranges': 'none',
},
});
} catch (err) {
logger.error(err);
return handleError(res, err);
}
})
Expand Down
Loading