mirror of
https://github.com/elastic/kibana.git
synced 2025-04-25 02:09:32 -04:00
* [Screenshotting] Expose packageInfo to pdf maker for dist data
* somehow use `dist` in the pdfmaker?
* use worker_src_harness exclusively when running from source
* Update pdfmaker.ts
* Update x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/pdfmaker.ts
Co-authored-by: Michael Dokolin <dokmic@gmail.com>
* [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix'
Co-authored-by: Michael Dokolin <dokmic@gmail.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
(cherry picked from commit 82e7356f02
)
# Conflicts:
# x-pack/plugins/screenshotting/server/formats/pdf/index.ts
# x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/index.ts
# x-pack/plugins/screenshotting/server/plugin.ts
# x-pack/plugins/screenshotting/server/screenshots/index.test.ts
# x-pack/plugins/screenshotting/server/screenshots/index.ts
This commit is contained in:
parent
a680eb80c8
commit
6a8d17c253
7 changed files with 56 additions and 12 deletions
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { groupBy } from 'lodash';
|
import { groupBy } from 'lodash';
|
||||||
import type { Logger } from 'src/core/server';
|
import type { Logger, PackageInfo } from 'src/core/server';
|
||||||
import { LayoutParams, LayoutTypes } from '../../../common';
|
import { LayoutParams, LayoutTypes } from '../../../common';
|
||||||
import { ScreenshotResult, ScreenshotOptions } from '../../screenshots';
|
import { ScreenshotResult, ScreenshotOptions } from '../../screenshots';
|
||||||
import { FormattedScreenshotResult } from '../types';
|
import { FormattedScreenshotResult } from '../types';
|
||||||
|
@ -54,6 +54,7 @@ export interface PdfScreenshotResult extends Omit<FormattedScreenshotResult, 're
|
||||||
|
|
||||||
interface ScreenshotsResultsToPdfArgs {
|
interface ScreenshotsResultsToPdfArgs {
|
||||||
logger: Logger;
|
logger: Logger;
|
||||||
|
packageInfo: PackageInfo;
|
||||||
title?: string;
|
title?: string;
|
||||||
logo?: string;
|
logo?: string;
|
||||||
}
|
}
|
||||||
|
@ -68,13 +69,14 @@ const getTimeRange = (urlScreenshots: ScreenshotResult['results']) => {
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function toPdf({ title, logo, logger }: ScreenshotsResultsToPdfArgs) {
|
export function toPdf({ title, logo, logger, packageInfo }: ScreenshotsResultsToPdfArgs) {
|
||||||
return async (screenshotResult: ScreenshotResult): Promise<PdfScreenshotResult> => {
|
return async (screenshotResult: ScreenshotResult): Promise<PdfScreenshotResult> => {
|
||||||
const timeRange = getTimeRange(screenshotResult.results);
|
const timeRange = getTimeRange(screenshotResult.results);
|
||||||
try {
|
try {
|
||||||
const { buffer, pageCount } = await pngsToPdf({
|
const { buffer, pageCount } = await pngsToPdf({
|
||||||
results: screenshotResult.results,
|
results: screenshotResult.results,
|
||||||
title: title ? title + (timeRange ? ` - ${timeRange}` : '') : undefined,
|
title: title ? title + (timeRange ? ` - ${timeRange}` : '') : undefined,
|
||||||
|
packageInfo,
|
||||||
logo,
|
logo,
|
||||||
layout: screenshotResult.layout,
|
layout: screenshotResult.layout,
|
||||||
logger,
|
logger,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Logger } from 'src/core/server';
|
import type { Logger, PackageInfo } from 'src/core/server';
|
||||||
import { PdfMaker } from './pdfmaker';
|
import { PdfMaker } from './pdfmaker';
|
||||||
import type { Layout } from '../../../layouts';
|
import type { Layout } from '../../../layouts';
|
||||||
import { getTracker } from './tracker';
|
import { getTracker } from './tracker';
|
||||||
|
@ -17,6 +17,7 @@ interface PngsToPdfArgs {
|
||||||
logger: Logger;
|
logger: Logger;
|
||||||
logo?: string;
|
logo?: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
|
packageInfo: PackageInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function pngsToPdf({
|
export async function pngsToPdf({
|
||||||
|
@ -24,9 +25,10 @@ export async function pngsToPdf({
|
||||||
layout,
|
layout,
|
||||||
logo,
|
logo,
|
||||||
title,
|
title,
|
||||||
|
packageInfo,
|
||||||
logger,
|
logger,
|
||||||
}: PngsToPdfArgs): Promise<{ buffer: Buffer; pageCount: number }> {
|
}: PngsToPdfArgs): Promise<{ buffer: Buffer; pageCount: number }> {
|
||||||
const pdfMaker = new PdfMaker(layout, logo, logger);
|
const pdfMaker = new PdfMaker(layout, logo, packageInfo, logger);
|
||||||
const tracker = getTracker();
|
const tracker = getTracker();
|
||||||
if (title) {
|
if (title) {
|
||||||
pdfMaker.setTitle(title);
|
pdfMaker.setTitle(title);
|
||||||
|
|
|
@ -7,11 +7,12 @@
|
||||||
|
|
||||||
/* eslint-disable max-classes-per-file */
|
/* eslint-disable max-classes-per-file */
|
||||||
|
|
||||||
|
import { PackageInfo } from 'kibana/server';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { loggingSystemMock } from 'src/core/server/mocks';
|
import { loggingSystemMock } from 'src/core/server/mocks';
|
||||||
import { isUint8Array } from 'util/types';
|
import { isUint8Array } from 'util/types';
|
||||||
import { createMockLayout } from '../../../../layouts/mock';
|
|
||||||
import { errors } from '../../../../../common';
|
import { errors } from '../../../../../common';
|
||||||
|
import { createMockLayout } from '../../../../layouts/mock';
|
||||||
import { PdfMaker } from '../pdfmaker';
|
import { PdfMaker } from '../pdfmaker';
|
||||||
|
|
||||||
const imageBase64 = Buffer.from(
|
const imageBase64 = Buffer.from(
|
||||||
|
@ -23,11 +24,19 @@ describe.skip('PdfMaker', () => {
|
||||||
let layout: ReturnType<typeof createMockLayout>;
|
let layout: ReturnType<typeof createMockLayout>;
|
||||||
let pdf: PdfMaker;
|
let pdf: PdfMaker;
|
||||||
let logger: ReturnType<typeof loggingSystemMock.createLogger>;
|
let logger: ReturnType<typeof loggingSystemMock.createLogger>;
|
||||||
|
let packageInfo: Readonly<PackageInfo>;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
layout = createMockLayout();
|
layout = createMockLayout();
|
||||||
logger = loggingSystemMock.createLogger();
|
logger = loggingSystemMock.createLogger();
|
||||||
pdf = new PdfMaker(layout, undefined, logger);
|
packageInfo = {
|
||||||
|
branch: 'screenshot-test',
|
||||||
|
buildNum: 567891011,
|
||||||
|
buildSha: 'screenshot-dfdfed0a',
|
||||||
|
dist: false,
|
||||||
|
version: '1000.0.0',
|
||||||
|
};
|
||||||
|
pdf = new PdfMaker(layout, undefined, packageInfo, logger);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('generate', () => {
|
describe('generate', () => {
|
||||||
|
@ -56,14 +65,14 @@ describe.skip('PdfMaker', () => {
|
||||||
protected workerMaxOldHeapSizeMb = 2;
|
protected workerMaxOldHeapSizeMb = 2;
|
||||||
protected workerMaxYoungHeapSizeMb = 2;
|
protected workerMaxYoungHeapSizeMb = 2;
|
||||||
protected workerModulePath = path.resolve(__dirname, './memory_leak_worker.js');
|
protected workerModulePath = path.resolve(__dirname, './memory_leak_worker.js');
|
||||||
})(layout, undefined, logger);
|
})(layout, undefined, packageInfo, logger);
|
||||||
await expect(leakyMaker.generate()).rejects.toBeInstanceOf(errors.PdfWorkerOutOfMemoryError);
|
await expect(leakyMaker.generate()).rejects.toBeInstanceOf(errors.PdfWorkerOutOfMemoryError);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip('restarts the PDF worker if it crashes', async () => {
|
it.skip('restarts the PDF worker if it crashes', async () => {
|
||||||
const buggyMaker = new (class BuggyPdfMaker extends PdfMaker {
|
const buggyMaker = new (class BuggyPdfMaker extends PdfMaker {
|
||||||
protected workerModulePath = path.resolve(__dirname, './buggy_worker.js');
|
protected workerModulePath = path.resolve(__dirname, './buggy_worker.js');
|
||||||
})(layout, undefined, logger);
|
})(layout, undefined, packageInfo, logger);
|
||||||
|
|
||||||
await expect(buggyMaker.generate()).rejects.toEqual(new Error('This is a bug'));
|
await expect(buggyMaker.generate()).rejects.toEqual(new Error('This is a bug'));
|
||||||
await expect(buggyMaker.generate()).rejects.toEqual(new Error('This is a bug'));
|
await expect(buggyMaker.generate()).rejects.toEqual(new Error('This is a bug'));
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Logger } from 'src/core/server';
|
import type { Logger, PackageInfo } from 'src/core/server';
|
||||||
import { SerializableRecord } from '@kbn/utility-types';
|
import { SerializableRecord } from '@kbn/utility-types';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { Content, ContentImage, ContentText } from 'pdfmake/interfaces';
|
import { Content, ContentImage, ContentText } from 'pdfmake/interfaces';
|
||||||
|
@ -34,7 +34,7 @@ export class PdfMaker {
|
||||||
private worker?: Worker;
|
private worker?: Worker;
|
||||||
private pageCount: number = 0;
|
private pageCount: number = 0;
|
||||||
|
|
||||||
protected workerModulePath = path.resolve(__dirname, './worker.js');
|
protected workerModulePath: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum heap size for old memory region of the worker thread.
|
* The maximum heap size for old memory region of the worker thread.
|
||||||
|
@ -65,10 +65,18 @@ export class PdfMaker {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly layout: Layout,
|
private readonly layout: Layout,
|
||||||
private readonly logo: string | undefined,
|
private readonly logo: string | undefined,
|
||||||
|
{ dist }: PackageInfo,
|
||||||
private readonly logger: Logger
|
private readonly logger: Logger
|
||||||
) {
|
) {
|
||||||
this.title = '';
|
this.title = '';
|
||||||
this.content = [];
|
this.content = [];
|
||||||
|
|
||||||
|
// running in dist: `worker.ts` becomes `worker.js`
|
||||||
|
// running in source: `worker_src_harness.ts` needs to be wrapped in JS and have a ts-node environment initialized.
|
||||||
|
this.workerModulePath = path.resolve(
|
||||||
|
__dirname,
|
||||||
|
dist ? './worker.js' : './worker_src_harness.js'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_addContents(contents: Content[]) {
|
_addContents(contents: Content[]) {
|
||||||
|
|
|
@ -5,5 +5,10 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file is the harness for importing worker.ts with Kibana running in dev mode.
|
||||||
|
* The TS file needs to be compiled on the fly, unlike when Kibana is running as a dist.
|
||||||
|
*/
|
||||||
|
|
||||||
require('../../../../../../../src/setup_node_env');
|
require('../../../../../../../src/setup_node_env');
|
||||||
require('./worker.ts');
|
require('./worker.ts');
|
|
@ -17,6 +17,13 @@ export function createMockScreenshottingStart(): jest.Mocked<ScreenshottingStart
|
||||||
const driver = createMockBrowserDriverFactory();
|
const driver = createMockBrowserDriverFactory();
|
||||||
const { getScreenshots } = createMockScreenshots();
|
const { getScreenshots } = createMockScreenshots();
|
||||||
const { diagnose } = driver;
|
const { diagnose } = driver;
|
||||||
|
const packageInfo = {
|
||||||
|
branch: 'screenshot-test',
|
||||||
|
buildNum: 567891011,
|
||||||
|
buildSha: 'screenshot-dfdfed0a',
|
||||||
|
dist: false,
|
||||||
|
version: '5000.0.0',
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
diagnose,
|
diagnose,
|
||||||
|
@ -24,7 +31,9 @@ export function createMockScreenshottingStart(): jest.Mocked<ScreenshottingStart
|
||||||
(options): ReturnType<ScreenshottingStart['getScreenshots']> =>
|
(options): ReturnType<ScreenshottingStart['getScreenshots']> =>
|
||||||
getScreenshots(options).pipe(
|
getScreenshots(options).pipe(
|
||||||
mergeMap<ScreenshotResult, Promise<PngScreenshotResult | PdfScreenshotResult>>(
|
mergeMap<ScreenshotResult, Promise<PngScreenshotResult | PdfScreenshotResult>>(
|
||||||
options.format === 'pdf' ? toPdf({ logger: loggingSystemMock.createLogger() }) : toPng
|
options.format === 'pdf'
|
||||||
|
? toPdf({ logger: loggingSystemMock.createLogger(), packageInfo })
|
||||||
|
: toPng
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
|
@ -11,6 +11,7 @@ import type {
|
||||||
CoreSetup,
|
CoreSetup,
|
||||||
CoreStart,
|
CoreStart,
|
||||||
Logger,
|
Logger,
|
||||||
|
PackageInfo,
|
||||||
Plugin,
|
Plugin,
|
||||||
PluginInitializerContext,
|
PluginInitializerContext,
|
||||||
} from 'src/core/server';
|
} from 'src/core/server';
|
||||||
|
@ -41,6 +42,7 @@ export interface ScreenshottingStart {
|
||||||
* @returns Observable with output messages.
|
* @returns Observable with output messages.
|
||||||
*/
|
*/
|
||||||
diagnose: HeadlessChromiumDriverFactory['diagnose'];
|
diagnose: HeadlessChromiumDriverFactory['diagnose'];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes screenshots of multiple pages.
|
* Takes screenshots of multiple pages.
|
||||||
* @param options Screenshots session options.
|
* @param options Screenshots session options.
|
||||||
|
@ -54,6 +56,7 @@ export interface ScreenshottingStart {
|
||||||
export class ScreenshottingPlugin implements Plugin<void, ScreenshottingStart, SetupDeps> {
|
export class ScreenshottingPlugin implements Plugin<void, ScreenshottingStart, SetupDeps> {
|
||||||
private config: ConfigType;
|
private config: ConfigType;
|
||||||
private logger: Logger;
|
private logger: Logger;
|
||||||
|
private packageInfo: PackageInfo;
|
||||||
private screenshotMode!: ScreenshotModePluginSetup;
|
private screenshotMode!: ScreenshotModePluginSetup;
|
||||||
private browserDriverFactory!: Promise<HeadlessChromiumDriverFactory>;
|
private browserDriverFactory!: Promise<HeadlessChromiumDriverFactory>;
|
||||||
private screenshots!: Promise<Screenshots>;
|
private screenshots!: Promise<Screenshots>;
|
||||||
|
@ -61,6 +64,7 @@ export class ScreenshottingPlugin implements Plugin<void, ScreenshottingStart, S
|
||||||
constructor(context: PluginInitializerContext<ConfigType>) {
|
constructor(context: PluginInitializerContext<ConfigType>) {
|
||||||
this.logger = context.logger.get();
|
this.logger = context.logger.get();
|
||||||
this.config = context.config.get();
|
this.config = context.config.get();
|
||||||
|
this.packageInfo = context.env.packageInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
setup({ http }: CoreSetup, { screenshotMode }: SetupDeps) {
|
setup({ http }: CoreSetup, { screenshotMode }: SetupDeps) {
|
||||||
|
@ -108,7 +112,12 @@ export class ScreenshottingPlugin implements Plugin<void, ScreenshottingStart, S
|
||||||
switchMap((screenshots) => screenshots.getScreenshots(options)),
|
switchMap((screenshots) => screenshots.getScreenshots(options)),
|
||||||
mergeMap<ScreenshotResult, Promise<PngScreenshotResult | PdfScreenshotResult>>(
|
mergeMap<ScreenshotResult, Promise<PngScreenshotResult | PdfScreenshotResult>>(
|
||||||
options.format === 'pdf'
|
options.format === 'pdf'
|
||||||
? toPdf({ logger: this.logger, logo: options.logo, title: options.title })
|
? toPdf({
|
||||||
|
logger: this.logger,
|
||||||
|
packageInfo: this.packageInfo,
|
||||||
|
logo: options.logo,
|
||||||
|
title: options.title,
|
||||||
|
})
|
||||||
: toPng
|
: toPng
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue