[Reporting] Consolidate Server Type Defs, move some out of Legacy (#66144)

* [Reporting] consolidate server types, move some to NP

* Revert touching routes code

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Tim Sullivan 2020-05-18 17:13:45 -07:00 committed by GitHub
parent 951c0f6528
commit 114a0a13a5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
132 changed files with 874 additions and 969 deletions

View file

@ -5,7 +5,13 @@
*/
import url from 'url';
import { AbsoluteURLFactoryOptions } from '../types';
interface AbsoluteURLFactoryOptions {
defaultBasePath: string;
protocol: string;
hostname: string;
port: string | number;
}
export const getAbsoluteUrlFactory = ({
protocol,

View file

@ -4,9 +4,4 @@
* you may not use this file except in compliance with the Elastic License.
*/
export const LayoutTypes = {
PRESERVE_LAYOUT: 'preserve_layout',
PRINT: 'print',
};
export const DEFAULT_PAGELOAD_SELECTOR = '.application';

View file

@ -4,8 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { cryptoFactory } from '../../../server/lib/crypto';
import { Logger } from '../../../types';
import { cryptoFactory, LevelLogger } from '../../../server/lib';
import { decryptJobHeaders } from './decrypt_job_headers';
const encryptHeaders = async (encryptionKey: string, headers: Record<string, string>) => {
@ -23,7 +22,7 @@ describe('headers', () => {
},
logger: ({
error: jest.fn(),
} as unknown) as Logger,
} as unknown) as LevelLogger,
});
await expect(getDecryptedHeaders()).rejects.toMatchInlineSnapshot(
`[Error: Failed to decrypt report job data. Please ensure that xpack.reporting.encryptionKey is set and re-generate this report. Error: Invalid IV length]`
@ -44,7 +43,7 @@ describe('headers', () => {
type: 'csv',
headers: encryptedHeaders,
},
logger: {} as Logger,
logger: {} as LevelLogger,
});
expect(decryptedHeaders).toEqual(headers);
});

View file

@ -5,8 +5,7 @@
*/
import { i18n } from '@kbn/i18n';
import { cryptoFactory } from '../../../server/lib/crypto';
import { Logger } from '../../../types';
import { cryptoFactory, LevelLogger } from '../../../server/lib';
interface HasEncryptedHeaders {
headers?: string;
@ -23,7 +22,7 @@ export const decryptJobHeaders = async <
}: {
encryptionKey?: string;
job: JobDocPayloadType;
logger: Logger;
logger: LevelLogger;
}): Promise<Record<string, string>> => {
try {
if (typeof job.headers !== 'string') {

View file

@ -5,9 +5,9 @@
*/
import sinon from 'sinon';
import { ReportingConfig, ReportingCore } from '../../../server';
import { JobDocPayload } from '../../../server/types';
import { createMockReportingCore } from '../../../test_helpers';
import { ReportingConfig, ReportingCore } from '../../../server/types';
import { JobDocPayload } from '../../../types';
import { JobDocPayloadPDF } from '../../printable_pdf/types';
import { getConditionalHeaders, getCustomLogo } from './index';

View file

@ -4,8 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { ReportingConfig } from '../../../server/types';
import { ConditionalHeaders } from '../../../types';
import { ReportingConfig } from '../../../server';
import { ConditionalHeaders } from '../../../server/types';
export const getConditionalHeaders = <JobDocPayloadType>({
config,

View file

@ -5,8 +5,8 @@
*/
import { UI_SETTINGS_CUSTOM_PDF_LOGO } from '../../../common/constants';
import { ReportingConfig, ReportingCore } from '../../../server/types';
import { ConditionalHeaders } from '../../../types';
import { ReportingConfig, ReportingCore } from '../../../server';
import { ConditionalHeaders } from '../../../server/types';
import { JobDocPayloadPDF } from '../../printable_pdf/types'; // Logo is PDF only
export const getCustomLogo = async ({

View file

@ -12,7 +12,7 @@ import {
} from 'url';
import { getAbsoluteUrlFactory } from '../../../common/get_absolute_url';
import { validateUrls } from '../../../common/validate_urls';
import { ReportingConfig } from '../../../server/types';
import { ReportingConfig } from '../../../server';
import { JobDocPayloadPNG } from '../../png/types';
import { JobDocPayloadPDF } from '../../printable_pdf/types';

View file

@ -5,8 +5,8 @@
*/
import { CaptureConfig } from '../../../server/types';
import { LayoutTypes } from '../constants';
import { Layout, LayoutParams } from './layout';
import { LayoutParams, LayoutTypes } from './';
import { Layout } from './layout';
import { PreserveLayout } from './preserve_layout';
import { PrintLayout } from './print_layout';

View file

@ -4,6 +4,63 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { HeadlessChromiumDriver } from '../../../server/browsers';
import { LevelLogger } from '../../../server/lib';
import { Layout } from './layout';
export { createLayout } from './create_layout';
export { PrintLayout } from './print_layout';
export { Layout } from './layout';
export { PreserveLayout } from './preserve_layout';
export { PrintLayout } from './print_layout';
export const LayoutTypes = {
PRESERVE_LAYOUT: 'preserve_layout',
PRINT: 'print',
};
export const getDefaultLayoutSelectors = (): LayoutSelectorDictionary => ({
screenshot: '[data-shared-items-container]',
renderComplete: '[data-shared-item]',
itemsCountAttribute: 'data-shared-items-count',
timefilterDurationAttribute: 'data-shared-timefilter-duration',
});
export interface PageSizeParams {
pageMarginTop: number;
pageMarginBottom: number;
pageMarginWidth: number;
tableBorderWidth: number;
headingHeight: number;
subheadingHeight: number;
}
export interface LayoutSelectorDictionary {
screenshot: string;
renderComplete: string;
itemsCountAttribute: string;
timefilterDurationAttribute: string;
}
export interface PdfImageSize {
width: number;
height?: number;
}
export interface Size {
width: number;
height: number;
}
export interface LayoutParams {
id: string;
dimensions: Size;
}
interface LayoutSelectors {
// Fields that are not part of Layout: the instances
// independently implement these fields on their own
selectors: LayoutSelectorDictionary;
positionElements?: (browser: HeadlessChromiumDriver, logger: LevelLogger) => Promise<void>;
}
export type LayoutInstance = Layout & LayoutSelectors & Size;

View file

@ -4,8 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { HeadlessChromiumDriver } from '../../../server/browsers/chromium/driver';
import { LevelLogger } from '../../../server/lib';
import { PageSizeParams, PdfImageSize, Size } from './';
export interface ViewZoomWidthHeight {
zoom: number;
@ -13,34 +12,6 @@ export interface ViewZoomWidthHeight {
height: number;
}
export interface PageSizeParams {
pageMarginTop: number;
pageMarginBottom: number;
pageMarginWidth: number;
tableBorderWidth: number;
headingHeight: number;
subheadingHeight: number;
}
export interface LayoutSelectorDictionary {
screenshot: string;
renderComplete: string;
itemsCountAttribute: string;
timefilterDurationAttribute: string;
}
export interface PdfImageSize {
width: number;
height?: number;
}
export const getDefaultLayoutSelectors = (): LayoutSelectorDictionary => ({
screenshot: '[data-shared-items-container]',
renderComplete: '[data-shared-item]',
itemsCountAttribute: 'data-shared-items-count',
timefilterDurationAttribute: 'data-shared-timefilter-duration',
});
export abstract class Layout {
public id: string = '';
@ -62,22 +33,3 @@ export abstract class Layout {
public abstract getCssOverridesPath(): string;
}
export interface Size {
width: number;
height: number;
}
export interface LayoutParams {
id: string;
dimensions: Size;
}
interface LayoutSelectors {
// Fields that are not part of Layout: the instances
// independently implement these fields on their own
selectors: LayoutSelectorDictionary;
positionElements?: (browser: HeadlessChromiumDriver, logger: LevelLogger) => Promise<void>;
}
export type LayoutInstance = Layout & LayoutSelectors & Size;

View file

@ -3,15 +3,16 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import path from 'path';
import { LayoutTypes } from '../constants';
import {
getDefaultLayoutSelectors,
Layout,
LayoutSelectorDictionary,
LayoutTypes,
PageSizeParams,
Size,
} from './layout';
} from './';
// We use a zoom of two to bump up the resolution of the screenshot a bit.
const ZOOM: number = 2;

View file

@ -6,11 +6,11 @@
import path from 'path';
import { EvaluateFn, SerializableOrJSHandle } from 'puppeteer';
import { HeadlessChromiumDriver } from '../../../server/browsers';
import { LevelLogger } from '../../../server/lib';
import { HeadlessChromiumDriver } from '../../../server/browsers';
import { CaptureConfig } from '../../../server/types';
import { LayoutTypes } from '../constants';
import { getDefaultLayoutSelectors, Layout, LayoutSelectorDictionary, Size } from './layout';
import { getDefaultLayoutSelectors, LayoutSelectorDictionary, Size, LayoutTypes } from './';
import { Layout } from './layout';
export class PrintLayout extends Layout {
public readonly selectors: LayoutSelectorDictionary = {

View file

@ -5,16 +5,16 @@
*/
import { i18n } from '@kbn/i18n';
import { HeadlessChromiumDriver as HeadlessBrowser } from '../../../../server/browsers';
import { LevelLogger as Logger, startTrace } from '../../../../server/lib';
import { LayoutInstance } from '../../layouts/layout';
import { HeadlessChromiumDriver } from '../../../../server/browsers';
import { LevelLogger, startTrace } from '../../../../server/lib';
import { AttributesMap, ElementsPositionAndAttribute } from '../../../../server/types';
import { LayoutInstance } from '../../layouts';
import { CONTEXT_ELEMENTATTRIBUTES } from './constants';
import { AttributesMap, ElementsPositionAndAttribute } from './types';
export const getElementPositionAndAttributes = async (
browser: HeadlessBrowser,
browser: HeadlessChromiumDriver,
layout: LayoutInstance,
logger: Logger
logger: LevelLogger
): Promise<ElementsPositionAndAttribute[] | null> => {
const endTrace = startTrace('get_element_position_data', 'read');
const { screenshot: screenshotSelector } = layout.selectors; // data-shared-items-container

View file

@ -5,15 +5,15 @@
*/
import { i18n } from '@kbn/i18n';
import { HeadlessChromiumDriver as HeadlessBrowser } from '../../../../server/browsers';
import { LevelLogger, startTrace } from '../../../../server/lib';
import { HeadlessChromiumDriver } from '../../../../server/browsers';
import { CaptureConfig } from '../../../../server/types';
import { LayoutInstance } from '../../layouts/layout';
import { LayoutInstance } from '../../layouts';
import { CONTEXT_GETNUMBEROFITEMS, CONTEXT_READMETADATA } from './constants';
export const getNumberOfItems = async (
captureConfig: CaptureConfig,
browser: HeadlessBrowser,
browser: HeadlessChromiumDriver,
layout: LayoutInstance,
logger: LevelLogger
): Promise<number> => {

View file

@ -5,12 +5,12 @@
*/
import { i18n } from '@kbn/i18n';
import { HeadlessChromiumDriver as HeadlessBrowser } from '../../../../server/browsers';
import { HeadlessChromiumDriver } from '../../../../server/browsers';
import { LevelLogger, startTrace } from '../../../../server/lib';
import { Screenshot, ElementsPositionAndAttribute } from './types';
import { ElementsPositionAndAttribute, Screenshot } from '../../../../server/types';
export const getScreenshots = async (
browser: HeadlessBrowser,
browser: HeadlessChromiumDriver,
elementsPositionAndAttributes: ElementsPositionAndAttribute[],
logger: LevelLogger
): Promise<Screenshot[]> => {

View file

@ -4,21 +4,20 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { HeadlessChromiumDriver as HeadlessBrowser } from '../../../../server/browsers';
import { LevelLogger, startTrace } from '../../../../server/lib';
import { LayoutInstance } from '../../layouts/layout';
import { HeadlessChromiumDriver } from '../../../../server/browsers';
import { LayoutInstance } from '../../layouts';
import { CONTEXT_GETTIMERANGE } from './constants';
import { TimeRange } from './types';
export const getTimeRange = async (
browser: HeadlessBrowser,
browser: HeadlessChromiumDriver,
layout: LayoutInstance,
logger: LevelLogger
): Promise<TimeRange | null> => {
): Promise<string | null> => {
const endTrace = startTrace('get_time_range', 'read');
logger.debug('getting timeRange');
const timeRange: TimeRange | null = await browser.evaluate(
const timeRange = await browser.evaluate(
{
fn: durationAttribute => {
const durationElement = document.querySelector(`[${durationAttribute}]`);
@ -32,7 +31,7 @@ export const getTimeRange = async (
return null;
}
return { duration };
return duration; // user-friendly date string
},
args: [layout.selectors.timefilterDurationAttribute],
},
@ -41,7 +40,7 @@ export const getTimeRange = async (
);
if (timeRange) {
logger.info(`timeRange: ${timeRange.duration}`);
logger.info(`timeRange: ${timeRange}`);
} else {
logger.debug('no timeRange');
}

View file

@ -4,4 +4,4 @@
* you may not use this file except in compliance with the Elastic License.
*/
export { screenshotsObservableFactory, ScreenshotsObservableFn } from './observable';
export { screenshotsObservableFactory } from './observable';

View file

@ -7,15 +7,15 @@
import { i18n } from '@kbn/i18n';
import fs from 'fs';
import { promisify } from 'util';
import { HeadlessChromiumDriver as HeadlessBrowser } from '../../../../server/browsers';
import { LevelLogger, startTrace } from '../../../../server/lib';
import { HeadlessChromiumDriver } from '../../../../server/browsers';
import { Layout } from '../../layouts/layout';
import { CONTEXT_INJECTCSS } from './constants';
const fsp = { readFile: promisify(fs.readFile) };
export const injectCustomCss = async (
browser: HeadlessBrowser,
browser: HeadlessChromiumDriver,
layout: Layout,
logger: LevelLogger
): Promise<void> => {

View file

@ -18,13 +18,16 @@ jest.mock('../../../../server/browsers/chromium/puppeteer', () => ({
import * as Rx from 'rxjs';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { loggingServiceMock } from '../../../../../../../../src/core/server/mocks';
import { HeadlessChromiumDriver } from '../../../../server/browsers';
import { LevelLogger } from '../../../../server/lib';
import {
CaptureConfig,
ConditionalHeaders,
ElementsPositionAndAttribute,
} from '../../../../server/types';
import { createMockBrowserDriverFactory, createMockLayoutInstance } from '../../../../test_helpers';
import { ConditionalHeaders, HeadlessChromiumDriver } from '../../../../types';
import { CaptureConfig } from '../../../../server/types';
import * as contexts from './constants';
import { screenshotsObservableFactory } from './observable';
import { ElementsPositionAndAttribute } from './types';
/*
* Mocks

View file

@ -16,29 +16,32 @@ import {
tap,
toArray,
} from 'rxjs/operators';
import { CaptureConfig } from '../../../../server/types';
import { HeadlessChromiumDriverFactory } from '../../../../server/browsers';
import {
CaptureConfig,
ElementsPositionAndAttribute,
ScreenshotObservableOpts,
ScreenshotResults,
ScreenshotsObservableFn,
} from '../../../../server/types';
import { DEFAULT_PAGELOAD_SELECTOR } from '../../constants';
import { HeadlessChromiumDriverFactory } from '../../../../types';
import { getElementPositionAndAttributes } from './get_element_position_data';
import { getNumberOfItems } from './get_number_of_items';
import { getScreenshots } from './get_screenshots';
import { getTimeRange } from './get_time_range';
import { injectCustomCss } from './inject_css';
import { openUrl } from './open_url';
import { ScreenSetupData, ScreenshotObservableOpts, ScreenshotResults } from './types';
import { waitForRenderComplete } from './wait_for_render';
import { waitForVisualizations } from './wait_for_visualizations';
const DEFAULT_SCREENSHOT_CLIP_HEIGHT = 1200;
const DEFAULT_SCREENSHOT_CLIP_WIDTH = 1800;
export type ScreenshotsObservableFn = ({
logger,
urls,
conditionalHeaders,
layout,
browserTimezone,
}: ScreenshotObservableOpts) => Rx.Observable<ScreenshotResults[]>;
interface ScreenSetupData {
elementsPositionAndAttributes: ElementsPositionAndAttribute[] | null;
timeRange: string | null;
error?: Error;
}
export function screenshotsObservableFactory(
captureConfig: CaptureConfig,

View file

@ -5,14 +5,13 @@
*/
import { i18n } from '@kbn/i18n';
import { HeadlessChromiumDriver as HeadlessBrowser } from '../../../../server/browsers';
import { HeadlessChromiumDriver } from '../../../../server/browsers';
import { LevelLogger, startTrace } from '../../../../server/lib';
import { CaptureConfig } from '../../../../server/types';
import { ConditionalHeaders } from '../../../../types';
import { CaptureConfig, ConditionalHeaders } from '../../../../server/types';
export const openUrl = async (
captureConfig: CaptureConfig,
browser: HeadlessBrowser,
browser: HeadlessChromiumDriver,
url: string,
pageLoadSelector: string,
conditionalHeaders: ConditionalHeaders,

View file

@ -1,49 +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 { LevelLogger } from '../../../../server/lib';
import { ConditionalHeaders, ElementPosition } from '../../../../types';
import { LayoutInstance } from '../../layouts/layout';
export interface ScreenshotObservableOpts {
logger: LevelLogger;
urls: string[];
conditionalHeaders: ConditionalHeaders;
layout: LayoutInstance;
browserTimezone: string;
}
export interface TimeRange {
duration: string;
}
export interface AttributesMap {
[key: string]: any;
}
export interface ElementsPositionAndAttribute {
position: ElementPosition;
attributes: AttributesMap;
}
export interface Screenshot {
base64EncodedData: string;
title: string;
description: string;
}
export interface ScreenSetupData {
elementsPositionAndAttributes: ElementsPositionAndAttribute[] | null;
timeRange: TimeRange | null;
error?: Error;
}
export interface ScreenshotResults {
timeRange: TimeRange | null;
screenshots: Screenshot[];
error?: Error;
elementsPositionAndAttributes?: ElementsPositionAndAttribute[]; // NOTE: for testing
}

View file

@ -5,15 +5,15 @@
*/
import { i18n } from '@kbn/i18n';
import { HeadlessChromiumDriver as HeadlessBrowser } from '../../../../server/browsers';
import { LevelLogger, startTrace } from '../../../../server/lib';
import { HeadlessChromiumDriver } from '../../../../server/browsers';
import { CaptureConfig } from '../../../../server/types';
import { LayoutInstance } from '../../layouts/layout';
import { LayoutInstance } from '../../layouts';
import { CONTEXT_WAITFORRENDER } from './constants';
export const waitForRenderComplete = async (
captureConfig: CaptureConfig,
browser: HeadlessBrowser,
browser: HeadlessChromiumDriver,
layout: LayoutInstance,
logger: LevelLogger
) => {

View file

@ -5,10 +5,10 @@
*/
import { i18n } from '@kbn/i18n';
import { HeadlessChromiumDriver as HeadlessBrowser } from '../../../../server/browsers';
import { LevelLogger, startTrace } from '../../../../server/lib';
import { HeadlessChromiumDriver } from '../../../../server/browsers';
import { CaptureConfig } from '../../../../server/types';
import { LayoutInstance } from '../../layouts/layout';
import { LayoutInstance } from '../../layouts';
import { CONTEXT_WAITFORELEMENTSTOBEINDOM } from './constants';
type SelectorArgs = Record<string, string>;
@ -24,7 +24,7 @@ const getCompletedItemsCount = ({ renderCompleteSelector }: SelectorArgs) => {
*/
export const waitForVisualizations = async (
captureConfig: CaptureConfig,
browser: HeadlessBrowser,
browser: HeadlessChromiumDriver,
itemsCount: number,
layout: LayoutInstance,
logger: LevelLogger

View file

@ -6,18 +6,22 @@
import {
CSV_JOB_TYPE as jobType,
LICENSE_TYPE_TRIAL,
LICENSE_TYPE_BASIC,
LICENSE_TYPE_STANDARD,
LICENSE_TYPE_ENTERPRISE,
LICENSE_TYPE_GOLD,
LICENSE_TYPE_PLATINUM,
LICENSE_TYPE_ENTERPRISE,
LICENSE_TYPE_STANDARD,
LICENSE_TYPE_TRIAL,
} from '../../common/constants';
import { ExportTypeDefinition, ESQueueCreateJobFn, ESQueueWorkerExecuteFn } from '../../types';
import {
ESQueueCreateJobFn,
ESQueueWorkerExecuteFn,
ExportTypeDefinition,
} from '../../server/types';
import { metadata } from './metadata';
import { createJobFactory } from './server/create_job';
import { executeJobFactory } from './server/execute_job';
import { JobParamsDiscoverCsv, JobDocPayloadDiscoverCsv } from './types';
import { JobDocPayloadDiscoverCsv, JobParamsDiscoverCsv } from './types';
export const getExportType = (): ExportTypeDefinition<
JobParamsDiscoverCsv,

View file

@ -5,13 +5,13 @@
*/
import { ReportingCore } from '../../../server';
import { cryptoFactory } from '../../../server/lib/crypto';
import { cryptoFactory } from '../../../server/lib';
import {
ConditionalHeaders,
CreateJobFactory,
ESQueueCreateJobFn,
RequestFacade,
} from '../../../types';
} from '../../../server/types';
import { JobParamsDiscoverCsv } from '../types';
export const createJobFactory: CreateJobFactory<ESQueueCreateJobFn<

View file

@ -4,18 +4,18 @@
* you may not use this file except in compliance with the Elastic License.
*/
import nodeCrypto from '@elastic/node-crypto';
// @ts-ignore
import Puid from 'puid';
import sinon from 'sinon';
import nodeCrypto from '@elastic/node-crypto';
import { CancellationToken } from '../../../common/cancellation_token';
import { fieldFormats } from '../../../../../../../src/plugins/data/server';
import { createMockReportingCore } from '../../../test_helpers';
import { LevelLogger } from '../../../server/lib/level_logger';
import { setFieldFormats } from '../../../server/services';
import { executeJobFactory } from './execute_job';
import { JobDocPayloadDiscoverCsv } from '../types';
import { CancellationToken } from '../../../../../../plugins/reporting/common';
import { CSV_BOM_CHARS } from '../../../common/constants';
import { LevelLogger } from '../../../server/lib';
import { setFieldFormats } from '../../../server/services';
import { createMockReportingCore } from '../../../test_helpers';
import { JobDocPayloadDiscoverCsv } from '../types';
import { executeJobFactory } from './execute_job';
const delay = (ms: number) => new Promise(resolve => setTimeout(() => resolve(), ms));
@ -65,6 +65,7 @@ describe('CSV Execute Job', function() {
beforeEach(async function() {
configGetStub = sinon.stub();
configGetStub.withArgs('index').returns('.reporting-foo-test');
configGetStub.withArgs('encryptionKey').returns(encryptionKey);
configGetStub.withArgs('csv', 'maxSizeBytes').returns(1024 * 1000); // 1mB
configGetStub.withArgs('csv', 'scroll').returns({});

View file

@ -7,18 +7,18 @@
import { i18n } from '@kbn/i18n';
import Hapi from 'hapi';
import { IUiSettingsClient, KibanaRequest } from '../../../../../../../src/core/server';
import { CSV_JOB_TYPE, CSV_BOM_CHARS } from '../../../common/constants';
import { ReportingCore } from '../../../server/core';
import { cryptoFactory } from '../../../server/lib';
import { CSV_BOM_CHARS, CSV_JOB_TYPE } from '../../../common/constants';
import { ReportingCore } from '../../../server';
import { cryptoFactory, LevelLogger } from '../../../server/lib';
import { getFieldFormats } from '../../../server/services';
import { ESQueueWorkerExecuteFn, ExecuteJobFactory, Logger } from '../../../types';
import { ESQueueWorkerExecuteFn, ExecuteJobFactory } from '../../../server/types';
import { JobDocPayloadDiscoverCsv } from '../types';
import { fieldFormatMapFactory } from './lib/field_format_map';
import { createGenerateCsv } from './lib/generate_csv';
export const executeJobFactory: ExecuteJobFactory<ESQueueWorkerExecuteFn<
JobDocPayloadDiscoverCsv
>> = async function executeJobFactoryFn(reporting: ReportingCore, parentLogger: Logger) {
>> = async function executeJobFactoryFn(reporting: ReportingCore, parentLogger: LevelLogger) {
const config = reporting.getConfig();
const crypto = cryptoFactory(config.get('encryptionKey'));
const logger = parentLogger.clone([CSV_JOB_TYPE, 'execute-job']);

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { RawValue } from './types';
import { RawValue } from '../../types';
import { cellHasFormulas } from './cell_has_formula';
const nonAlphaNumRE = /[^a-zA-Z0-9]/;

View file

@ -9,7 +9,15 @@ import {
FieldFormatConfig,
IFieldFormatsRegistry,
} from '../../../../../../../../src/plugins/data/server';
import { IndexPatternSavedObject } from '../../../../types';
interface IndexPatternSavedObject {
attributes: {
fieldFormatMap: string;
};
id: string;
type: string;
version: string;
}
/**
* Create a map of FieldFormat instances for index pattern fields

View file

@ -4,8 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { isObject, isNull, isUndefined } from 'lodash';
import { RawValue } from './types';
import { isNull, isObject, isUndefined } from 'lodash';
import { RawValue } from '../../types';
export function createFormatCsvValues(
escapeValue: (value: RawValue, index: number, array: RawValue[]) => string,

View file

@ -5,7 +5,7 @@
*/
import { i18n } from '@kbn/i18n';
import { Logger } from '../../../../types';
import { LevelLogger } from '../../../../server/lib';
import { GenerateCsvParams, SavedSearchGeneratorResult } from '../../types';
import { createFlattenHit } from './flatten_hit';
import { createFormatCsvValues } from './format_csv_values';
@ -14,7 +14,7 @@ import { createHitIterator } from './hit_iterator';
import { MaxSizeStringBuilder } from './max_size_string_builder';
import { checkIfRowsHaveFormulas } from './check_cells_for_formulas';
export function createGenerateCsv(logger: Logger) {
export function createGenerateCsv(logger: LevelLogger) {
const hitIterator = createHitIterator(logger);
return async function generateCsv({

View file

@ -6,16 +6,16 @@
import expect from '@kbn/expect';
import sinon from 'sinon';
import { CancellationToken } from '../../../../common/cancellation_token';
import { CancellationToken } from '../../../../../../../plugins/reporting/common';
import { LevelLogger } from '../../../../server/lib';
import { ScrollConfig } from '../../../../server/types';
import { Logger } from '../../../../types';
import { createHitIterator } from './hit_iterator';
const mockLogger = {
error: new Function(),
debug: new Function(),
warning: new Function(),
} as Logger;
} as LevelLogger;
const debugLogStub = sinon.stub(mockLogger, 'debug');
const warnLogStub = sinon.stub(mockLogger, 'warning');
const errorLogStub = sinon.stub(mockLogger, 'error');

View file

@ -6,8 +6,9 @@
import { i18n } from '@kbn/i18n';
import { SearchParams, SearchResponse } from 'elasticsearch';
import { CancellationToken } from '../../../../../../../plugins/reporting/common';
import { LevelLogger } from '../../../../server/lib';
import { ScrollConfig } from '../../../../server/types';
import { CancellationToken, Logger } from '../../../../types';
async function parseResponse(request: SearchResponse<any>) {
const response = await request;
@ -35,7 +36,7 @@ async function parseResponse(request: SearchResponse<any>) {
};
}
export function createHitIterator(logger: Logger) {
export function createHitIterator(logger: LevelLogger) {
return async function* hitIterator(
scrollSettings: ScrollConfig,
callEndpoint: Function,

View file

@ -4,9 +4,10 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { CancellationToken } from '../../common/cancellation_token';
import { ScrollConfig } from '../../server/types';
import { JobDocPayload, JobParamPostPayload } from '../../types';
import { CancellationToken } from '../../../../../plugins/reporting/common';
import { JobDocPayload, JobParamPostPayload, ScrollConfig } from '../../server/types';
export type RawValue = string | object | null | undefined;
interface DocValueField {
field: string;

View file

@ -6,25 +6,25 @@
import {
CSV_FROM_SAVEDOBJECT_JOB_TYPE,
LICENSE_TYPE_TRIAL,
LICENSE_TYPE_BASIC,
LICENSE_TYPE_STANDARD,
LICENSE_TYPE_ENTERPRISE,
LICENSE_TYPE_GOLD,
LICENSE_TYPE_PLATINUM,
LICENSE_TYPE_ENTERPRISE,
LICENSE_TYPE_STANDARD,
LICENSE_TYPE_TRIAL,
} from '../../common/constants';
import { ExportTypeDefinition, ImmediateCreateJobFn, ImmediateExecuteFn } from '../../types';
import { createJobFactory } from './server/create_job';
import { executeJobFactory } from './server/execute_job';
import { ExportTypeDefinition } from '../../server/types';
import { metadata } from './metadata';
import { createJobFactory, ImmediateCreateJobFn } from './server/create_job';
import { executeJobFactory, ImmediateExecuteFn } 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 { executeJobFactory } from './server/execute_job';
export { createJobFactory } from './server/create_job';
export { executeJobFactory } from './server/execute_job';
export const getExportType = (): ExportTypeDefinition<
JobParamsPanelCsv,

View file

@ -8,8 +8,8 @@ import { notFound, notImplemented } from 'boom';
import { get } from 'lodash';
import { CSV_FROM_SAVEDOBJECT_JOB_TYPE } from '../../../../common/constants';
import { ReportingCore } from '../../../../server';
import { cryptoFactory } from '../../../../server/lib';
import { CreateJobFactory, ImmediateCreateJobFn, Logger, RequestFacade } from '../../../../types';
import { cryptoFactory, LevelLogger } from '../../../../server/lib';
import { CreateJobFactory, RequestFacade, TimeRangeParams } from '../../../../server/types';
import {
JobDocPayloadPanelCsv,
JobParamsPanelCsv,
@ -17,11 +17,20 @@ import {
SavedObjectServiceError,
SavedSearchObjectAttributesJSON,
SearchPanel,
TimeRangeParams,
VisObjectAttributesJSON,
} from '../../types';
import { createJobSearch } from './create_job_search';
export type ImmediateCreateJobFn<JobParamsType> = (
jobParams: JobParamsType,
headers: Record<string, string>,
req: RequestFacade
) => Promise<{
type: string | null;
title: string;
jobParams: JobParamsType;
}>;
interface VisData {
title: string;
visType: string;
@ -30,7 +39,7 @@ interface VisData {
export const createJobFactory: CreateJobFactory<ImmediateCreateJobFn<
JobParamsPanelCsv
>> = function createJobFactoryFn(reporting: ReportingCore, parentLogger: Logger) {
>> = 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']);

View file

@ -4,12 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { TimeRangeParams } from '../../../../server/types';
import {
SavedObjectMeta,
SavedObjectReference,
SavedSearchObjectAttributes,
SearchPanel,
TimeRangeParams,
} from '../../types';
interface SearchPanelData {

View file

@ -4,4 +4,4 @@
* you may not use this file except in compliance with the Elastic License.
*/
export { createJobFactory } from './create_job';
export { createJobFactory, ImmediateCreateJobFn } from './create_job';

View file

@ -7,21 +7,30 @@
import { i18n } from '@kbn/i18n';
import { CONTENT_TYPE_CSV, CSV_FROM_SAVEDOBJECT_JOB_TYPE } from '../../../common/constants';
import { ReportingCore } from '../../../server';
import { cryptoFactory } from '../../../server/lib';
import { cryptoFactory, LevelLogger } from '../../../server/lib';
import {
ExecuteJobFactory,
ImmediateExecuteFn,
JobDocOutput,
Logger,
JobDocPayload,
RequestFacade,
} from '../../../types';
} from '../../../server/types';
import { CsvResultFromSearch } from '../../csv/types';
import { FakeRequest, JobDocPayloadPanelCsv, JobParamsPanelCsv, SearchPanel } from '../types';
import { createGenerateCsv } from './lib';
/*
* ImmediateExecuteFn receives the job doc payload because the payload was
* generated in the CreateFn
*/
export type ImmediateExecuteFn<JobParamsType> = (
jobId: null,
job: JobDocPayload<JobParamsType>,
request: RequestFacade
) => Promise<JobDocOutput>;
export const executeJobFactory: ExecuteJobFactory<ImmediateExecuteFn<
JobParamsPanelCsv
>> = async function executeJobFactoryFn(reporting: ReportingCore, parentLogger: Logger) {
>> = async function executeJobFactoryFn(reporting: ReportingCore, parentLogger: LevelLogger) {
const config = reporting.getConfig();
const crypto = cryptoFactory(config.get('encryptionKey'));
const logger = parentLogger.clone([CSV_FROM_SAVEDOBJECT_JOB_TYPE, 'execute-job']);

View file

@ -5,12 +5,13 @@
*/
import { badRequest } from 'boom';
import { ReportingCore } from '../../../../server/types';
import { Logger, RequestFacade } from '../../../../types';
import { ReportingCore } from '../../../../server';
import { LevelLogger } from '../../../../server/lib';
import { RequestFacade } from '../../../../server/types';
import { FakeRequest, JobParamsPanelCsv, SearchPanel, VisPanel } from '../../types';
import { generateCsvSearch } from './generate_csv_search';
export function createGenerateCsv(reporting: ReportingCore, logger: Logger) {
export function createGenerateCsv(reporting: ReportingCore, logger: LevelLogger) {
return async function generateCsv(
request: RequestFacade | FakeRequest,
visType: string,

View file

@ -11,13 +11,11 @@ import {
Filter,
IIndexPattern,
Query,
// Reporting uses an unconventional directory structure so the linter marks this as a violation, server files should
// be moved under reporting/server/
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
} from '../../../../../../../../src/plugins/data/server';
import { CancellationToken } from '../../../../common/cancellation_token';
import { CancellationToken } from '../../../../../../../plugins/reporting/common';
import { ReportingCore } from '../../../../server';
import { Logger, RequestFacade } from '../../../../types';
import { LevelLogger } from '../../../../server/lib';
import { RequestFacade } from '../../../../server/types';
import { createGenerateCsv } from '../../../csv/server/lib/generate_csv';
import {
CsvResultFromSearch,
@ -58,7 +56,7 @@ const getUiSettings = async (config: IUiSettingsClient) => {
export async function generateCsvSearch(
req: RequestFacade,
reporting: ReportingCore,
logger: Logger,
logger: LevelLogger,
searchPanel: SearchPanel,
jobParams: JobParamsDiscoverCsv
): Promise<CsvResultFromSearch> {

View file

@ -4,12 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
import {
QueryFilter,
SavedSearchObjectAttributes,
SearchSourceFilter,
TimeRangeParams,
} from '../../types';
import { TimeRangeParams } from '../../../../server/types';
import { QueryFilter, SavedSearchObjectAttributes, SearchSourceFilter } from '../../types';
import { getFilters } from './get_filters';
interface Args {

View file

@ -6,14 +6,8 @@
import { badRequest } from 'boom';
import moment from 'moment-timezone';
import {
Filter,
QueryFilter,
SavedSearchObjectAttributes,
SearchSourceFilter,
TimeRangeParams,
} from '../../types';
import { TimeRangeParams } from '../../../../server/types';
import { Filter, QueryFilter, SavedSearchObjectAttributes, SearchSourceFilter } from '../../types';
export function getFilters(
indexPatternId: string,

View file

@ -4,8 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { RequestFacade } from '../../../../types';
import { JobParamsPostPayloadPanelCsv, JobParamsPanelCsv } from '../../types';
import { RequestFacade } from '../../../../server/types';
import { JobParamsPanelCsv, JobParamsPostPayloadPanelCsv } from '../../types';
export function getJobParamsFromRequest(
request: RequestFacade,

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { JobDocPayload, JobParamPostPayload } from '../../types';
import { JobDocPayload, JobParamPostPayload, TimeRangeParams } from '../../server/types';
export interface FakeRequest {
headers: Record<string, unknown>;
@ -114,12 +114,6 @@ export interface IndexPatternSavedObject {
};
}
export interface TimeRangeParams {
timezone: string;
min: Date | string | number;
max: Date | string | number;
}
export interface VisPanel {
indexPatternSavedObjectId?: string;
savedSearchObjectId?: string;

View file

@ -5,18 +5,22 @@
*/
import {
PNG_JOB_TYPE as jobType,
LICENSE_TYPE_TRIAL,
LICENSE_TYPE_STANDARD,
LICENSE_TYPE_ENTERPRISE,
LICENSE_TYPE_GOLD,
LICENSE_TYPE_PLATINUM,
LICENSE_TYPE_ENTERPRISE,
LICENSE_TYPE_STANDARD,
LICENSE_TYPE_TRIAL,
PNG_JOB_TYPE as jobType,
} from '../../common/constants';
import { ExportTypeDefinition, ESQueueCreateJobFn, ESQueueWorkerExecuteFn } from '../../types';
import {
ESQueueCreateJobFn,
ESQueueWorkerExecuteFn,
ExportTypeDefinition,
} from '../../server/types';
import { metadata } from './metadata';
import { createJobFactory } from './server/create_job';
import { executeJobFactory } from './server/execute_job';
import { metadata } from './metadata';
import { JobParamsPNG, JobDocPayloadPNG } from './types';
import { JobDocPayloadPNG, JobParamsPNG } from './types';
export const getExportType = (): ExportTypeDefinition<
JobParamsPNG,

View file

@ -6,13 +6,13 @@
import { validateUrls } from '../../../../common/validate_urls';
import { ReportingCore } from '../../../../server';
import { cryptoFactory } from '../../../../server/lib/crypto';
import { cryptoFactory } from '../../../../server/lib';
import {
ConditionalHeaders,
CreateJobFactory,
ESQueueCreateJobFn,
RequestFacade,
} from '../../../../types';
} from '../../../../server/types';
import { JobParamsPNG } from '../../types';
export const createJobFactory: CreateJobFactory<ESQueueCreateJobFn<

View file

@ -5,10 +5,9 @@
*/
import * as Rx from 'rxjs';
import { CancellationToken } from '../../../../common/cancellation_token';
import { CancellationToken } from '../../../../../../../plugins/reporting/common';
import { ReportingCore } from '../../../../server';
import { LevelLogger } from '../../../../server/lib';
import { cryptoFactory } from '../../../../server/lib/crypto';
import { cryptoFactory, LevelLogger } from '../../../../server/lib';
import { createMockReportingCore } from '../../../../test_helpers';
import { JobDocPayloadPNG } from '../../types';
import { generatePngObservableFactory } from '../lib/generate_png';
@ -125,8 +124,8 @@ test(`returns content_type of application/png`, async () => {
const executeJob = await executeJobFactory(mockReporting, getMockLogger());
const encryptedHeaders = await encryptHeaders({});
const generatePngObservable = (await generatePngObservableFactory(mockReporting)) as jest.Mock;
generatePngObservable.mockReturnValue(Rx.of('foo'));
const generatePngObservable = await generatePngObservableFactory(mockReporting);
(generatePngObservable as jest.Mock).mockReturnValue(Rx.of('foo'));
const { content_type: contentType } = await executeJob(
'pngJobId',
@ -138,9 +137,8 @@ test(`returns content_type of application/png`, async () => {
test(`returns content of generatePng getBuffer base64 encoded`, async () => {
const testContent = 'raw string from get_screenhots';
const generatePngObservable = (await generatePngObservableFactory(mockReporting)) as jest.Mock;
generatePngObservable.mockReturnValue(Rx.of({ base64: testContent }));
const generatePngObservable = await generatePngObservableFactory(mockReporting);
(generatePngObservable as jest.Mock).mockReturnValue(Rx.of({ base64: testContent }));
const executeJob = await executeJobFactory(mockReporting, getMockLogger());
const encryptedHeaders = await encryptHeaders({});

View file

@ -9,7 +9,8 @@ import * as Rx from 'rxjs';
import { catchError, map, mergeMap, takeUntil } from 'rxjs/operators';
import { PNG_JOB_TYPE } from '../../../../common/constants';
import { ReportingCore } from '../../../../server';
import { ESQueueWorkerExecuteFn, ExecuteJobFactory, JobDocOutput, Logger } from '../../../../types';
import { LevelLogger } from '../../../../server/lib';
import { ESQueueWorkerExecuteFn, ExecuteJobFactory, JobDocOutput } from '../../../../server/types';
import {
decryptJobHeaders,
getConditionalHeaders,
@ -23,7 +24,7 @@ type QueuedPngExecutorFactory = ExecuteJobFactory<ESQueueWorkerExecuteFn<JobDocP
export const executeJobFactory: QueuedPngExecutorFactory = async function executeJobFactoryFn(
reporting: ReportingCore,
parentLogger: Logger
parentLogger: LevelLogger
) {
const config = reporting.getConfig();
const encryptionKey = config.get('encryptionKey');

View file

@ -9,10 +9,9 @@ import * as Rx from 'rxjs';
import { map } from 'rxjs/operators';
import { ReportingCore } from '../../../../server';
import { LevelLogger } from '../../../../server/lib';
import { ConditionalHeaders } from '../../../../types';
import { LayoutParams } from '../../../common/layouts/layout';
import { ConditionalHeaders, ScreenshotResults } from '../../../../server/types';
import { LayoutParams } from '../../../common/layouts';
import { PreserveLayout } from '../../../common/layouts/preserve_layout';
import { ScreenshotResults } from '../../../common/lib/screenshots/types';
export async function generatePngObservableFactory(reporting: ReportingCore) {
const getScreenshots = await reporting.getScreenshotsObservable();

View file

@ -4,8 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { LayoutInstance, LayoutParams } from '../common/layouts/layout';
import { ConditionalHeaders, JobDocPayload, RequestFacade } from '../../types';
import { JobDocPayload } from '../../server/types';
import { LayoutInstance, LayoutParams } from '../common/layouts';
// Job params: structure of incoming user request data
export interface JobParamsPNG {

View file

@ -5,18 +5,22 @@
*/
import {
PDF_JOB_TYPE as jobType,
LICENSE_TYPE_TRIAL,
LICENSE_TYPE_STANDARD,
LICENSE_TYPE_ENTERPRISE,
LICENSE_TYPE_GOLD,
LICENSE_TYPE_PLATINUM,
LICENSE_TYPE_ENTERPRISE,
LICENSE_TYPE_STANDARD,
LICENSE_TYPE_TRIAL,
PDF_JOB_TYPE as jobType,
} from '../../common/constants';
import { ExportTypeDefinition, ESQueueCreateJobFn, ESQueueWorkerExecuteFn } from '../../types';
import {
ESQueueCreateJobFn,
ESQueueWorkerExecuteFn,
ExportTypeDefinition,
} from '../../server/types';
import { metadata } from './metadata';
import { createJobFactory } from './server/create_job';
import { executeJobFactory } from './server/execute_job';
import { metadata } from './metadata';
import { JobParamsPDF, JobDocPayloadPDF } from './types';
import { JobDocPayloadPDF, JobParamsPDF } from './types';
export const getExportType = (): ExportTypeDefinition<
JobParamsPDF,

View file

@ -6,13 +6,13 @@
import { validateUrls } from '../../../../common/validate_urls';
import { ReportingCore } from '../../../../server';
import { cryptoFactory } from '../../../../server/lib/crypto';
import { cryptoFactory } from '../../../../server/lib';
import {
ConditionalHeaders,
CreateJobFactory,
ESQueueCreateJobFn,
RequestFacade,
} from '../../../../types';
} from '../../../../server/types';
import { JobParamsPDF } from '../../types';
export const createJobFactory: CreateJobFactory<ESQueueCreateJobFn<

View file

@ -4,18 +4,17 @@
* you may not use this file except in compliance with the Elastic License.
*/
import * as Rx from 'rxjs';
import { createMockReportingCore } from '../../../../test_helpers';
import { cryptoFactory } from '../../../../server/lib/crypto';
import { LevelLogger } from '../../../../server/lib';
import { CancellationToken } from '../../../../types';
import { ReportingCore } from '../../../../server';
import { generatePdfObservableFactory } from '../lib/generate_pdf';
import { JobDocPayloadPDF } from '../../types';
import { executeJobFactory } from './index';
jest.mock('../lib/generate_pdf', () => ({ generatePdfObservableFactory: jest.fn() }));
import * as Rx from 'rxjs';
import { CancellationToken } from '../../../../../../../plugins/reporting/common';
import { ReportingCore } from '../../../../server';
import { cryptoFactory, LevelLogger } from '../../../../server/lib';
import { createMockReportingCore } from '../../../../test_helpers';
import { JobDocPayloadPDF } from '../../types';
import { generatePdfObservableFactory } from '../lib/generate_pdf';
import { executeJobFactory } from './index';
let mockReporting: ReportingCore;
const cancellationToken = ({
@ -44,6 +43,7 @@ beforeEach(async () => {
'server.basePath': '/sbp',
};
const reportingConfig = {
index: '.reports-test',
encryptionKey: mockEncryptionKey,
'kibanaServer.hostname': 'localhost',
'kibanaServer.port': 5601,

View file

@ -9,7 +9,8 @@ import * as Rx from 'rxjs';
import { catchError, map, mergeMap, takeUntil } from 'rxjs/operators';
import { PDF_JOB_TYPE } from '../../../../common/constants';
import { ReportingCore } from '../../../../server';
import { ESQueueWorkerExecuteFn, ExecuteJobFactory, JobDocOutput, Logger } from '../../../../types';
import { LevelLogger } from '../../../../server/lib';
import { ESQueueWorkerExecuteFn, ExecuteJobFactory, JobDocOutput } from '../../../../server/types';
import {
decryptJobHeaders,
getConditionalHeaders,
@ -24,7 +25,7 @@ type QueuedPdfExecutorFactory = ExecuteJobFactory<ESQueueWorkerExecuteFn<JobDocP
export const executeJobFactory: QueuedPdfExecutorFactory = async function executeJobFactoryFn(
reporting: ReportingCore,
parentLogger: Logger
parentLogger: LevelLogger
) {
const config = reporting.getConfig();
const encryptionKey = config.get('encryptionKey');

View file

@ -9,13 +9,11 @@ import * as Rx from 'rxjs';
import { mergeMap } from 'rxjs/operators';
import { ReportingCore } from '../../../../server';
import { LevelLogger } from '../../../../server/lib';
import { ConditionalHeaders } from '../../../../types';
import { createLayout } from '../../../common/layouts';
import { LayoutInstance, LayoutParams } from '../../../common/layouts/layout';
import { ScreenshotResults } from '../../../common/lib/screenshots/types';
import { getTracker } from './tracker';
import { ConditionalHeaders, ScreenshotResults } from '../../../../server/types';
import { createLayout, LayoutInstance, LayoutParams } from '../../../common/layouts';
// @ts-ignore untyped module
import { pdf } from './pdf';
import { getTracker } from './tracker';
const getTimeRange = (urlScreenshots: ScreenshotResults[]) => {
const grouped = groupBy(urlScreenshots.map(u => u.timeRange));
@ -62,7 +60,7 @@ export async function generatePdfObservableFactory(reporting: ReportingCore) {
const pdfOutput = pdf.create(layout, logo);
if (title) {
const timeRange = getTimeRange(results);
title += timeRange ? ` - ${timeRange.duration}` : '';
title += timeRange ? ` - ${timeRange}` : '';
pdfOutput.setTitle(title);
}
tracker.endSetup();

View file

@ -4,8 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { JobDocPayload } from '../../types';
import { LayoutInstance, LayoutParams } from '../common/layouts/layout';
import { JobDocPayload } from '../../server/types';
import { LayoutInstance, LayoutParams } from '../common/layouts';
// Job params: structure of incoming user request data, after being parsed from RISON
export interface JobParamsPDF {

View file

@ -9,7 +9,8 @@ import { Legacy } from 'kibana';
import { resolve } from 'path';
import { PLUGIN_ID, UI_SETTINGS_CUSTOM_PDF_LOGO } from './common/constants';
import { legacyInit } from './server/legacy';
import { ReportingPluginSpecOptions } from './types';
export type ReportingPluginSpecOptions = Legacy.PluginSpecOptions;
const kbToBase64Length = (kb: number) => Math.floor((kb * 1024 * 8) / 6);

View file

@ -7,18 +7,12 @@
import { i18n } from '@kbn/i18n';
import { map, trunc } from 'lodash';
import open from 'opn';
import { ElementHandle, EvaluateFn, Page, SerializableOrJSHandle, Response } from 'puppeteer';
import { ElementHandle, EvaluateFn, Page, Response, SerializableOrJSHandle } from 'puppeteer';
import { parse as parseUrl } from 'url';
import { ViewZoomWidthHeight } from '../../../../export_types/common/layouts/layout';
import { LevelLogger } from '../../../../server/lib';
import {
ConditionalHeaders,
ConditionalHeadersConditions,
ElementPosition,
InterceptedRequest,
NetworkPolicy,
} from '../../../../types';
import { allowRequest } from '../../network_policy';
import { LevelLogger } from '../../../lib';
import { ConditionalHeaders, ElementPosition } from '../../../types';
import { allowRequest, NetworkPolicy } from '../../network_policy';
export interface ChromiumDriverOptions {
inspect: boolean;
@ -38,6 +32,23 @@ interface EvaluateMetaOpts {
context: string;
}
type ConditionalHeadersConditions = ConditionalHeaders['conditions'];
interface InterceptedRequest {
requestId: string;
request: {
url: string;
method: string;
headers: {
[key: string]: string;
};
initialPriority: string;
referrerPolicy: string;
};
frameId: string;
resourceType: string;
}
const WAIT_FOR_DELAY_MS: number = 100;
export class HeadlessChromiumDriver {

View file

@ -21,7 +21,7 @@ import { InnerSubscriber } from 'rxjs/internal/InnerSubscriber';
import { ignoreElements, map, mergeMap, tap } from 'rxjs/operators';
import { BROWSER_TYPE } from '../../../../common/constants';
import { CaptureConfig } from '../../../../server/types';
import { LevelLogger as Logger } from '../../../lib/level_logger';
import { LevelLogger } from '../../../lib';
import { safeChildProcess } from '../../safe_child_process';
import { HeadlessChromiumDriver } from '../driver';
import { getChromeLogLocation } from '../paths';
@ -39,7 +39,7 @@ export class HeadlessChromiumDriverFactory {
private userDataDir: string;
private getChromiumArgs: (viewport: ViewportConfig) => string[];
constructor(binaryPath: binaryPath, logger: Logger, captureConfig: CaptureConfig) {
constructor(binaryPath: binaryPath, logger: LevelLogger, captureConfig: CaptureConfig) {
this.binaryPath = binaryPath;
this.captureConfig = captureConfig;
this.browserConfig = captureConfig.browser.chromium;
@ -56,7 +56,7 @@ export class HeadlessChromiumDriverFactory {
type = BROWSER_TYPE;
test(logger: Logger) {
test(logger: LevelLogger) {
const chromiumArgs = args({
userDataDir: this.userDataDir,
viewport: { width: 800, height: 600 },
@ -84,7 +84,7 @@ export class HeadlessChromiumDriverFactory {
*/
createPage(
{ viewport, browserTimezone }: { viewport: ViewportConfig; browserTimezone: string },
pLogger: Logger
pLogger: LevelLogger
): Rx.Observable<{ driver: HeadlessChromiumDriver; exit$: Rx.Observable<never> }> {
return Rx.Observable.create(async (observer: InnerSubscriber<any, any>) => {
const logger = pLogger.clone(['browser-driver']);
@ -172,7 +172,7 @@ export class HeadlessChromiumDriverFactory {
});
}
getBrowserLogger(page: Page, logger: Logger): Rx.Observable<void> {
getBrowserLogger(page: Page, logger: LevelLogger): Rx.Observable<void> {
const consoleMessages$ = Rx.fromEvent<ConsoleMessage>(page, 'console').pipe(
map(line => {
if (line.type() === 'error') {
@ -197,7 +197,7 @@ export class HeadlessChromiumDriverFactory {
return Rx.merge(consoleMessages$, pageRequestFailed$);
}
getProcessLogger(browser: Browser, logger: Logger): Rx.Observable<void> {
getProcessLogger(browser: Browser, logger: LevelLogger): Rx.Observable<void> {
const childProcess = browser.process();
// NOTE: The browser driver can not observe stdout and stderr of the child process
// Puppeteer doesn't give a handle to the original ChildProcess object

View file

@ -4,8 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { Logger } from '../../types';
import { ReportingConfig } from '../types';
import { ReportingConfig } from '../';
import { LevelLogger } from '../lib';
import { HeadlessChromiumDriverFactory } from './chromium/driver_factory';
import { ensureBrowserDownloaded } from './download';
import { chromium } from './index';
@ -13,7 +13,7 @@ import { installBrowser } from './install';
export async function createBrowserDriverFactory(
config: ReportingConfig,
logger: Logger
logger: LevelLogger
): Promise<HeadlessChromiumDriverFactory> {
const captureConfig = config.get('capture');
const browserConfig = captureConfig.browser.chromium;

View file

@ -6,9 +6,8 @@
import { existsSync } from 'fs';
import { resolve as resolvePath } from 'path';
import { BrowserDownload, chromium } from '../';
import { BROWSER_TYPE } from '../../../common/constants';
import { chromium } from '../index';
import { BrowserDownload } from '../types';
import { md5 } from './checksum';
import { clean } from './clean';
import { download } from './download';

View file

@ -16,3 +16,17 @@ export const chromium = {
paths: chromiumDefinition.paths,
createDriverFactory: chromiumDefinition.createDriverFactory,
};
export interface BrowserDownload {
paths: {
archivesPath: string;
baseUrl: string;
packages: Array<{
archiveChecksum: string;
archiveFilename: string;
binaryChecksum: string;
binaryRelativePath: string;
platforms: string[];
}>;
};
}

View file

@ -7,12 +7,12 @@
import fs from 'fs';
import path from 'path';
import { promisify } from 'util';
import { LevelLogger as Logger } from '../lib/level_logger';
// @ts-ignore
import { extract } from './extract';
import { LevelLogger } from '../lib';
import { BrowserDownload } from './';
// @ts-ignore
import { md5 } from './download/checksum';
import { BrowserDownload } from './types';
// @ts-ignore
import { extract } from './extract';
const chmod = promisify(fs.chmod);
@ -28,7 +28,7 @@ interface PathResponse {
* archive. If there is an error extracting the archive an `ExtractError` is thrown
*/
export async function installBrowser(
logger: Logger,
logger: LevelLogger,
browser: BrowserDownload,
installsPath: string
): Promise<PathResponse> {

View file

@ -6,7 +6,17 @@
import * as _ from 'lodash';
import { parse } from 'url';
import { NetworkPolicyRule } from '../../types';
interface NetworkPolicyRule {
allow: boolean;
protocol?: string;
host?: string;
}
export interface NetworkPolicy {
enabled: boolean;
rules: NetworkPolicyRule[];
}
const isHostMatch = (actualHost: string, ruleHost: string) => {
const hostParts = actualHost.split('.').reverse();

View file

@ -6,7 +6,7 @@
import * as Rx from 'rxjs';
import { take, share, mapTo, delay, tap } from 'rxjs/operators';
import { Logger } from '../../types';
import { LevelLogger } from '../lib';
interface IChild {
kill: (signal: string) => Promise<any>;
@ -15,7 +15,7 @@ interface IChild {
// Our process can get sent various signals, and when these occur we wish to
// kill the subprocess and then kill our process as long as the observer isn't cancelled
export function safeChildProcess(
logger: Logger,
logger: LevelLogger,
childProcess: IChild
): { terminate$: Rx.Observable<string> } {
const ownTerminateSignal$ = Rx.merge(

View file

@ -1,19 +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.
*/
export interface BrowserDownload {
paths: {
archivesPath: string;
baseUrl: string;
packages: Array<{
archiveChecksum: string;
archiveFilename: string;
binaryChecksum: string;
binaryRelativePath: string;
platforms: string[];
}>;
};
}

View file

@ -5,10 +5,9 @@
*/
import { Legacy } from 'kibana';
import { CoreSetup } from 'src/core/server';
import { get } from 'lodash';
import { CoreSetup } from 'src/core/server';
import { ConfigType as ReportingConfigType } from '../../../../../plugins/reporting/server';
export { ReportingConfigType };
// make config.get() aware of the value type it returns
interface Config<BaseType> {
@ -85,3 +84,5 @@ export const buildConfig = (
},
};
};
export { ReportingConfigType };

View file

@ -8,26 +8,25 @@ import * as Rx from 'rxjs';
import { first, mapTo } from 'rxjs/operators';
import {
ElasticsearchServiceSetup,
IUiSettingsClient,
KibanaRequest,
SavedObjectsClient,
SavedObjectsServiceStart,
UiSettingsServiceStart,
} from 'src/core/server';
import { ReportingPluginSpecOptions } from '../';
// @ts-ignore no module definition
import { mirrorPluginStatus } from '../../../server/lib/mirror_plugin_status';
import { XPackMainPlugin } from '../../xpack_main/server/xpack_main';
import { PLUGIN_ID } from '../common/constants';
import { EnqueueJobFn, ESQueueInstance, ReportingPluginSpecOptions, ServerFacade } from '../types';
import { screenshotsObservableFactory } from '../export_types/common/lib/screenshots';
import { ServerFacade } from '../server/types';
import { ReportingConfig } from './';
import { HeadlessChromiumDriverFactory } from './browsers/chromium/driver_factory';
import { ReportingConfig, ReportingConfigType } from './config';
import { checkLicenseFactory, getExportTypesRegistry, LevelLogger } from './lib';
import { ESQueueInstance } from './lib/create_queue';
import { EnqueueJobFn } from './lib/enqueue_job';
import { registerRoutes } from './routes';
import { ReportingSetupDeps } from './types';
import {
screenshotsObservableFactory,
ScreenshotsObservableFn,
} from '../export_types/common/lib/screenshots';
interface ReportingInternalSetup {
browserDriverFactory: HeadlessChromiumDriverFactory;
@ -40,8 +39,6 @@ interface ReportingInternalStart {
uiSettings: UiSettingsServiceStart;
}
export { ReportingConfig, ReportingConfigType };
export class ReportingCore {
private pluginSetupDeps?: ReportingInternalSetup;
private pluginStartDeps?: ReportingInternalStart;
@ -91,18 +88,18 @@ export class ReportingCore {
return this.exportTypesRegistry;
}
public async getEsqueue(): Promise<ESQueueInstance> {
public async getEsqueue() {
return (await this.getPluginStartDeps()).esqueue;
}
public async getEnqueueJob(): Promise<EnqueueJobFn> {
public async getEnqueueJob() {
return (await this.getPluginStartDeps()).enqueueJob;
}
public getConfig(): ReportingConfig {
public getConfig() {
return this.config;
}
public async getScreenshotsObservable(): Promise<ScreenshotsObservableFn> {
public async getScreenshotsObservable() {
const { browserDriverFactory } = await this.getPluginSetupDeps();
return screenshotsObservableFactory(this.config.get('capture'), browserDriverFactory);
}
@ -110,32 +107,30 @@ export class ReportingCore {
/*
* Outside dependencies
*/
private async getPluginSetupDeps(): Promise<ReportingInternalSetup> {
private async getPluginSetupDeps() {
if (this.pluginSetupDeps) {
return this.pluginSetupDeps;
}
return await this.pluginSetup$.pipe(first()).toPromise();
}
private async getPluginStartDeps(): Promise<ReportingInternalStart> {
private async getPluginStartDeps() {
if (this.pluginStartDeps) {
return this.pluginStartDeps;
}
return await this.pluginStart$.pipe(first()).toPromise();
}
public async getElasticsearchService(): Promise<ElasticsearchServiceSetup> {
public async getElasticsearchService() {
return (await this.getPluginSetupDeps()).elasticsearch;
}
public async getSavedObjectsClient(fakeRequest: KibanaRequest): Promise<SavedObjectsClient> {
public async getSavedObjectsClient(fakeRequest: KibanaRequest) {
const { savedObjects } = await this.getPluginStartDeps();
return savedObjects.getScopedClient(fakeRequest) as SavedObjectsClient;
}
public async getUiSettingsServiceFactory(
savedObjectsClient: SavedObjectsClient
): Promise<IUiSettingsClient> {
public async getUiSettingsServiceFactory(savedObjectsClient: SavedObjectsClient) {
const { uiSettings: uiSettingsService } = await this.getPluginStartDeps();
const scopedUiSettingsService = uiSettingsService.asScopedToClient(savedObjectsClient);
return scopedUiSettingsService;

View file

@ -5,8 +5,9 @@
*/
import { PluginInitializerContext } from 'src/core/server';
import { ReportingConfig } from './config';
import { ReportingCore } from './core';
import { ReportingPlugin as Plugin } from './plugin';
import { ReportingConfig, ReportingCore } from './core';
export const plugin = (context: PluginInitializerContext, config: ReportingConfig) => {
return new Plugin(context, config);
@ -14,5 +15,3 @@ export const plugin = (context: PluginInitializerContext, config: ReportingConfi
export { ReportingPlugin } from './plugin';
export { ReportingConfig, ReportingCore };
export { PreserveLayout, PrintLayout } from '../export_types/common/layouts';

View file

@ -7,9 +7,9 @@
import { Legacy } from 'kibana';
import { take } from 'rxjs/operators';
import { PluginInitializerContext } from 'src/core/server';
import { ReportingPluginSpecOptions } from '../';
import { PluginsSetup } from '../../../../plugins/reporting/server';
import { SecurityPluginSetup } from '../../../../plugins/security/server';
import { ReportingPluginSpecOptions } from '../types';
import { buildConfig } from './config';
import { plugin } from './index';
import { LegacySetup, ReportingStartDeps } from './types';

View file

@ -6,7 +6,8 @@
import { XPackInfo } from '../../../xpack_main/server/lib/xpack_info';
import { XPackInfoLicense } from '../../../xpack_main/server/lib/xpack_info_license';
import { ExportTypesRegistry, ExportTypeDefinition } from '../../types';
import { ExportTypeDefinition } from '../types';
import { ExportTypesRegistry } from './export_types_registry';
interface LicenseCheckResult {
showLinks: boolean;

View file

@ -4,16 +4,42 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { ESQueueInstance, Logger } from '../../types';
import { ReportingCore } from '../core';
import { JobDocOutput, JobSource } 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';
// @ts-ignore
import { Esqueue } from './esqueue';
import { LevelLogger } from './level_logger';
interface ESQueueWorker {
on: (event: string, handler: any) => void;
}
export interface ESQueueInstance {
addJob: (type: string, payload: unknown, options: object) => Job;
registerWorker: <JobParamsType>(
pluginId: string,
workerFn: GenericWorkerFn<JobParamsType>,
workerOptions: {
kibanaName: string;
kibanaId: string;
interval: number;
intervalErrorMultiplier: number;
}
) => ESQueueWorker;
}
// GenericWorkerFn is a generic for ImmediateExecuteFn<JobParamsType> | ESQueueWorkerExecuteFn<JobDocPayloadType>,
type GenericWorkerFn<JobParamsType> = (
jobSource: JobSource<JobParamsType>,
...workerRestArgs: any[]
) => void | Promise<JobDocOutput>;
export async function createQueueFactory<JobParamsType, JobPayloadType>(
reporting: ReportingCore,
logger: Logger
logger: LevelLogger
): Promise<ESQueueInstance> {
const config = reporting.getConfig();
const queueIndexInterval = config.get('queue', 'indexInterval');

View file

@ -4,9 +4,9 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { Logger } from '../../types';
import { LevelLogger } from './level_logger';
export function createTaggedLogger(logger: Logger, tags: string[]) {
export function createTaggedLogger(logger: LevelLogger, tags: string[]) {
return (msg: string, additionalTags = []) => {
const allTags = [...tags, ...additionalTags];

View file

@ -5,7 +5,7 @@
*/
import * as sinon from 'sinon';
import { ReportingConfig, ReportingCore } from '../../server/types';
import { ReportingConfig, ReportingCore } from '../../server';
import { createMockReportingCore } from '../../test_helpers';
import { createWorkerFactory } from './create_worker';
// @ts-ignore

View file

@ -4,20 +4,16 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { CancellationToken } from '../../common/cancellation_token';
import { CancellationToken } from '../../../../../plugins/reporting/common';
import { PLUGIN_ID } from '../../common/constants';
import { ReportingCore } from '../../server/types';
import {
ESQueueInstance,
ESQueueWorkerExecuteFn,
ExportTypeDefinition,
JobSource,
Logger,
} from '../../types';
import { ReportingCore } from '../../server';
import { LevelLogger } from '../../server/lib';
import { ESQueueWorkerExecuteFn, ExportTypeDefinition, JobSource } from '../../server/types';
import { ESQueueInstance } from './create_queue';
// @ts-ignore untyped dependency
import { events as esqueueEvents } from './esqueue';
export function createWorkerFactory<JobParamsType>(reporting: ReportingCore, logger: Logger) {
export function createWorkerFactory<JobParamsType>(reporting: ReportingCore, logger: LevelLogger) {
const config = reporting.getConfig();
const queueConfig = config.get('queue');
const kibanaName = config.kbnConfig.get('server', 'name');

View file

@ -4,18 +4,13 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { EventEmitter } from 'events';
import { get } from 'lodash';
import {
ConditionalHeaders,
EnqueueJobFn,
ESQueueCreateJobFn,
Job,
Logger,
RequestFacade,
} from '../../types';
import { ConditionalHeaders, ESQueueCreateJobFn, RequestFacade } from '../../server/types';
import { ReportingCore } from '../core';
// @ts-ignore
import { events as esqueueEvents } from './esqueue';
import { LevelLogger } from './level_logger';
interface ConfirmedJob {
id: string;
@ -24,7 +19,25 @@ interface ConfirmedJob {
_primary_term: number;
}
export function enqueueJobFactory(reporting: ReportingCore, parentLogger: Logger): EnqueueJobFn {
export type Job = EventEmitter & {
id: string;
toJSON: () => {
id: string;
};
};
export type EnqueueJobFn = <JobParamsType>(
exportTypeId: string,
jobParams: JobParamsType,
user: string,
headers: Record<string, string>,
request: RequestFacade
) => Promise<Job>;
export function enqueueJobFactory(
reporting: ReportingCore,
parentLogger: LevelLogger
): EnqueueJobFn {
const config = reporting.getConfig();
const queueTimeout = config.get('queue', 'timeout');
const browserType = config.get('capture', 'browser', 'type');

View file

@ -1,75 +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 expect from '@kbn/expect';
import sinon from 'sinon';
import { CancellationToken } from '../../../../../common/cancellation_token';
describe('CancellationToken', function() {
let cancellationToken;
beforeEach(function() {
cancellationToken = new CancellationToken();
});
describe('on', function() {
[true, null, undefined, 1, 'string', {}, []].forEach(function(value) {
it(`should throw an Error if value is ${value}`, function() {
expect(cancellationToken.on)
.withArgs(value)
.to.throwError();
});
});
it('accepts a function', function() {
expect(cancellationToken.on)
.withArgs(function() {})
.not.to.throwError();
});
it(`calls function if cancel has previously been called`, function() {
const spy = sinon.spy();
cancellationToken.cancel();
cancellationToken.on(spy);
expect(spy.calledOnce).to.be(true);
});
});
describe('cancel', function() {
it('should be a function accepting no parameters', function() {
expect(cancellationToken.cancel)
.withArgs()
.to.not.throwError();
});
it('should call a single callback', function() {
const spy = sinon.spy();
cancellationToken.on(spy);
cancellationToken.cancel();
expect(spy.calledOnce).to.be(true);
});
it('should call two callbacks', function() {
const spy1 = sinon.spy();
const spy2 = sinon.spy();
cancellationToken.on(spy1);
cancellationToken.on(spy2);
cancellationToken.cancel();
expect(spy1.calledOnce).to.be(true);
expect(spy2.calledOnce).to.be(true);
});
});
describe('isCancelled', function() {
it('should default to false', function() {
expect(cancellationToken.isCancelled()).to.be(false);
});
it('should switch to true after call to cancel', function() {
cancellationToken.cancel();
expect(cancellationToken.isCancelled()).to.be(true);
});
});
});

View file

@ -5,12 +5,12 @@
*/
import events from 'events';
import Puid from 'puid';
import moment from 'moment';
import { constants } from './constants';
import { WorkerTimeoutError, UnspecifiedWorkerError } from './helpers/errors';
import { CancellationToken } from '../../../common/cancellation_token';
import Puid from 'puid';
import { CancellationToken } from '../../../../../../plugins/reporting/common';
import { Poller } from '../../../../../common/poller';
import { constants } from './constants';
import { UnspecifiedWorkerError, WorkerTimeoutError } from './helpers/errors';
const puid = new Puid();

View file

@ -4,13 +4,13 @@
* you may not use this file except in compliance with the Elastic License.
*/
import memoizeOne from 'memoize-one';
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';
import { ExportTypeDefinition } from '../types';
type GetCallbackFn<JobParamsType, CreateJobFnType, JobPayloadType, ExecuteJobFnType> = (
item: ExportTypeDefinition<JobParamsType, CreateJobFnType, JobPayloadType, ExecuteJobFnType>

View file

@ -6,10 +6,10 @@
import { Legacy } from 'kibana';
import { KibanaRequest } from '../../../../../../src/core/server';
import { Logger } from '../../types';
import { ReportingSetupDeps } from '../types';
import { LevelLogger } from './level_logger';
export function getUserFactory(security: ReportingSetupDeps['security'], logger: Logger) {
export function getUserFactory(security: ReportingSetupDeps['security'], logger: LevelLogger) {
/*
* Legacy.Request because this is called from routing middleware
*/

View file

@ -9,8 +9,8 @@ import Boom from 'boom';
import { errors as elasticsearchErrors } from 'elasticsearch';
import { ElasticsearchServiceSetup } from 'kibana/server';
import { get } from 'lodash';
import { JobSource } from '../../types';
import { ReportingConfig } from '../types';
import { ReportingConfig } from '../';
import { JobSource } from '../types';
const esErrors = elasticsearchErrors as Record<string, any>;
const defaultSize = 10;

View file

@ -1,43 +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 { memoize, MemoizedFunction } from 'lodash';
import { ServerFacade } from '../../types';
type ServerFn = (server: ServerFacade) => any;
type Memo = ((server: ServerFacade) => any) & MemoizedFunction;
/**
* allow this function to be called multiple times, but
* ensure that it only received one argument, the server,
* and cache the return value so that subsequent calls get
* the exact same value.
*
* This is intended to be used by service factories like getObjectQueueFactory
*
* @param {Function} fn - the factory function
* @return {any}
*/
export function oncePerServer(fn: ServerFn) {
const memoized: Memo = memoize(function(server: ServerFacade) {
if (arguments.length !== 1) {
throw new TypeError('This function expects to be called with a single argument');
}
// @ts-ignore
return fn.call(this, server);
});
// @ts-ignore
// Type 'WeakMap<object, any>' is not assignable to type 'MapCache
// use a weak map a the cache so that:
// 1. return values mapped to the actual server instance
// 2. return value lifecycle matches that of the server
memoized.cache = new WeakMap();
return memoized;
}

View file

@ -6,9 +6,9 @@
import { i18n } from '@kbn/i18n';
import { ElasticsearchServiceSetup } from 'kibana/server';
import { Logger } from '../../../types';
import { ReportingConfig } from '../../';
import { LevelLogger } from '../../lib';
import { HeadlessChromiumDriverFactory } from '../../browsers/chromium/driver_factory';
import { ReportingConfig } from '../../types';
import { validateBrowser } from './validate_browser';
import { validateMaxContentLength } from './validate_max_content_length';
@ -16,7 +16,7 @@ export async function runValidations(
config: ReportingConfig,
elasticsearch: ElasticsearchServiceSetup,
browserFactory: HeadlessChromiumDriverFactory,
logger: Logger
logger: LevelLogger
) {
try {
await Promise.all([

View file

@ -6,8 +6,8 @@
import { Browser } from 'puppeteer';
import { BROWSER_TYPE } from '../../../common/constants';
import { Logger } from '../../../types';
import { HeadlessChromiumDriverFactory } from '../../browsers/chromium/driver_factory';
import { LevelLogger } from '../';
/*
* Validate the Reporting headless browser can launch, and that it can connect
@ -15,7 +15,7 @@ import { HeadlessChromiumDriverFactory } from '../../browsers/chromium/driver_fa
*/
export const validateBrowser = async (
browserFactory: HeadlessChromiumDriverFactory,
logger: Logger
logger: LevelLogger
) => {
if (browserFactory.type === BROWSER_TYPE) {
return browserFactory.test(logger).then((browser: Browser | null) => {

View file

@ -7,8 +7,8 @@
import numeral from '@elastic/numeral';
import { ElasticsearchServiceSetup } from 'kibana/server';
import { defaults, get } from 'lodash';
import { Logger } from '../../../types';
import { ReportingConfig } from '../../types';
import { ReportingConfig } from '../../';
import { LevelLogger } from '../../lib';
const KIBANA_MAX_SIZE_BYTES_PATH = 'csv.maxSizeBytes';
const ES_MAX_SIZE_BYTES_PATH = 'http.max_content_length';
@ -16,7 +16,7 @@ const ES_MAX_SIZE_BYTES_PATH = 'http.max_content_length';
export async function validateMaxContentLength(
config: ReportingConfig,
elasticsearch: ElasticsearchServiceSetup,
logger: Logger
logger: LevelLogger
) {
const { callAsInternalUser } = elasticsearch.dataClient;

View file

@ -6,7 +6,8 @@
import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'src/core/server';
import { createBrowserDriverFactory } from './browsers';
import { ReportingCore, ReportingConfig } from './core';
import { ReportingConfig } from './config';
import { ReportingCore } from './core';
import { createQueueFactory, enqueueJobFactory, LevelLogger, runValidations } from './lib';
import { setFieldFormats } from './services';
import { ReportingSetup, ReportingSetupDeps, ReportingStart, ReportingStartDeps } from './types';

View file

@ -8,16 +8,17 @@ import boom from 'boom';
import Joi from 'joi';
import { Legacy } from 'kibana';
import rison from 'rison-node';
import { ReportingCore } from '../';
import { API_BASE_URL } from '../../common/constants';
import { Logger, ReportingResponseToolkit, ServerFacade } from '../../types';
import { ReportingCore, ReportingSetupDeps } from '../types';
import { LevelLogger as Logger } from '../lib';
import { ReportingSetupDeps, ServerFacade } from '../types';
import { makeRequestFacade } from './lib/make_request_facade';
import {
GetRouteConfigFactoryFn,
getRouteConfigFactoryReportingPre,
RouteConfigFactory,
} from './lib/route_config_factories';
import { HandlerErrorFunction, HandlerFunction } from './types';
import { HandlerErrorFunction, HandlerFunction, ReportingResponseToolkit } from './types';
const BASE_GENERATE = `${API_BASE_URL}/generate`;

View file

@ -6,13 +6,19 @@
import { Legacy } from 'kibana';
import { get } from 'lodash';
import { ReportingCore } from '../';
import { API_BASE_GENERATE_V1, CSV_FROM_SAVEDOBJECT_JOB_TYPE } from '../../common/constants';
import { getJobParamsFromRequest } from '../../export_types/csv_from_savedobject/server/lib/get_job_params_from_request';
import { Logger, ReportingResponseToolkit, ServerFacade } from '../../types';
import { ReportingCore, ReportingSetupDeps } from '../types';
import { LevelLogger as Logger } from '../lib';
import { ReportingSetupDeps, ServerFacade } from '../types';
import { makeRequestFacade } from './lib/make_request_facade';
import { getRouteOptionsCsv } from './lib/route_config_factories';
import { HandlerErrorFunction, HandlerFunction, QueuedJobPayload } from './types';
import {
HandlerErrorFunction,
HandlerFunction,
QueuedJobPayload,
ReportingResponseToolkit,
} from './types';
/*
* This function registers API Endpoints for queuing Reporting jobs. The API inputs are:

View file

@ -4,21 +4,22 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { ResponseObject } from 'hapi';
import { Legacy } from 'kibana';
import { ReportingCore } from '../';
import { API_BASE_GENERATE_V1 } from '../../common/constants';
import { createJobFactory, executeJobFactory } from '../../export_types/csv_from_savedobject';
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 {
JobDocOutput,
Logger,
ReportingResponseToolkit,
ResponseFacade,
ServerFacade,
} from '../../types';
import { ReportingCore, ReportingSetupDeps } from '../types';
import { LevelLogger as Logger } from '../lib';
import { JobDocOutput, ReportingSetupDeps, ServerFacade } from '../types';
import { makeRequestFacade } from './lib/make_request_facade';
import { getRouteOptionsCsv } from './lib/route_config_factories';
import { ReportingResponseToolkit } from './types';
type ResponseFacade = ResponseObject & {
isBoom: boolean;
};
/*
* This function registers API Endpoints for immediate Reporting jobs. The API inputs are:

View file

@ -5,9 +5,11 @@
*/
import Hapi from 'hapi';
import { ReportingConfig, ReportingCore } from '../';
import { createMockReportingCore } from '../../test_helpers';
import { Logger, ServerFacade } from '../../types';
import { ReportingConfig, ReportingCore, ReportingSetupDeps } from '../types';
import { LevelLogger as Logger } from '../lib';
import { ReportingSetupDeps, ServerFacade } from '../types';
import { registerJobGenerationRoutes } from './generation';
jest.mock('./lib/authorized_user_pre_routing', () => ({
authorizedUserPreRoutingFactory: () => () => ({}),
@ -18,8 +20,6 @@ jest.mock('./lib/reporting_feature_pre_routing', () => ({
}),
}));
import { registerJobGenerationRoutes } from './generation';
let mockServer: Hapi.Server;
let mockReportingPlugin: ReportingCore;
let mockReportingConfig: ReportingConfig;

View file

@ -7,13 +7,15 @@
import boom from 'boom';
import { errors as elasticsearchErrors } from 'elasticsearch';
import { Legacy } from 'kibana';
import { ReportingCore } from '../';
import { API_BASE_URL } from '../../common/constants';
import { Logger, ReportingResponseToolkit, ServerFacade } from '../../types';
import { ReportingCore, ReportingSetupDeps } from '../types';
import { LevelLogger as Logger } from '../lib';
import { ReportingSetupDeps, ServerFacade } from '../types';
import { registerGenerateFromJobParams } from './generate_from_jobparams';
import { registerGenerateCsvFromSavedObject } from './generate_from_savedobject';
import { registerGenerateCsvFromSavedObjectImmediate } from './generate_from_savedobject_immediate';
import { makeRequestFacade } from './lib/make_request_facade';
import { ReportingResponseToolkit } from './types';
const esErrors = elasticsearchErrors as Record<string, any>;

View file

@ -4,8 +4,9 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { Logger, ServerFacade } from '../../types';
import { ReportingCore, ReportingSetupDeps } from '../types';
import { ReportingCore } from '../';
import { LevelLogger as Logger } from '../lib';
import { ReportingSetupDeps, ServerFacade } from '../types';
import { registerJobGenerationRoutes } from './generation';
import { registerJobInfoRoutes } from './jobs';

View file

@ -5,11 +5,12 @@
*/
import Hapi from 'hapi';
import { ReportingConfig, ReportingCore } from '../';
import { LevelLogger } from '../lib';
import { createMockReportingCore } from '../../test_helpers';
import { ExportTypeDefinition } from '../../types';
import { ExportTypesRegistry } from '../lib/export_types_registry';
import { LevelLogger } from '../lib/level_logger';
import { ReportingConfig, ReportingCore, ReportingSetupDeps } from '../types';
import { ExportTypeDefinition, ReportingSetupDeps } from '../types';
import { registerJobInfoRoutes } from './jobs';
jest.mock('./lib/authorized_user_pre_routing', () => ({
authorizedUserPreRoutingFactory: () => () => ({}),
@ -20,8 +21,6 @@ jest.mock('./lib/reporting_feature_pre_routing', () => ({
}),
}));
import { registerJobInfoRoutes } from './jobs';
let mockServer: any;
let exportTypesRegistry: ExportTypesRegistry;
let mockReportingPlugin: ReportingCore;

View file

@ -7,17 +7,11 @@
import Boom from 'boom';
import { ResponseObject } from 'hapi';
import { Legacy } from 'kibana';
import { ReportingCore } from '../';
import { API_BASE_URL } from '../../common/constants';
import {
JobDocOutput,
JobSource,
ListQuery,
Logger,
ReportingResponseToolkit,
ServerFacade,
} from '../../types';
import { LevelLogger as Logger } from '../lib';
import { jobsQueryFactory } from '../lib/jobs_query';
import { ReportingCore, ReportingSetupDeps } from '../types';
import { JobDocOutput, JobSource, ReportingSetupDeps, ServerFacade } from '../types';
import {
deleteJobResponseHandlerFactory,
downloadJobResponseHandlerFactory,
@ -28,7 +22,13 @@ import {
getRouteConfigFactoryDownloadPre,
getRouteConfigFactoryManagementPre,
} from './lib/route_config_factories';
import { ReportingResponseToolkit } from './types';
interface ListQuery {
page: string;
size: string;
ids?: string; // optional field forbids us from extending RequestQuery
}
const MAIN_ENTRY = `${API_BASE_URL}/jobs`;
function isResponse(response: Boom<null> | ResponseObject): response is ResponseObject {

View file

@ -8,9 +8,9 @@ import Boom from 'boom';
import { Legacy } from 'kibana';
import { AuthenticatedUser } from '../../../../../../plugins/security/server';
import { ReportingConfig } from '../../../server';
import { Logger } from '../../../types';
import { LevelLogger as Logger } from '../../../server/lib';
import { ReportingSetupDeps } from '../../../server/types';
import { getUserFactory } from '../../lib/get_user';
import { ReportingSetupDeps } from '../../types';
const superuserRole = 'superuser';

View file

@ -8,8 +8,9 @@
import contentDisposition from 'content-disposition';
import * as _ from 'lodash';
import { CSV_JOB_TYPE } from '../../../common/constants';
import { ExportTypeDefinition, ExportTypesRegistry, JobDocOutput, JobSource } from '../../../types';
import { statuses } from '../../lib/esqueue/constants/statuses';
import { ExportTypesRegistry } from '../../lib/export_types_registry';
import { ExportTypeDefinition, JobDocOutput, JobSource } from '../../types';
interface ICustomHeaders {
[x: string]: any;

View file

@ -7,10 +7,10 @@
import Boom from 'boom';
import { ResponseToolkit } from 'hapi';
import { ElasticsearchServiceSetup } from 'kibana/server';
import { ReportingConfig } from '../../';
import { WHITELISTED_JOB_CONTENT_TYPES } from '../../../common/constants';
import { ExportTypesRegistry } from '../../../types';
import { ExportTypesRegistry } from '../../lib/export_types_registry';
import { jobsQueryFactory } from '../../lib/jobs_query';
import { ReportingConfig } from '../../types';
import { getDocumentPayloadFactory } from './get_document_payload';
interface JobResponseHandlerParams {

Some files were not shown because too many files have changed in this diff Show more