From 7deba6b998ab15946162d16d75bf0177b3c109ac Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 8 Feb 2022 16:11:06 +0200 Subject: [PATCH 01/57] Client side execution app level context propagation --- src/core/public/core_system.ts | 18 ++++++- .../execution_context_service.ts | 53 +++++++++++++++++++ src/core/public/execution_context/index.ts | 2 + src/core/public/http/fetch.ts | 11 ++-- src/core/public/http/http_service.ts | 7 ++- src/core/public/index.ts | 5 ++ src/core/public/plugins/plugin_context.ts | 2 + .../public/application/dashboard_app.tsx | 5 ++ .../application/listing/dashboard_listing.tsx | 5 ++ .../search_interceptor/search_interceptor.ts | 10 +++- .../data/public/search/search_service.ts | 3 +- src/plugins/dev_tools/public/application.tsx | 7 ++- src/plugins/dev_tools/public/plugin.ts | 3 +- .../application/context/context_app.tsx | 8 ++- .../application/doc/single_doc_route.tsx | 8 ++- .../application/main/discover_main_route.tsx | 6 +++ .../components/visualize_editor.tsx | 7 +++ .../components/visualize_listing.tsx | 7 +++ x-pack/plugins/lens/public/app_plugin/app.tsx | 11 +++- .../lens/public/app_plugin/mounter.tsx | 1 + .../plugins/lens/public/app_plugin/types.ts | 2 + x-pack/plugins/maps/public/kibana_services.ts | 1 + .../routes/list_page/maps_list_view.tsx | 7 +++ .../routes/map_page/map_app/map_app.tsx | 8 +++ 24 files changed, 183 insertions(+), 14 deletions(-) create mode 100644 src/core/public/execution_context/execution_context_service.ts diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index 3d3331d54792bb..2ee91458399d88 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -31,6 +31,7 @@ import { DeprecationsService } from './deprecations'; import { ThemeService } from './theme'; import { CoreApp } from './core_app'; import type { InternalApplicationSetup, InternalApplicationStart } from './application/types'; +import { ExecutionContextService } from './execution_context'; interface Params { rootDomElement: HTMLElement; @@ -87,6 +88,7 @@ export class CoreSystem { private readonly theme: ThemeService; private readonly rootDomElement: HTMLElement; private readonly coreContext: CoreContext; + private readonly executionContext: ExecutionContextService; private fatalErrorsSetup: FatalErrorsSetup | null = null; constructor(params: Params) { @@ -121,6 +123,7 @@ export class CoreSystem { this.application = new ApplicationService(); this.integrations = new IntegrationsService(); this.deprecations = new DeprecationsService(); + this.executionContext = new ExecutionContextService(); this.plugins = new PluginsService(this.coreContext, injectedMetadata.uiPlugins); this.coreApp = new CoreApp(this.coreContext); @@ -137,7 +140,9 @@ export class CoreSystem { }); await this.integrations.setup(); this.docLinks.setup(); - const http = this.http.setup({ injectedMetadata, fatalErrors: this.fatalErrorsSetup }); + + const executionContext = this.executionContext.setup(); + const http = this.http.setup({ injectedMetadata, fatalErrors: this.fatalErrorsSetup, executionContext }); const uiSettings = this.uiSettings.setup({ http, injectedMetadata }); const notifications = this.notifications.setup({ uiSettings }); const theme = this.theme.setup({ injectedMetadata }); @@ -153,6 +158,7 @@ export class CoreSystem { notifications, theme, uiSettings, + executionContext, }; // Services that do not expose contracts at setup @@ -180,6 +186,7 @@ export class CoreSystem { const i18n = await this.i18n.start(); const fatalErrors = await this.fatalErrors.start(); const theme = this.theme.start(); + const executionContext = this.executionContext.start(); await this.integrations.start({ uiSettings }); const coreUiTargetDomElement = document.createElement('div'); @@ -201,6 +208,14 @@ export class CoreSystem { targetDomElement: notificationsTargetDomElement, }); const application = await this.application.start({ http, theme, overlays }); + + application.currentAppId$.subscribe(appId => { + executionContext.clear(); + executionContext.set({ + appId + }) + }) + const chrome = await this.chrome.start({ application, docLinks, @@ -216,6 +231,7 @@ export class CoreSystem { application, chrome, docLinks, + executionContext, http, theme, savedObjects, diff --git a/src/core/public/execution_context/execution_context_service.ts b/src/core/public/execution_context/execution_context_service.ts new file mode 100644 index 00000000000000..7377d3bc438873 --- /dev/null +++ b/src/core/public/execution_context/execution_context_service.ts @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { CoreService } from '../../types'; + +/** @public */ +export interface ExecutionContextSetup { + set(c$: Record): void; + getAll(): Record; + clear(): void; +} + +/** + * See {@link ExecutionContextSetup}. + * @public + */ +export type ExecutionContextStart = ExecutionContextSetup; + +/** @internal */ +export class ExecutionContextService implements CoreService { + private context: Record = {}; + + public setup() { + return { + clear: () => { + this.context = {}; + }, + set: (c: Record) => { + this.context = { + ...this.context, + ...c + } + }, + getAll: () => { + return { + app: this.context + } + } + }; + } + + public start() { + return this.setup(); + } + + public stop() { + } +} diff --git a/src/core/public/execution_context/index.ts b/src/core/public/execution_context/index.ts index b15a967ac714aa..32386547907a75 100644 --- a/src/core/public/execution_context/index.ts +++ b/src/core/public/execution_context/index.ts @@ -8,3 +8,5 @@ export type { KibanaExecutionContext } from '../../types'; export { ExecutionContextContainer } from './execution_context_container'; +export { ExecutionContextService } from './execution_context_service'; +export type { ExecutionContextSetup, ExecutionContextStart } from './execution_context_service'; \ No newline at end of file diff --git a/src/core/public/http/fetch.ts b/src/core/public/http/fetch.ts index 4ee81f4b47aa0c..14566b34de8b4b 100644 --- a/src/core/public/http/fetch.ts +++ b/src/core/public/http/fetch.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { omitBy } from 'lodash'; +import { isEmpty, omitBy } from 'lodash'; import { format } from 'url'; import { BehaviorSubject } from 'rxjs'; @@ -22,11 +22,12 @@ import { HttpFetchError } from './http_fetch_error'; import { HttpInterceptController } from './http_intercept_controller'; import { interceptRequest, interceptResponse } from './intercept'; import { HttpInterceptHaltError } from './http_intercept_halt_error'; -import { ExecutionContextContainer } from '../execution_context'; +import { ExecutionContextContainer, ExecutionContextSetup } from '../execution_context'; interface Params { basePath: IBasePath; kibanaVersion: string; + executionContext: ExecutionContextSetup; } const JSON_CONTENT = /^(application\/(json|x-javascript)|text\/(x-)?javascript|x-json)(;.*)?$/; @@ -107,6 +108,10 @@ export class Fetch { }; private createRequest(options: HttpFetchOptionsWithPath): Request { + const context = { + ...this.params.executionContext?.getAll(), + ...options.context, + } // Merge and destructure options out that are not applicable to the Fetch API. const { query, @@ -125,7 +130,7 @@ export class Fetch { 'Content-Type': 'application/json', ...options.headers, 'kbn-version': this.params.kibanaVersion, - ...(options.context ? new ExecutionContextContainer(options.context).toHeader() : {}), + ...(!isEmpty(context) ? new ExecutionContextContainer(context as any).toHeader() : {}), }), }; diff --git a/src/core/public/http/http_service.ts b/src/core/public/http/http_service.ts index a9719cfce67aff..390130da4e07dd 100644 --- a/src/core/public/http/http_service.ts +++ b/src/core/public/http/http_service.ts @@ -15,10 +15,12 @@ import { LoadingCountService } from './loading_count_service'; import { Fetch } from './fetch'; import { CoreService } from '../../types'; import { ExternalUrlService } from './external_url_service'; +import { ExecutionContextSetup } from '../execution_context'; interface HttpDeps { injectedMetadata: InjectedMetadataSetup; fatalErrors: FatalErrorsSetup; + executionContext: ExecutionContextSetup; } /** @internal */ @@ -27,14 +29,15 @@ export class HttpService implements CoreService { private readonly loadingCount = new LoadingCountService(); private service?: HttpSetup; - public setup({ injectedMetadata, fatalErrors }: HttpDeps): HttpSetup { + public setup({ injectedMetadata, fatalErrors, executionContext }: HttpDeps): HttpSetup { const kibanaVersion = injectedMetadata.getKibanaVersion(); const basePath = new BasePath( injectedMetadata.getBasePath(), injectedMetadata.getServerBasePath(), injectedMetadata.getPublicBaseUrl() ); - const fetchService = new Fetch({ basePath, kibanaVersion }); + + const fetchService = new Fetch({ basePath, kibanaVersion, executionContext }); const loadingCount = this.loadingCount.setup({ fatalErrors }); loadingCount.addLoadingCountSource(fetchService.getRequestCount$()); diff --git a/src/core/public/index.ts b/src/core/public/index.ts index ded7db9c6f892d..87335206fbea27 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -65,6 +65,7 @@ import { DocLinksStart } from './doc_links'; import { SavedObjectsStart } from './saved_objects'; import { DeprecationsServiceStart } from './deprecations'; import type { ThemeServiceSetup, ThemeServiceStart } from './theme'; +import { ExecutionContextSetup, ExecutionContextStart } from './execution_context'; export type { PackageInfo, @@ -221,6 +222,8 @@ export interface CoreSetup deps.application.registerAppUpdater(statusUpdater$), }, fatalErrors: deps.fatalErrors, + executionContext: deps.executionContext, http: deps.http, notifications: deps.notifications, uiSettings: deps.uiSettings, @@ -129,6 +130,7 @@ export function createPluginStartContext< getUrlForApp: deps.application.getUrlForApp, }, docLinks: deps.docLinks, + executionContext: deps.executionContext, http: deps.http, chrome: omit(deps.chrome, 'getComponent'), i18n: deps.i18n, diff --git a/src/plugins/dashboard/public/application/dashboard_app.tsx b/src/plugins/dashboard/public/application/dashboard_app.tsx index 7aedbe9e110019..8985cd78d46b61 100644 --- a/src/plugins/dashboard/public/application/dashboard_app.tsx +++ b/src/plugins/dashboard/public/application/dashboard_app.tsx @@ -48,6 +48,11 @@ export function DashboardApp({ [core.notifications.toasts, history, uiSettings] ); + core.executionContext.set({ + page: 'app', + id: savedDashboardId || 'new', + }); + const dashboardState = useDashboardSelector((state) => state.dashboardStateReducer); const dashboardAppState = useDashboardAppState({ history, diff --git a/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx b/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx index 5b53fc47e06a41..99f867de324748 100644 --- a/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx +++ b/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx @@ -67,6 +67,11 @@ export const DashboardListing = ({ dashboardSessionStorage.getDashboardIdsWithUnsavedChanges() ); + core.executionContext.set({ + page: 'list', + id: '', + }) + // Set breadcrumbs useEffect useEffect(() => { setBreadcrumbs([ diff --git a/src/plugins/data/public/search/search_interceptor/search_interceptor.ts b/src/plugins/data/public/search/search_interceptor/search_interceptor.ts index 7dc1ce6dee0786..c00f012bdb548a 100644 --- a/src/plugins/data/public/search/search_interceptor/search_interceptor.ts +++ b/src/plugins/data/public/search/search_interceptor/search_interceptor.ts @@ -61,6 +61,7 @@ import { SearchAbortController } from './search_abort_controller'; export interface SearchInterceptorDeps { bfetch: BfetchPublicSetup; http: CoreSetup['http']; + executionContext: CoreSetup['executionContext']; uiSettings: CoreSetup['uiSettings']; startServices: Promise<[CoreStart, any, unknown]>; toasts: ToastsSetup; @@ -297,10 +298,17 @@ export class SearchInterceptor { } }) as Promise; } else { + const { executionContext, ...rest } = options || {}; return this.batchedFetch( { request, - options: this.getSerializableOptions(options), + options: this.getSerializableOptions({ + ...rest, + executionContext: { + ...executionContext, + ...this.deps.executionContext.getAll(), + } as any + }), }, abortSignal ); diff --git a/src/plugins/data/public/search/search_service.ts b/src/plugins/data/public/search/search_service.ts index 961599de713df8..b21ad44c7bd6de 100644 --- a/src/plugins/data/public/search/search_service.ts +++ b/src/plugins/data/public/search/search_service.ts @@ -89,7 +89,7 @@ export class SearchService implements Plugin { constructor(private initializerContext: PluginInitializerContext) {} public setup( - { http, getStartServices, notifications, uiSettings, theme }: CoreSetup, + { http, getStartServices, notifications, uiSettings, executionContext, theme }: CoreSetup, { bfetch, expressions, usageCollection, nowProvider }: SearchServiceSetupDependencies ): ISearchSetup { this.usageCollector = createUsageCollector(getStartServices, usageCollection); @@ -108,6 +108,7 @@ export class SearchService implements Plugin { this.searchInterceptor = new SearchInterceptor({ bfetch, toasts: notifications.toasts, + executionContext, http, uiSettings, startServices: getStartServices(), diff --git a/src/plugins/dev_tools/public/application.tsx b/src/plugins/dev_tools/public/application.tsx index a3ec8fc0a9af20..a6718b1bd721cc 100644 --- a/src/plugins/dev_tools/public/application.tsx +++ b/src/plugins/dev_tools/public/application.tsx @@ -15,7 +15,7 @@ import { I18nProvider } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { euiThemeVars } from '@kbn/ui-theme'; -import { ApplicationStart, ChromeStart, ScopedHistory, CoreTheme } from 'src/core/public'; +import { ApplicationStart, ChromeStart, ScopedHistory, CoreTheme, CoreStart } from 'src/core/public'; import { KibanaThemeProvider } from '../../kibana_react/public'; import type { DocTitleService, BreadcrumbService } from './services'; @@ -24,6 +24,7 @@ import { DevToolApp } from './dev_tool'; export interface AppServices { docTitleService: DocTitleService; breadcrumbService: BreadcrumbService; + executionContext: CoreStart['executionContext']; } interface DevToolsWrapperProps { @@ -64,6 +65,10 @@ function DevToolsWrapper({ breadcrumbService.setBreadcrumbs(activeDevTool.title); }, [activeDevTool, docTitleService, breadcrumbService]); + appServices.executionContext.set({ + page: activeDevTool, + }) + return (
diff --git a/src/plugins/dev_tools/public/plugin.ts b/src/plugins/dev_tools/public/plugin.ts index 1876bf278513e6..ee729c8f4400c0 100644 --- a/src/plugins/dev_tools/public/plugin.ts +++ b/src/plugins/dev_tools/public/plugin.ts @@ -61,7 +61,7 @@ export class DevToolsPlugin implements Plugin { element.classList.add('devAppWrapper'); const [core] = await getStartServices(); - const { application, chrome } = core; + const { application, chrome, executionContext } = core; this.docTitleService.setup(chrome.docTitle.change); this.breadcrumbService.setup(chrome.setBreadcrumbs); @@ -69,6 +69,7 @@ export class DevToolsPlugin implements Plugin { const appServices = { breadcrumbService: this.breadcrumbService, docTitleService: this.docTitleService, + executionContext, }; const { renderApp } = await import('./application'); diff --git a/src/plugins/discover/public/application/context/context_app.tsx b/src/plugins/discover/public/application/context/context_app.tsx index f93bc2b49fdd51..0f4e5209ee8b26 100644 --- a/src/plugins/discover/public/application/context/context_app.tsx +++ b/src/plugins/discover/public/application/context/context_app.tsx @@ -36,11 +36,17 @@ export interface ContextAppProps { export const ContextApp = ({ indexPattern, anchorId }: ContextAppProps) => { const services = useDiscoverServices(); - const { uiSettings, capabilities, indexPatterns, navigation, filterManager } = services; + const { uiSettings, capabilities, indexPatterns, navigation, filterManager, core } = services; const isLegacy = useMemo(() => uiSettings.get(DOC_TABLE_LEGACY), [uiSettings]); const useNewFieldsApi = useMemo(() => !uiSettings.get(SEARCH_FIELDS_FROM_SOURCE), [uiSettings]); + core.executionContext.set({ + page: 'context', + id: indexPattern.id || '', + }); + + /** * Context app state */ diff --git a/src/plugins/discover/public/application/doc/single_doc_route.tsx b/src/plugins/discover/public/application/doc/single_doc_route.tsx index d11c6bdca76a04..1926a01fe16a95 100644 --- a/src/plugins/discover/public/application/doc/single_doc_route.tsx +++ b/src/plugins/discover/public/application/doc/single_doc_route.tsx @@ -31,11 +31,17 @@ export interface DocUrlParams { const SingleDoc = ({ id }: SingleDocRouteProps) => { const services = useDiscoverServices(); - const { chrome, timefilter } = services; + const { chrome, timefilter, core } = services; const { indexPatternId, index } = useParams(); const breadcrumb = useMainRouteBreadcrumb(); + core.executionContext.set({ + page: 'single-doc', + id: indexPatternId || '', + }); + + useEffect(() => { chrome.setBreadcrumbs([ ...getRootBreadcrumbs(breadcrumb), diff --git a/src/plugins/discover/public/application/main/discover_main_route.tsx b/src/plugins/discover/public/application/main/discover_main_route.tsx index d5950085b94c72..30dff57cae45e3 100644 --- a/src/plugins/discover/public/application/main/discover_main_route.tsx +++ b/src/plugins/discover/public/application/main/discover_main_route.tsx @@ -50,6 +50,12 @@ export function DiscoverMainRoute() { >([]); const { id } = useParams(); + core.executionContext.set({ + page: 'app', + id: id || 'new', + }); + + const navigateToOverview = useCallback(() => { core.application.navigateToApp('kibanaOverview', { path: '#' }); }, [core.application]); diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx index 45241ec501084c..6f0725c6420b8d 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx @@ -33,6 +33,13 @@ export const VisualizeEditor = ({ onAppLeave }: VisualizeAppProps) => { const [eventEmitter] = useState(new EventEmitter()); const [hasUnsavedChanges, setHasUnsavedChanges] = useState(!visualizationIdFromUrl); + + services.executionContext.set({ + page: 'editor', + id: visualizationIdFromUrl, + }) + + const isChromeVisible = useChromeVisibility(services.chrome); const { savedVisInstance, visEditorRef, visEditorController } = useSavedVisInstance( services, diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx index cf219b1cda117d..1861be444b384b 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx @@ -31,6 +31,7 @@ export const VisualizeListing = () => { const { services: { application, + executionContext, chrome, history, toastNotifications, @@ -96,6 +97,12 @@ export const VisualizeListing = () => { [application, history] ); + executionContext.set({ + page: 'list', + id: '', + }) + + const noItemsFragment = useMemo(() => getNoItemsMessage(createNewVis), [createNewVis]); const tableColumns = useMemo( () => getTableColumns(application, kbnUrlStateStorage, savedObjectsTagging), diff --git a/x-pack/plugins/lens/public/app_plugin/app.tsx b/x-pack/plugins/lens/public/app_plugin/app.tsx index 78e739a6324ec8..b4efcd9b1289fe 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.tsx @@ -69,6 +69,7 @@ export function App({ getOriginatingAppName, spaces, http, + executionContext, // Temporarily required until the 'by value' paradigm is default. dashboardFeatureFlag, } = lensAppServices; @@ -105,6 +106,7 @@ export function App({ const [indicateNoData, setIndicateNoData] = useState(false); const [isSaveModalVisible, setIsSaveModalVisible] = useState(false); const [lastKnownDoc, setLastKnownDoc] = useState(undefined); + const savedObjectId = (initialInput as LensByReferenceInput)?.savedObjectId; useEffect(() => { if (currentDoc) { @@ -116,6 +118,11 @@ export function App({ setIndicateNoData(true); }, [setIndicateNoData]); + executionContext.set({ + id: savedObjectId || 'new', + page: 'editor', + }); + useEffect(() => { if (indicateNoData) { setIndicateNoData(false); @@ -128,9 +135,9 @@ export function App({ // Temporarily required until the 'by value' paradigm is default. dashboardFeatureFlag.allowByValueEmbeddables && isLinkedToOriginatingApp && - !(initialInput as LensByReferenceInput)?.savedObjectId + !savedObjectId ), - [dashboardFeatureFlag.allowByValueEmbeddables, isLinkedToOriginatingApp, initialInput] + [dashboardFeatureFlag.allowByValueEmbeddables, isLinkedToOriginatingApp, savedObjectId] ); useEffect(() => { diff --git a/x-pack/plugins/lens/public/app_plugin/mounter.tsx b/x-pack/plugins/lens/public/app_plugin/mounter.tsx index ff45c996cce981..c86367d02bf43f 100644 --- a/x-pack/plugins/lens/public/app_plugin/mounter.tsx +++ b/x-pack/plugins/lens/public/app_plugin/mounter.tsx @@ -76,6 +76,7 @@ export async function getLensServices( usageCollection, savedObjectsTagging, attributeService, + executionContext: coreStart.executionContext, http: coreStart.http, chrome: coreStart.chrome, overlays: coreStart.overlays, diff --git a/x-pack/plugins/lens/public/app_plugin/types.ts b/x-pack/plugins/lens/public/app_plugin/types.ts index a5cd8bfef71f35..70c75b5345994e 100644 --- a/x-pack/plugins/lens/public/app_plugin/types.ts +++ b/x-pack/plugins/lens/public/app_plugin/types.ts @@ -12,6 +12,7 @@ import type { ApplicationStart, AppMountParameters, ChromeStart, + CoreStart, HttpStart, IUiSettingsClient, NotificationsStart, @@ -98,6 +99,7 @@ export interface HistoryLocationState { export interface LensAppServices { http: HttpStart; + executionContext: CoreStart['executionContext']; chrome: ChromeStart; overlays: OverlayStart; storage: IStorageWrapper; diff --git a/x-pack/plugins/maps/public/kibana_services.ts b/x-pack/plugins/maps/public/kibana_services.ts index 027981de32295e..d56329ae102b42 100644 --- a/x-pack/plugins/maps/public/kibana_services.ts +++ b/x-pack/plugins/maps/public/kibana_services.ts @@ -33,6 +33,7 @@ export const getUiSettings = () => coreStart.uiSettings; export const getIsDarkMode = () => getUiSettings().get('theme:darkMode', false); export const getIndexPatternSelectComponent = () => pluginsStart.data.ui.IndexPatternSelect; export const getHttp = () => coreStart.http; +export const getExecutionContext = () => coreStart.executionContext; export const getTimeFilter = () => pluginsStart.data.query.timefilter.timefilter; export const getToasts = () => coreStart.notifications.toasts; export const getSavedObjectsClient = () => coreStart.savedObjects.client; diff --git a/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx b/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx index 571cba64a06c45..21abe54e0d5d45 100644 --- a/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx +++ b/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx @@ -17,6 +17,7 @@ import { getMapsCapabilities, getToasts, getCoreChrome, + getExecutionContext, getNavigateToApp, getSavedObjectsClient, getSavedObjectsTagging, @@ -121,6 +122,12 @@ async function deleteMaps(items: object[]) { } export function MapsListView() { + + getExecutionContext().set({ + page: 'list', + id: '', + }) + const isReadOnly = !getMapsCapabilities().save; getCoreChrome().docTitle.change(getAppTitle()); diff --git a/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx b/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx index 9aede248e1877d..234c8e34d2ac6e 100644 --- a/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx +++ b/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx @@ -16,6 +16,7 @@ import { type Filter, FilterStateStore } from '@kbn/es-query'; import type { Query, TimeRange, DataView } from 'src/plugins/data/common'; import { getData, + getExecutionContext, getCoreChrome, getMapsCapabilities, getNavigation, @@ -115,6 +116,13 @@ export class MapApp extends React.Component { componentDidMount() { this._isMounted = true; + + getExecutionContext().set({ + page: 'editor', + id: this.props.savedMap.getSavedObjectId() || 'new', + }) + + this._autoRefreshSubscription = getTimeFilter() .getAutoRefreshFetch$() .pipe( From c44c4f28fcc2e605b415f21ae241d7494bb9377f Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 8 Feb 2022 16:57:18 +0200 Subject: [PATCH 02/57] context$ + apm rum integration --- src/core/public/apm_system.ts | 11 ++++++++ src/core/public/core_system.ts | 1 + .../execution_context_service.ts | 28 +++++++++++++------ 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/core/public/apm_system.ts b/src/core/public/apm_system.ts index 2231f394381f04..a0ad71a663be93 100644 --- a/src/core/public/apm_system.ts +++ b/src/core/public/apm_system.ts @@ -10,6 +10,7 @@ import type { ApmBase, AgentConfigOptions, Transaction } from '@elastic/apm-rum' import { modifyUrl } from '@kbn/std'; import { CachedResourceObserver } from './apm_resource_counter'; import type { InternalApplicationStart } from './application'; +import { ExecutionContextStart } from './execution_context'; /** "GET protocol://hostname:port/pathname" */ const HTTP_REQUEST_TRANSACTION_NAME_REGEX = @@ -27,6 +28,7 @@ interface ApmConfig extends AgentConfigOptions { interface StartDeps { application: InternalApplicationStart; + executionContext: ExecutionContextStart; } export class ApmSystem { @@ -34,6 +36,7 @@ export class ApmSystem { private pageLoadTransaction?: Transaction; private resourceObserver: CachedResourceObserver; private apm?: ApmBase; + /** * `apmConfig` would be populated with relevant APM RUM agent * configuration if server is started with elastic.apm.* config. @@ -64,6 +67,14 @@ export class ApmSystem { this.markPageLoadStart(); + start.executionContext.context$.subscribe(c => { + // We're using labels because we want the context to be indexed + // https://www.elastic.co/guide/en/apm/get-started/current/metadata.html + this.apm?.addLabels(c); + }); + + // TODO: Start a new transaction every page change instead of every app change. + /** * Register listeners for navigation changes and capture them as * route-change transactions after Kibana app is bootstrapped diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index 2ee91458399d88..5f67ce224849fb 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -264,6 +264,7 @@ export class CoreSystem { return { application, + executionContext, }; } catch (error) { if (this.fatalErrorsSetup) { diff --git a/src/core/public/execution_context/execution_context_service.ts b/src/core/public/execution_context/execution_context_service.ts index 7377d3bc438873..3e297776f7fe76 100644 --- a/src/core/public/execution_context/execution_context_service.ts +++ b/src/core/public/execution_context/execution_context_service.ts @@ -6,10 +6,14 @@ * Side Public License, v 1. */ +import { isEqual } from 'lodash'; +import { BehaviorSubject, Observable } from 'rxjs'; import { CoreService } from '../../types'; +export type ExecutionContext = Record; /** @public */ export interface ExecutionContextSetup { + context$: Observable; set(c$: Record): void; getAll(): Record; clear(): void; @@ -23,23 +27,29 @@ export type ExecutionContextStart = ExecutionContextSetup; /** @internal */ export class ExecutionContextService implements CoreService { - private context: Record = {}; + // private context: Record = {}; + private context$: BehaviorSubject = new BehaviorSubject({}); public setup() { return { + context$: this.context$, clear: () => { - this.context = {}; + this.context$.next({}); }, - set: (c: Record) => { - this.context = { - ...this.context, + set: (c: ExecutionContext) => { + const newVal = { + ...this.context$.value, ...c - } + }; + if (!isEqual(newVal, this.context$.value)) { + this.context$.next({ + ...this.context$.value, + ...c + }); + } }, getAll: () => { - return { - app: this.context - } + return this.context$.value; } }; } From 6b1839590df8693968852e0dbcb4c5fd0085e67a Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 8 Feb 2022 18:45:28 +0200 Subject: [PATCH 03/57] invert the context parent \ child relationship (cc @mikhail) move more things to top level context --- src/core/public/core_system.ts | 12 +++---- .../execution_context_service.ts | 33 +++++++++++++------ src/core/types/execution_context.ts | 12 +++---- .../public/application/dashboard_app.tsx | 1 + .../hooks/use_dashboard_app_state.ts | 4 --- .../application/listing/dashboard_listing.tsx | 1 + src/plugins/dev_tools/public/application.tsx | 1 + .../application/context/context_app.tsx | 1 + .../application/doc/single_doc_route.tsx | 1 + .../application/main/discover_main_route.tsx | 1 + .../application/main/utils/fetch_chart.ts | 4 --- .../application/main/utils/fetch_documents.ts | 4 --- .../main/utils/fetch_total_hits.ts | 4 --- .../embeddable/saved_search_embeddable.tsx | 14 ++++---- .../embeddable/visualize_embeddable.tsx | 14 ++++---- .../components/visualize_editor.tsx | 1 + .../components/visualize_listing.tsx | 1 + x-pack/plugins/lens/public/app_plugin/app.tsx | 1 + .../lens/public/embeddable/embeddable.tsx | 14 ++++---- .../routes/map_page/map_app/map_app.tsx | 2 +- 20 files changed, 67 insertions(+), 59 deletions(-) diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index 5f67ce224849fb..fa30d0e33b5ba0 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -186,7 +186,6 @@ export class CoreSystem { const i18n = await this.i18n.start(); const fatalErrors = await this.fatalErrors.start(); const theme = this.theme.start(); - const executionContext = this.executionContext.start(); await this.integrations.start({ uiSettings }); const coreUiTargetDomElement = document.createElement('div'); @@ -209,13 +208,10 @@ export class CoreSystem { }); const application = await this.application.start({ http, theme, overlays }); - application.currentAppId$.subscribe(appId => { - executionContext.clear(); - executionContext.set({ - appId - }) - }) - + const executionContext = this.executionContext.start({ + curApp$: application.currentAppId$ + }); + const chrome = await this.chrome.start({ application, docLinks, diff --git a/src/core/public/execution_context/execution_context_service.ts b/src/core/public/execution_context/execution_context_service.ts index 3e297776f7fe76..d1f2762cd002a8 100644 --- a/src/core/public/execution_context/execution_context_service.ts +++ b/src/core/public/execution_context/execution_context_service.ts @@ -7,15 +7,17 @@ */ import { isEqual } from 'lodash'; -import { BehaviorSubject, Observable } from 'rxjs'; +import { BehaviorSubject, Observable, Subscription } from 'rxjs'; +import { distinctUntilChanged } from 'rxjs/operators'; import { CoreService } from '../../types'; export type ExecutionContext = Record; + /** @public */ export interface ExecutionContextSetup { context$: Observable; - set(c$: Record): void; - getAll(): Record; + set(c$: ExecutionContext): void; + getAll(): ExecutionContext; clear(): void; } @@ -25,10 +27,15 @@ export interface ExecutionContextSetup { */ export type ExecutionContextStart = ExecutionContextSetup; +export type StartDeps = { + curApp$: Observable, +}; + /** @internal */ export class ExecutionContextService implements CoreService { - // private context: Record = {}; private context$: BehaviorSubject = new BehaviorSubject({}); + private appId?: string; + private subscription?: Subscription; public setup() { return { @@ -38,14 +45,13 @@ export class ExecutionContextService implements CoreService { const newVal = { + url: window.location.pathname, + name: this.appId, ...this.context$.value, ...c }; if (!isEqual(newVal, this.context$.value)) { - this.context$.next({ - ...this.context$.value, - ...c - }); + this.context$.next(newVal); } }, getAll: () => { @@ -54,10 +60,17 @@ export class ExecutionContextService implements CoreService { + start.clear(); + this.appId = appId; + }); + return start; } public stop() { + this.subscription?.unsubscribe(); } } diff --git a/src/core/types/execution_context.ts b/src/core/types/execution_context.ts index 8a2d657812da8e..cbc043c202b185 100644 --- a/src/core/types/execution_context.ts +++ b/src/core/types/execution_context.ts @@ -16,15 +16,15 @@ export type KibanaExecutionContext = { /** * Kibana application initated an operation. * */ - readonly type: string; // 'visualization' | 'actions' | 'server' | ..; + readonly type?: string; // 'visualization' | 'actions' | 'server' | ..; /** public name of a user-facing feature */ - readonly name: string; // 'TSVB' | 'Lens' | 'action_execution' | ..; + readonly name?: string; // 'TSVB' | 'Lens' | 'action_execution' | ..; /** unique value to identify the source */ - readonly id: string; + readonly id?: string; /** human readable description. For example, a vis title, action name */ - readonly description: string; + readonly description?: string; /** in browser - url to navigate to a current page, on server - endpoint path, for task: task SO url */ readonly url?: string; - /** a context that spawned the current context. */ - parent?: KibanaExecutionContext; + /** an inner context spawned from the current context. */ + child?: KibanaExecutionContext; }; diff --git a/src/plugins/dashboard/public/application/dashboard_app.tsx b/src/plugins/dashboard/public/application/dashboard_app.tsx index 8985cd78d46b61..7f9f85e4aa7e46 100644 --- a/src/plugins/dashboard/public/application/dashboard_app.tsx +++ b/src/plugins/dashboard/public/application/dashboard_app.tsx @@ -49,6 +49,7 @@ export function DashboardApp({ ); core.executionContext.set({ + type: 'application', page: 'app', id: savedDashboardId || 'new', }); diff --git a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts index 8c58eab0ded83c..edbc0e9f20f970 100644 --- a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts +++ b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts @@ -219,11 +219,7 @@ export const useDashboardAppState = ({ savedDashboard, data, executionContext: { - type: 'application', - name: 'dashboard', - id: savedDashboard.id ?? 'unsaved_dashboard', description: savedDashboard.title, - url: history.location.pathname, }, }); if (canceled || !dashboardContainer) { diff --git a/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx b/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx index 99f867de324748..d10a68e2519915 100644 --- a/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx +++ b/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx @@ -68,6 +68,7 @@ export const DashboardListing = ({ ); core.executionContext.set({ + type: 'application', page: 'list', id: '', }) diff --git a/src/plugins/dev_tools/public/application.tsx b/src/plugins/dev_tools/public/application.tsx index a6718b1bd721cc..e20fb91a900c50 100644 --- a/src/plugins/dev_tools/public/application.tsx +++ b/src/plugins/dev_tools/public/application.tsx @@ -66,6 +66,7 @@ function DevToolsWrapper({ }, [activeDevTool, docTitleService, breadcrumbService]); appServices.executionContext.set({ + type: 'application', page: activeDevTool, }) diff --git a/src/plugins/discover/public/application/context/context_app.tsx b/src/plugins/discover/public/application/context/context_app.tsx index 0f4e5209ee8b26..e130bf00b1b135 100644 --- a/src/plugins/discover/public/application/context/context_app.tsx +++ b/src/plugins/discover/public/application/context/context_app.tsx @@ -42,6 +42,7 @@ export const ContextApp = ({ indexPattern, anchorId }: ContextAppProps) => { const useNewFieldsApi = useMemo(() => !uiSettings.get(SEARCH_FIELDS_FROM_SOURCE), [uiSettings]); core.executionContext.set({ + type: 'application', page: 'context', id: indexPattern.id || '', }); diff --git a/src/plugins/discover/public/application/doc/single_doc_route.tsx b/src/plugins/discover/public/application/doc/single_doc_route.tsx index 1926a01fe16a95..f20b37afff1793 100644 --- a/src/plugins/discover/public/application/doc/single_doc_route.tsx +++ b/src/plugins/discover/public/application/doc/single_doc_route.tsx @@ -37,6 +37,7 @@ const SingleDoc = ({ id }: SingleDocRouteProps) => { const breadcrumb = useMainRouteBreadcrumb(); core.executionContext.set({ + type: 'application', page: 'single-doc', id: indexPatternId || '', }); diff --git a/src/plugins/discover/public/application/main/discover_main_route.tsx b/src/plugins/discover/public/application/main/discover_main_route.tsx index 30dff57cae45e3..7356c5998c566c 100644 --- a/src/plugins/discover/public/application/main/discover_main_route.tsx +++ b/src/plugins/discover/public/application/main/discover_main_route.tsx @@ -51,6 +51,7 @@ export function DiscoverMainRoute() { const { id } = useParams(); core.executionContext.set({ + type: 'application', page: 'app', id: id || 'new', }); diff --git a/src/plugins/discover/public/application/main/utils/fetch_chart.ts b/src/plugins/discover/public/application/main/utils/fetch_chart.ts index 00cb9c43caccf2..1ea2594a89d97f 100644 --- a/src/plugins/discover/public/application/main/utils/fetch_chart.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_chart.ts @@ -40,11 +40,7 @@ export function fetchChart( const chartAggConfigs = updateSearchSource(searchSource, interval, data); const executionContext = { - type: 'application', - name: 'discover', description: 'fetch chart data and total hits', - url: window.location.pathname, - id: savedSearch.id ?? '', }; const fetch$ = searchSource diff --git a/src/plugins/discover/public/application/main/utils/fetch_documents.ts b/src/plugins/discover/public/application/main/utils/fetch_documents.ts index dbf972265547ee..8338839e8b0acd 100644 --- a/src/plugins/discover/public/application/main/utils/fetch_documents.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_documents.ts @@ -32,11 +32,7 @@ export const fetchDocuments = ( } const executionContext = { - type: 'application', - name: 'discover', description: 'fetch documents', - url: window.location.pathname, - id: savedSearch.id ?? '', }; const fetch$ = searchSource diff --git a/src/plugins/discover/public/application/main/utils/fetch_total_hits.ts b/src/plugins/discover/public/application/main/utils/fetch_total_hits.ts index af2d55e23cf323..e696570f05cf0b 100644 --- a/src/plugins/discover/public/application/main/utils/fetch_total_hits.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_total_hits.ts @@ -30,11 +30,7 @@ export function fetchTotalHits( } const executionContext = { - type: 'application', - name: 'discover', description: 'fetch total hits', - url: window.location.pathname, - id: savedSearch.id ?? '', }; const fetch$ = searchSource diff --git a/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx b/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx index b950e42fb5f22a..efd1031bddc889 100644 --- a/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx +++ b/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx @@ -169,12 +169,14 @@ export class SavedSearchEmbeddable this.updateOutput({ loading: true, error: undefined }); const executionContext = { - type: this.type, - name: 'discover', - id: this.savedSearch.id!, - description: this.output.title || this.output.defaultTitle || '', - url: this.output.editUrl, - parent: this.input.executionContext, + ...this.input.executionContext!, + child: { + type: this.type, + name: 'discover', + id: this.savedSearch.id!, + description: this.output.title || this.output.defaultTitle || '', + url: this.output.editUrl, + } }; try { diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx index a12195e34a81ec..ed84e3a4e6ddda 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx @@ -399,12 +399,14 @@ export class VisualizeEmbeddable private async updateHandler() { const context = { - type: 'visualization', - name: this.vis.type.title, - id: this.vis.id ?? 'an_unsaved_vis', - description: this.vis.title || this.input.title || this.vis.type.name, - url: this.output.editUrl, - parent: this.parent?.getInput().executionContext, + ...this.parent?.getInput().executionContext, + child: { + type: 'visualization', + name: this.vis.type.title, + id: this.vis.id ?? 'an_unsaved_vis', + description: this.vis.title || this.input.title || this.vis.type.name, + url: this.output.editUrl, + } }; const expressionParams: IExpressionLoaderParams = { diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx index 6f0725c6420b8d..bbdb006231e6c0 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx @@ -35,6 +35,7 @@ export const VisualizeEditor = ({ onAppLeave }: VisualizeAppProps) => { services.executionContext.set({ + type: 'application', page: 'editor', id: visualizationIdFromUrl, }) diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx index 1861be444b384b..c108fc1e24bc68 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx @@ -98,6 +98,7 @@ export const VisualizeListing = () => { ); executionContext.set({ + type: 'application', page: 'list', id: '', }) diff --git a/x-pack/plugins/lens/public/app_plugin/app.tsx b/x-pack/plugins/lens/public/app_plugin/app.tsx index b4efcd9b1289fe..ca1becd2a11bcc 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.tsx @@ -119,6 +119,7 @@ export function App({ }, [setIndicateNoData]); executionContext.set({ + type: 'application', id: savedObjectId || 'new', page: 'editor', }); diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.tsx index ca37580ad682f5..edd35879680463 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable.tsx @@ -414,12 +414,14 @@ export class Embeddable this.renderComplete.dispatchInProgress(); const executionContext = { - type: 'lens', - name: this.savedVis.visualizationType ?? '', - id: this.id, - description: this.savedVis.title || this.input.title || '', - url: this.output.editUrl, - parent: this.input.executionContext, + ...this.input.executionContext, + child: { + type: 'lens', + name: this.savedVis.visualizationType ?? '', + id: this.id, + description: this.savedVis.title || this.input.title || '', + url: this.output.editUrl, + } }; const input = this.getInput(); diff --git a/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx b/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx index 234c8e34d2ac6e..7c85bf23a078cc 100644 --- a/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx +++ b/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx @@ -116,8 +116,8 @@ export class MapApp extends React.Component { componentDidMount() { this._isMounted = true; - getExecutionContext().set({ + type: 'application', page: 'editor', id: this.props.savedMap.getSavedObjectId() || 'new', }) From a0044cd0812578f82023adb2c130f16f600f4543 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 8 Feb 2022 19:33:43 +0200 Subject: [PATCH 04/57] Pass down context to apm on server --- src/core/server/http/http_server.ts | 14 +++++++++++++- src/core/types/execution_context.ts | 5 ++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/core/server/http/http_server.ts b/src/core/server/http/http_server.ts index 4623b09b19e297..eae796fbb514f8 100644 --- a/src/core/server/http/http_server.ts +++ b/src/core/server/http/http_server.ts @@ -46,6 +46,7 @@ import { AuthHeadersStorage, IAuthHeadersStorage } from './auth_headers_storage' import { BasePath } from './base_path_service'; import { getEcsResponseLog } from './logging'; import { HttpServiceSetup, HttpServerInfo, HttpAuth } from './types'; +import apm from 'elastic-apm-node'; /** @internal */ export interface HttpServerSetup { @@ -338,7 +339,18 @@ export class HttpServer { const requestId = getRequestId(request, config.requestId); const parentContext = executionContext?.getParentContextFrom(request.headers); - if (parentContext) executionContext?.set(parentContext); + + if (parentContext) { + const apmContext = { + appId: parentContext.name, + page: parentContext.page, + id: parentContext.id, + }; + + apm.addLabels(apmContext); + executionContext?.set(parentContext); + } + executionContext?.setRequestId(requestId); diff --git a/src/core/types/execution_context.ts b/src/core/types/execution_context.ts index cbc043c202b185..8ab91a760f3334 100644 --- a/src/core/types/execution_context.ts +++ b/src/core/types/execution_context.ts @@ -17,8 +17,10 @@ export type KibanaExecutionContext = { * Kibana application initated an operation. * */ readonly type?: string; // 'visualization' | 'actions' | 'server' | ..; - /** public name of a user-facing feature */ + /** public name of an application or an user-facing feature */ readonly name?: string; // 'TSVB' | 'Lens' | 'action_execution' | ..; + /** a stand alone, logical unit such as an application page or tab */ + readonly page?: string; // /** unique value to identify the source */ readonly id?: string; /** human readable description. For example, a vis title, action name */ @@ -27,4 +29,5 @@ export type KibanaExecutionContext = { readonly url?: string; /** an inner context spawned from the current context. */ child?: KibanaExecutionContext; + }; From ac41e1f78b590860e6f176dc33674c8e6873afd9 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 8 Feb 2022 19:40:19 +0200 Subject: [PATCH 05/57] types --- src/core/public/http/fetch.ts | 2 +- .../data/public/search/search_interceptor/search_interceptor.ts | 2 +- x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/public/http/fetch.ts b/src/core/public/http/fetch.ts index 14566b34de8b4b..4a36ba0fa46352 100644 --- a/src/core/public/http/fetch.ts +++ b/src/core/public/http/fetch.ts @@ -130,7 +130,7 @@ export class Fetch { 'Content-Type': 'application/json', ...options.headers, 'kbn-version': this.params.kibanaVersion, - ...(!isEmpty(context) ? new ExecutionContextContainer(context as any).toHeader() : {}), + ...(!isEmpty(context) ? new ExecutionContextContainer(context).toHeader() : {}), }), }; diff --git a/src/plugins/data/public/search/search_interceptor/search_interceptor.ts b/src/plugins/data/public/search/search_interceptor/search_interceptor.ts index c00f012bdb548a..de641090818753 100644 --- a/src/plugins/data/public/search/search_interceptor/search_interceptor.ts +++ b/src/plugins/data/public/search/search_interceptor/search_interceptor.ts @@ -307,7 +307,7 @@ export class SearchInterceptor { executionContext: { ...executionContext, ...this.deps.executionContext.getAll(), - } as any + } }), }, abortSignal diff --git a/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx b/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx index 21abe54e0d5d45..6701877bf4a765 100644 --- a/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx +++ b/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx @@ -124,6 +124,7 @@ async function deleteMaps(items: object[]) { export function MapsListView() { getExecutionContext().set({ + type: 'application', page: 'list', id: '', }) From c2ed495e4dd80cb7fc7c3d3fa39096c76c05523f Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 8 Feb 2022 20:01:35 +0200 Subject: [PATCH 06/57] eslint --- src/core/public/http/fetch.ts | 4 ++-- .../public/search/search_interceptor/search_interceptor.ts | 2 +- .../plugins/maps/public/routes/list_page/maps_list_view.tsx | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/core/public/http/fetch.ts b/src/core/public/http/fetch.ts index 4a36ba0fa46352..7a7177f3d1af34 100644 --- a/src/core/public/http/fetch.ts +++ b/src/core/public/http/fetch.ts @@ -111,7 +111,7 @@ export class Fetch { const context = { ...this.params.executionContext?.getAll(), ...options.context, - } + }; // Merge and destructure options out that are not applicable to the Fetch API. const { query, @@ -130,7 +130,7 @@ export class Fetch { 'Content-Type': 'application/json', ...options.headers, 'kbn-version': this.params.kibanaVersion, - ...(!isEmpty(context) ? new ExecutionContextContainer(context).toHeader() : {}), + ...(!isEmpty(context) ? new ExecutionContextContainer(context).toHeader() : {}), }), }; diff --git a/src/plugins/data/public/search/search_interceptor/search_interceptor.ts b/src/plugins/data/public/search/search_interceptor/search_interceptor.ts index de641090818753..4d36e3c32b7df3 100644 --- a/src/plugins/data/public/search/search_interceptor/search_interceptor.ts +++ b/src/plugins/data/public/search/search_interceptor/search_interceptor.ts @@ -307,7 +307,7 @@ export class SearchInterceptor { executionContext: { ...executionContext, ...this.deps.executionContext.getAll(), - } + }, }), }, abortSignal diff --git a/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx b/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx index 6701877bf4a765..dab284b0b71e46 100644 --- a/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx +++ b/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx @@ -122,12 +122,11 @@ async function deleteMaps(items: object[]) { } export function MapsListView() { - getExecutionContext().set({ type: 'application', page: 'list', id: '', - }) + }); const isReadOnly = !getMapsCapabilities().save; From 85408b18ba75fecb83990da7ab8950f24fd7ea3f Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 8 Feb 2022 20:13:10 +0200 Subject: [PATCH 07/57] parent <> child --- .../execution_context/execution_context_container.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/server/execution_context/execution_context_container.ts b/src/core/server/execution_context/execution_context_container.ts index a81c409ab3e9e6..0d63789398e003 100644 --- a/src/core/server/execution_context/execution_context_container.ts +++ b/src/core/server/execution_context/execution_context_container.ts @@ -50,14 +50,14 @@ export interface IExecutionContextContainer { } function stringify(ctx: KibanaExecutionContext): string { - const stringifiedCtx = `${ctx.type}:${ctx.name}:${encodeURIComponent(ctx.id)}`; - return ctx.parent ? `${stringify(ctx.parent)};${stringifiedCtx}` : stringifiedCtx; + const stringifiedCtx = `${ctx.type}:${ctx.name}:${encodeURIComponent(ctx.id!)}`; + return ctx.child ? `${stringifiedCtx};${stringify(ctx.child)}` : stringifiedCtx; } export class ExecutionContextContainer implements IExecutionContextContainer { readonly #context: Readonly; - constructor(context: KibanaExecutionContext, parent?: IExecutionContextContainer) { - this.#context = { parent: parent?.toJSON(), ...context }; + constructor(context: KibanaExecutionContext, child?: IExecutionContextContainer) { + this.#context = { child: child?.toJSON(), ...context }; } toString(): string { return enforceMaxLength(stringify(this.#context)); From efb7952f129f40ade5c20d70badcadafe0266c33 Mon Sep 17 00:00:00 2001 From: lizozom Date: Wed, 9 Feb 2022 10:57:52 +0200 Subject: [PATCH 08/57] docs + eslint + jest --- ...-core-public.coresetup.executioncontext.md | 12 +++++++ .../kibana-plugin-core-public.coresetup.md | 1 + ...-core-public.corestart.executioncontext.md | 12 +++++++ .../kibana-plugin-core-public.corestart.md | 1 + ...ugin-core-public.kibanaexecutioncontext.md | 11 ++++--- ...ugin-core-server.kibanaexecutioncontext.md | 11 ++++--- src/core/public/apm_system.ts | 4 +-- src/core/public/core_system.ts | 8 +++-- .../execution_context_service.ts | 18 ++++++----- src/core/public/execution_context/index.ts | 2 +- src/core/public/public.api.md | 31 +++++++++++++++---- .../integration_tests/tracing.test.ts | 8 +++-- src/core/server/server.api.md | 11 ++++--- .../application/listing/dashboard_listing.tsx | 2 +- .../application/context/context_app.tsx | 1 - .../application/doc/single_doc_route.tsx | 1 - .../application/main/discover_main_route.tsx | 1 - .../embeddable/saved_search_embeddable.tsx | 2 +- .../embeddable/visualize_embeddable.tsx | 2 +- .../components/visualize_editor.tsx | 4 +-- .../components/visualize_listing.tsx | 3 +- x-pack/plugins/lens/public/app_plugin/app.tsx | 4 +-- .../lens/public/embeddable/embeddable.tsx | 2 +- .../routes/map_page/map_app/map_app.tsx | 3 +- 24 files changed, 101 insertions(+), 54 deletions(-) create mode 100644 docs/development/core/public/kibana-plugin-core-public.coresetup.executioncontext.md create mode 100644 docs/development/core/public/kibana-plugin-core-public.corestart.executioncontext.md diff --git a/docs/development/core/public/kibana-plugin-core-public.coresetup.executioncontext.md b/docs/development/core/public/kibana-plugin-core-public.coresetup.executioncontext.md new file mode 100644 index 00000000000000..dc1b5e1f336598 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.coresetup.executioncontext.md @@ -0,0 +1,12 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [CoreSetup](./kibana-plugin-core-public.coresetup.md) > [executionContext](./kibana-plugin-core-public.coresetup.executioncontext.md) + +## CoreSetup.executionContext property + + +Signature: + +```typescript +executionContext: ExecutionContextSetup; +``` diff --git a/docs/development/core/public/kibana-plugin-core-public.coresetup.md b/docs/development/core/public/kibana-plugin-core-public.coresetup.md index 9488b8a26b8679..547c2517405726 100644 --- a/docs/development/core/public/kibana-plugin-core-public.coresetup.md +++ b/docs/development/core/public/kibana-plugin-core-public.coresetup.md @@ -17,6 +17,7 @@ export interface CoreSetup + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [CoreStart](./kibana-plugin-core-public.corestart.md) > [executionContext](./kibana-plugin-core-public.corestart.executioncontext.md) + +## CoreStart.executionContext property + + +Signature: + +```typescript +executionContext: ExecutionContextStart; +``` diff --git a/docs/development/core/public/kibana-plugin-core-public.corestart.md b/docs/development/core/public/kibana-plugin-core-public.corestart.md index ae67696e12501b..8c0be567eb3230 100644 --- a/docs/development/core/public/kibana-plugin-core-public.corestart.md +++ b/docs/development/core/public/kibana-plugin-core-public.corestart.md @@ -20,6 +20,7 @@ export interface CoreStart | [chrome](./kibana-plugin-core-public.corestart.chrome.md) | ChromeStart | [ChromeStart](./kibana-plugin-core-public.chromestart.md) | | [deprecations](./kibana-plugin-core-public.corestart.deprecations.md) | DeprecationsServiceStart | [DeprecationsServiceStart](./kibana-plugin-core-public.deprecationsservicestart.md) | | [docLinks](./kibana-plugin-core-public.corestart.doclinks.md) | DocLinksStart | [DocLinksStart](./kibana-plugin-core-public.doclinksstart.md) | +| [executionContext](./kibana-plugin-core-public.corestart.executioncontext.md) | ExecutionContextStart | | | [fatalErrors](./kibana-plugin-core-public.corestart.fatalerrors.md) | FatalErrorsStart | [FatalErrorsStart](./kibana-plugin-core-public.fatalerrorsstart.md) | | [http](./kibana-plugin-core-public.corestart.http.md) | HttpStart | [HttpStart](./kibana-plugin-core-public.httpstart.md) | | [i18n](./kibana-plugin-core-public.corestart.i18n.md) | I18nStart | [I18nStart](./kibana-plugin-core-public.i18nstart.md) | diff --git a/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.md b/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.md index 8b758715a19752..d8f8a77d84b2f4 100644 --- a/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.md +++ b/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.md @@ -10,11 +10,12 @@ Represents a meta-information about a Kibana entity initiating a search request. ```typescript export declare type KibanaExecutionContext = { - readonly type: string; - readonly name: string; - readonly id: string; - readonly description: string; + readonly type?: string; + readonly name?: string; + readonly page?: string; + readonly id?: string; + readonly description?: string; readonly url?: string; - parent?: KibanaExecutionContext; + child?: KibanaExecutionContext; }; ``` diff --git a/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.md b/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.md index db06f9b13f9f60..792af8f693869f 100644 --- a/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.md +++ b/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.md @@ -10,11 +10,12 @@ Represents a meta-information about a Kibana entity initiating a search request. ```typescript export declare type KibanaExecutionContext = { - readonly type: string; - readonly name: string; - readonly id: string; - readonly description: string; + readonly type?: string; + readonly name?: string; + readonly page?: string; + readonly id?: string; + readonly description?: string; readonly url?: string; - parent?: KibanaExecutionContext; + child?: KibanaExecutionContext; }; ``` diff --git a/src/core/public/apm_system.ts b/src/core/public/apm_system.ts index a0ad71a663be93..8a4c0efe3772c7 100644 --- a/src/core/public/apm_system.ts +++ b/src/core/public/apm_system.ts @@ -36,7 +36,7 @@ export class ApmSystem { private pageLoadTransaction?: Transaction; private resourceObserver: CachedResourceObserver; private apm?: ApmBase; - + /** * `apmConfig` would be populated with relevant APM RUM agent * configuration if server is started with elastic.apm.* config. @@ -67,7 +67,7 @@ export class ApmSystem { this.markPageLoadStart(); - start.executionContext.context$.subscribe(c => { + start.executionContext.context$.subscribe((c) => { // We're using labels because we want the context to be indexed // https://www.elastic.co/guide/en/apm/get-started/current/metadata.html this.apm?.addLabels(c); diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index fa30d0e33b5ba0..1aa01c13dd3751 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -142,7 +142,11 @@ export class CoreSystem { this.docLinks.setup(); const executionContext = this.executionContext.setup(); - const http = this.http.setup({ injectedMetadata, fatalErrors: this.fatalErrorsSetup, executionContext }); + const http = this.http.setup({ + injectedMetadata, + fatalErrors: this.fatalErrorsSetup, + executionContext, + }); const uiSettings = this.uiSettings.setup({ http, injectedMetadata }); const notifications = this.notifications.setup({ uiSettings }); const theme = this.theme.setup({ injectedMetadata }); @@ -209,7 +213,7 @@ export class CoreSystem { const application = await this.application.start({ http, theme, overlays }); const executionContext = this.executionContext.start({ - curApp$: application.currentAppId$ + curApp$: application.currentAppId$, }); const chrome = await this.chrome.start({ diff --git a/src/core/public/execution_context/execution_context_service.ts b/src/core/public/execution_context/execution_context_service.ts index d1f2762cd002a8..bbc592050fa392 100644 --- a/src/core/public/execution_context/execution_context_service.ts +++ b/src/core/public/execution_context/execution_context_service.ts @@ -27,12 +27,14 @@ export interface ExecutionContextSetup { */ export type ExecutionContextStart = ExecutionContextSetup; -export type StartDeps = { - curApp$: Observable, -}; +export interface StartDeps { + curApp$: Observable; +} /** @internal */ -export class ExecutionContextService implements CoreService { +export class ExecutionContextService + implements CoreService +{ private context$: BehaviorSubject = new BehaviorSubject({}); private appId?: string; private subscription?: Subscription; @@ -48,22 +50,22 @@ export class ExecutionContextService implements CoreService { return this.context$.value; - } + }, }; } public start({ curApp$ }: StartDeps) { const start = this.setup(); // Clear context on app change - this.subscription = curApp$.pipe(distinctUntilChanged()).subscribe(appId => { + this.subscription = curApp$.pipe(distinctUntilChanged()).subscribe((appId) => { start.clear(); this.appId = appId; }); diff --git a/src/core/public/execution_context/index.ts b/src/core/public/execution_context/index.ts index 32386547907a75..f160b0ecea67b5 100644 --- a/src/core/public/execution_context/index.ts +++ b/src/core/public/execution_context/index.ts @@ -9,4 +9,4 @@ export type { KibanaExecutionContext } from '../../types'; export { ExecutionContextContainer } from './execution_context_container'; export { ExecutionContextService } from './execution_context_service'; -export type { ExecutionContextSetup, ExecutionContextStart } from './execution_context_service'; \ No newline at end of file +export type { ExecutionContextSetup, ExecutionContextStart } from './execution_context_service'; diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index d8cf4706ceb163..bad2d6df14c363 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -7,6 +7,7 @@ /// import { Action } from 'history'; +import { BehaviorSubject } from 'rxjs'; import Boom from '@hapi/boom'; import { ByteSizeValue } from '@kbn/config-schema'; import { ConfigPath } from '@kbn/config'; @@ -398,6 +399,11 @@ export interface CoreContext { export interface CoreSetup { // (undocumented) application: ApplicationSetup; + // Warning: (ae-forgotten-export) The symbol "ExecutionContextSetup" needs to be exported by the entry point index.d.ts + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "ExecutionContextSetup" + // + // (undocumented) + executionContext: ExecutionContextSetup; // (undocumented) fatalErrors: FatalErrorsSetup; // (undocumented) @@ -426,6 +432,11 @@ export interface CoreStart { deprecations: DeprecationsServiceStart; // (undocumented) docLinks: DocLinksStart; + // Warning: (ae-forgotten-export) The symbol "ExecutionContextStart" needs to be exported by the entry point index.d.ts + // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "ExecutionContextStart" + // + // (undocumented) + executionContext: ExecutionContextStart; // (undocumented) fatalErrors: FatalErrorsStart; // (undocumented) @@ -459,6 +470,12 @@ export class CoreSystem { // (undocumented) start(): Promise<{ application: InternalApplicationStart; + executionContext: { + context$: BehaviorSubject; + clear: () => void; + set: (c: ExecutionContext) => void; + getAll: () => ExecutionContext; + }; } | undefined>; // (undocumented) stop(): void; @@ -749,12 +766,13 @@ export interface IUiSettingsClient { // @public export type KibanaExecutionContext = { - readonly type: string; - readonly name: string; - readonly id: string; - readonly description: string; + readonly type?: string; + readonly name?: string; + readonly page?: string; + readonly id?: string; + readonly description?: string; readonly url?: string; - parent?: KibanaExecutionContext; + child?: KibanaExecutionContext; }; // @public @@ -1520,6 +1538,7 @@ export interface UserProvidedValues { // Warnings were encountered during analysis: // -// src/core/public/core_system.ts:173:21 - (ae-forgotten-export) The symbol "InternalApplicationStart" needs to be exported by the entry point index.d.ts +// src/core/public/core_system.ts:179:21 - (ae-forgotten-export) The symbol "InternalApplicationStart" needs to be exported by the entry point index.d.ts +// src/core/public/core_system.ts:182:24 - (ae-forgotten-export) The symbol "ExecutionContext" needs to be exported by the entry point index.d.ts ``` diff --git a/src/core/server/execution_context/integration_tests/tracing.test.ts b/src/core/server/execution_context/integration_tests/tracing.test.ts index 7a54315204a6ba..afcac1129f512d 100644 --- a/src/core/server/execution_context/integration_tests/tracing.test.ts +++ b/src/core/server/execution_context/integration_tests/tracing.test.ts @@ -552,7 +552,7 @@ describe('trace', () => { expect(response.body).toEqual(parentContext); }); - it('set execution context inerits a parent if presented', async () => { + it('set execution context becomes child if parent context is presented', async () => { const { executionContext, http } = await root.setup(); const { createRouter } = http; @@ -575,7 +575,7 @@ describe('trace', () => { await root.start(); const response = await kbnTestServer.request.get(root, '/execution-context').expect(200); - expect(response.body).toEqual({ ...nestedContext, parent: parentContext }); + expect(response.body).toEqual({ child: nestedContext, ...parentContext }); }); it('extends the execution context passed from the client-side', async () => { @@ -604,7 +604,9 @@ describe('trace', () => { .expect(200); const header = response.body['x-opaque-id']; - expect(header).toContain('kibana:test-type:test-name:42;new-type:new-name:41'); + expect(header).toContain( + 'de16b1df-510a-43e2-bf83-b658af27f168;kibana:new-type:new-name:41;test-type:test-name:42' + ); }); }); }); diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index a722e6eb98b02b..6b4f2c4d3a7965 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -1326,12 +1326,13 @@ export interface IUiSettingsClient { // @public export type KibanaExecutionContext = { - readonly type: string; - readonly name: string; - readonly id: string; - readonly description: string; + readonly type?: string; + readonly name?: string; + readonly page?: string; + readonly id?: string; + readonly description?: string; readonly url?: string; - parent?: KibanaExecutionContext; + child?: KibanaExecutionContext; }; // @public diff --git a/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx b/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx index d10a68e2519915..cd5e70efae7b5b 100644 --- a/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx +++ b/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx @@ -71,7 +71,7 @@ export const DashboardListing = ({ type: 'application', page: 'list', id: '', - }) + }); // Set breadcrumbs useEffect useEffect(() => { diff --git a/src/plugins/discover/public/application/context/context_app.tsx b/src/plugins/discover/public/application/context/context_app.tsx index e130bf00b1b135..a33238d6439527 100644 --- a/src/plugins/discover/public/application/context/context_app.tsx +++ b/src/plugins/discover/public/application/context/context_app.tsx @@ -47,7 +47,6 @@ export const ContextApp = ({ indexPattern, anchorId }: ContextAppProps) => { id: indexPattern.id || '', }); - /** * Context app state */ diff --git a/src/plugins/discover/public/application/doc/single_doc_route.tsx b/src/plugins/discover/public/application/doc/single_doc_route.tsx index f20b37afff1793..2ad53051bd5e2b 100644 --- a/src/plugins/discover/public/application/doc/single_doc_route.tsx +++ b/src/plugins/discover/public/application/doc/single_doc_route.tsx @@ -42,7 +42,6 @@ const SingleDoc = ({ id }: SingleDocRouteProps) => { id: indexPatternId || '', }); - useEffect(() => { chrome.setBreadcrumbs([ ...getRootBreadcrumbs(breadcrumb), diff --git a/src/plugins/discover/public/application/main/discover_main_route.tsx b/src/plugins/discover/public/application/main/discover_main_route.tsx index 7356c5998c566c..0585a0fead4d7f 100644 --- a/src/plugins/discover/public/application/main/discover_main_route.tsx +++ b/src/plugins/discover/public/application/main/discover_main_route.tsx @@ -56,7 +56,6 @@ export function DiscoverMainRoute() { id: id || 'new', }); - const navigateToOverview = useCallback(() => { core.application.navigateToApp('kibanaOverview', { path: '#' }); }, [core.application]); diff --git a/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx b/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx index efd1031bddc889..057d5d6901c3aa 100644 --- a/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx +++ b/src/plugins/discover/public/embeddable/saved_search_embeddable.tsx @@ -176,7 +176,7 @@ export class SavedSearchEmbeddable id: this.savedSearch.id!, description: this.output.title || this.output.defaultTitle || '', url: this.output.editUrl, - } + }, }; try { diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx index ed84e3a4e6ddda..6db66171e65441 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx @@ -406,7 +406,7 @@ export class VisualizeEmbeddable id: this.vis.id ?? 'an_unsaved_vis', description: this.vis.title || this.input.title || this.vis.type.name, url: this.output.editUrl, - } + }, }; const expressionParams: IExpressionLoaderParams = { diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx index bbdb006231e6c0..d6e6aef2a99a91 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx @@ -33,13 +33,11 @@ export const VisualizeEditor = ({ onAppLeave }: VisualizeAppProps) => { const [eventEmitter] = useState(new EventEmitter()); const [hasUnsavedChanges, setHasUnsavedChanges] = useState(!visualizationIdFromUrl); - services.executionContext.set({ type: 'application', page: 'editor', id: visualizationIdFromUrl, - }) - + }); const isChromeVisible = useChromeVisibility(services.chrome); const { savedVisInstance, visEditorRef, visEditorController } = useSavedVisInstance( diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx index c108fc1e24bc68..2a1b36610cc225 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx @@ -101,8 +101,7 @@ export const VisualizeListing = () => { type: 'application', page: 'list', id: '', - }) - + }); const noItemsFragment = useMemo(() => getNoItemsMessage(createNewVis), [createNewVis]); const tableColumns = useMemo( diff --git a/x-pack/plugins/lens/public/app_plugin/app.tsx b/x-pack/plugins/lens/public/app_plugin/app.tsx index d3d7161a0805e2..ff31b39df9e655 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.tsx @@ -134,9 +134,7 @@ export function App({ () => Boolean( // Temporarily required until the 'by value' paradigm is default. - dashboardFeatureFlag.allowByValueEmbeddables && - isLinkedToOriginatingApp && - !savedObjectId + dashboardFeatureFlag.allowByValueEmbeddables && isLinkedToOriginatingApp && !savedObjectId ), [dashboardFeatureFlag.allowByValueEmbeddables, isLinkedToOriginatingApp, savedObjectId] ); diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.tsx index edd35879680463..d63be5040c251e 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable.tsx @@ -421,7 +421,7 @@ export class Embeddable id: this.id, description: this.savedVis.title || this.input.title || '', url: this.output.editUrl, - } + }, }; const input = this.getInput(); diff --git a/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx b/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx index 7c85bf23a078cc..a341246f748f3a 100644 --- a/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx +++ b/x-pack/plugins/maps/public/routes/map_page/map_app/map_app.tsx @@ -120,8 +120,7 @@ export class MapApp extends React.Component { type: 'application', page: 'editor', id: this.props.savedMap.getSavedObjectId() || 'new', - }) - + }); this._autoRefreshSubscription = getTimeFilter() .getAutoRefreshFetch$() From 5da627a22b772670692eb5c20ff347ff6b02cd40 Mon Sep 17 00:00:00 2001 From: lizozom Date: Wed, 9 Feb 2022 11:41:34 +0200 Subject: [PATCH 09/57] execution context mock --- .../execution_context_service.mock.ts | 37 +++++++++++++++++++ src/core/public/mocks.ts | 3 ++ 2 files changed, 40 insertions(+) create mode 100644 src/core/public/execution_context/execution_context_service.mock.ts diff --git a/src/core/public/execution_context/execution_context_service.mock.ts b/src/core/public/execution_context/execution_context_service.mock.ts new file mode 100644 index 00000000000000..463df62d4afeb3 --- /dev/null +++ b/src/core/public/execution_context/execution_context_service.mock.ts @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { PublicMethodsOf } from '@kbn/utility-types'; +import { BehaviorSubject } from 'rxjs'; + +import { + ExecutionContextService, + ExecutionContextSetup, +} from './execution_context_service'; + +const createContractMock = (): jest.Mocked => ({ + context$: new BehaviorSubject({}), + clear: jest.fn(), + set: jest.fn(), + getAll: jest.fn(), +}); + + +const createMock = (): jest.Mocked> => ({ + setup: jest.fn().mockReturnValue(createContractMock()), + start: jest.fn().mockReturnValue(createContractMock()), + stop: jest.fn(), +}); + +export const executionContextServiceMock = { + create: createMock, + createSetupContract: createContractMock, + createStartContract: createContractMock, + createInternalSetupContract: createContractMock, + createInternalStartContract: createContractMock, +}; diff --git a/src/core/public/mocks.ts b/src/core/public/mocks.ts index f11839129be64a..6399b55c8a8944 100644 --- a/src/core/public/mocks.ts +++ b/src/core/public/mocks.ts @@ -29,6 +29,7 @@ import { themeServiceMock } from './theme/theme_service.mock'; export { chromeServiceMock } from './chrome/chrome_service.mock'; export { docLinksServiceMock } from './doc_links/doc_links_service.mock'; +import { executionContextServiceMock } from './execution_context/execution_context_service.mock'; export { fatalErrorsServiceMock } from './fatal_errors/fatal_errors_service.mock'; export { httpServiceMock } from './http/http_service.mock'; export { i18nServiceMock } from './i18n/i18n_service.mock'; @@ -54,6 +55,7 @@ function createCoreSetupMock({ const mock = { application: applicationServiceMock.createSetupContract(), docLinks: docLinksServiceMock.createSetupContract(), + executionContext: executionContextServiceMock.createSetupContract(), fatalErrors: fatalErrorsServiceMock.createSetupContract(), getStartServices: jest.fn, any, any]>, []>(() => Promise.resolve([createCoreStartMock({ basePath }), pluginStartDeps, pluginStartContract]) @@ -76,6 +78,7 @@ function createCoreStartMock({ basePath = '' } = {}) { application: applicationServiceMock.createStartContract(), chrome: chromeServiceMock.createStartContract(), docLinks: docLinksServiceMock.createStartContract(), + executionContext: executionContextServiceMock.createStartContract(), http: httpServiceMock.createStartContract({ basePath }), i18n: i18nServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(), From 1c1fce131c6166556b6319c342a7a4044e6261a7 Mon Sep 17 00:00:00 2001 From: lizozom Date: Wed, 9 Feb 2022 11:42:10 +0200 Subject: [PATCH 10/57] eslint --- .../execution_context/execution_context_service.mock.ts | 6 +----- src/core/public/mocks.ts | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/core/public/execution_context/execution_context_service.mock.ts b/src/core/public/execution_context/execution_context_service.mock.ts index 463df62d4afeb3..63444a7d7d0941 100644 --- a/src/core/public/execution_context/execution_context_service.mock.ts +++ b/src/core/public/execution_context/execution_context_service.mock.ts @@ -9,10 +9,7 @@ import { PublicMethodsOf } from '@kbn/utility-types'; import { BehaviorSubject } from 'rxjs'; -import { - ExecutionContextService, - ExecutionContextSetup, -} from './execution_context_service'; +import { ExecutionContextService, ExecutionContextSetup } from './execution_context_service'; const createContractMock = (): jest.Mocked => ({ context$: new BehaviorSubject({}), @@ -21,7 +18,6 @@ const createContractMock = (): jest.Mocked => ({ getAll: jest.fn(), }); - const createMock = (): jest.Mocked> => ({ setup: jest.fn().mockReturnValue(createContractMock()), start: jest.fn().mockReturnValue(createContractMock()), diff --git a/src/core/public/mocks.ts b/src/core/public/mocks.ts index 6399b55c8a8944..930d78c52e27e0 100644 --- a/src/core/public/mocks.ts +++ b/src/core/public/mocks.ts @@ -46,7 +46,7 @@ export { themeServiceMock } from './theme/theme_service.mock'; function createCoreSetupMock({ basePath = '', pluginStartDeps = {}, - pluginStartContract, + pluginStartContract, }: { basePath?: string; pluginStartDeps?: object; From 52000523d73c1fa3021a14c95967f9057424a043 Mon Sep 17 00:00:00 2001 From: lizozom Date: Wed, 9 Feb 2022 13:31:44 +0200 Subject: [PATCH 11/57] jest --- src/core/public/mocks.ts | 2 +- src/core/public/public.api.md | 4 ++-- src/core/server/http/http_server.ts | 3 +-- src/core/types/execution_context.ts | 1 - src/plugins/dev_tools/public/application.tsx | 10 ++++++++-- .../public/application/context/context_app.test.tsx | 3 +++ .../public/application/main/utils/fetch_chart.test.ts | 6 +----- .../application/main/utils/fetch_total_hits.test.ts | 4 ---- 8 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/core/public/mocks.ts b/src/core/public/mocks.ts index 930d78c52e27e0..6399b55c8a8944 100644 --- a/src/core/public/mocks.ts +++ b/src/core/public/mocks.ts @@ -46,7 +46,7 @@ export { themeServiceMock } from './theme/theme_service.mock'; function createCoreSetupMock({ basePath = '', pluginStartDeps = {}, - pluginStartContract, + pluginStartContract, }: { basePath?: string; pluginStartDeps?: object; diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index bad2d6df14c363..403ce8445d95ee 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -1538,7 +1538,7 @@ export interface UserProvidedValues { // Warnings were encountered during analysis: // -// src/core/public/core_system.ts:179:21 - (ae-forgotten-export) The symbol "InternalApplicationStart" needs to be exported by the entry point index.d.ts -// src/core/public/core_system.ts:182:24 - (ae-forgotten-export) The symbol "ExecutionContext" needs to be exported by the entry point index.d.ts +// src/core/public/core_system.ts:183:21 - (ae-forgotten-export) The symbol "InternalApplicationStart" needs to be exported by the entry point index.d.ts +// src/core/public/core_system.ts:186:24 - (ae-forgotten-export) The symbol "ExecutionContext" needs to be exported by the entry point index.d.ts ``` diff --git a/src/core/server/http/http_server.ts b/src/core/server/http/http_server.ts index eae796fbb514f8..0f59f66d4fa835 100644 --- a/src/core/server/http/http_server.ts +++ b/src/core/server/http/http_server.ts @@ -21,6 +21,7 @@ import agent from 'elastic-apm-node'; import type { Duration } from 'moment'; import { Observable } from 'rxjs'; import { take } from 'rxjs/operators'; +import apm from 'elastic-apm-node'; import { Logger, LoggerFactory } from '../logging'; import { HttpConfig } from './http_config'; import type { InternalExecutionContextSetup } from '../execution_context'; @@ -46,7 +47,6 @@ import { AuthHeadersStorage, IAuthHeadersStorage } from './auth_headers_storage' import { BasePath } from './base_path_service'; import { getEcsResponseLog } from './logging'; import { HttpServiceSetup, HttpServerInfo, HttpAuth } from './types'; -import apm from 'elastic-apm-node'; /** @internal */ export interface HttpServerSetup { @@ -350,7 +350,6 @@ export class HttpServer { apm.addLabels(apmContext); executionContext?.set(parentContext); } - executionContext?.setRequestId(requestId); diff --git a/src/core/types/execution_context.ts b/src/core/types/execution_context.ts index 8ab91a760f3334..0ff8f4a6a19397 100644 --- a/src/core/types/execution_context.ts +++ b/src/core/types/execution_context.ts @@ -29,5 +29,4 @@ export type KibanaExecutionContext = { readonly url?: string; /** an inner context spawned from the current context. */ child?: KibanaExecutionContext; - }; diff --git a/src/plugins/dev_tools/public/application.tsx b/src/plugins/dev_tools/public/application.tsx index e20fb91a900c50..beebe9334738e3 100644 --- a/src/plugins/dev_tools/public/application.tsx +++ b/src/plugins/dev_tools/public/application.tsx @@ -15,7 +15,13 @@ import { I18nProvider } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { euiThemeVars } from '@kbn/ui-theme'; -import { ApplicationStart, ChromeStart, ScopedHistory, CoreTheme, CoreStart } from 'src/core/public'; +import { + ApplicationStart, + ChromeStart, + ScopedHistory, + CoreTheme, + CoreStart, +} from 'src/core/public'; import { KibanaThemeProvider } from '../../kibana_react/public'; import type { DocTitleService, BreadcrumbService } from './services'; @@ -68,7 +74,7 @@ function DevToolsWrapper({ appServices.executionContext.set({ type: 'application', page: activeDevTool, - }) + }); return (
diff --git a/src/plugins/discover/public/application/context/context_app.test.tsx b/src/plugins/discover/public/application/context/context_app.test.tsx index c9089a6c1111c1..cf1e7a98e01a37 100644 --- a/src/plugins/discover/public/application/context/context_app.test.tsx +++ b/src/plugins/discover/public/application/context/context_app.test.tsx @@ -46,6 +46,9 @@ describe('ContextApp test', () => { toastNotifications: { addDanger: () => {} }, navigation: mockNavigationPlugin, core: { + executionContext: { + set: jest.fn(), + }, notifications: { toasts: [] }, theme: { theme$: themeServiceMock.createStartContract().theme$ }, }, diff --git a/src/plugins/discover/public/application/main/utils/fetch_chart.test.ts b/src/plugins/discover/public/application/main/utils/fetch_chart.test.ts index 4c68eff54f579f..b1f736fa4b2242 100644 --- a/src/plugins/discover/public/application/main/utils/fetch_chart.test.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_chart.test.ts @@ -117,7 +117,7 @@ describe('test fetchCharts', () => { }); }); - test('fetch$ is called with execution context containing savedSearch id', async () => { + test('fetch$ is called with request specific execution context', async () => { const fetch$Mock = jest.fn().mockReturnValue(of(requestResult)); savedSearchMockWithTimeField.searchSource.fetch$ = fetch$Mock; @@ -126,10 +126,6 @@ describe('test fetchCharts', () => { expect(fetch$Mock.mock.calls[0][0].executionContext).toMatchInlineSnapshot(` Object { "description": "fetch chart data and total hits", - "id": "the-saved-search-id-with-timefield", - "name": "discover", - "type": "application", - "url": "/", } `); }); diff --git a/src/plugins/discover/public/application/main/utils/fetch_total_hits.test.ts b/src/plugins/discover/public/application/main/utils/fetch_total_hits.test.ts index ba7b6a765aa2e9..a5485c1a2e2e90 100644 --- a/src/plugins/discover/public/application/main/utils/fetch_total_hits.test.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_total_hits.test.ts @@ -51,10 +51,6 @@ describe('test fetchTotalHits', () => { expect(fetch$Mock.mock.calls[0][0].executionContext).toMatchInlineSnapshot(` Object { "description": "fetch total hits", - "id": "the-saved-search-id", - "name": "discover", - "type": "application", - "url": "/", } `); }); From 4c151dd686b785e1c4c86cfc06a291bb221d5bc6 Mon Sep 17 00:00:00 2001 From: lizozom Date: Wed, 9 Feb 2022 15:48:28 +0200 Subject: [PATCH 12/57] jest --- src/core/public/apm_system.test.ts | 4 ++ .../execution_context_container.test.ts | 60 +++++++++---------- src/core/public/http/fetch.test.ts | 2 + src/core/public/http/http_service.test.ts | 10 +++- .../public/plugins/plugins_service.test.ts | 3 + src/core/test_helpers/http_test_setup.ts | 5 +- 6 files changed, 50 insertions(+), 34 deletions(-) diff --git a/src/core/public/apm_system.test.ts b/src/core/public/apm_system.test.ts index 842d5de7e5afcb..9414a00456fd00 100644 --- a/src/core/public/apm_system.test.ts +++ b/src/core/public/apm_system.test.ts @@ -13,6 +13,7 @@ import type { Transaction } from '@elastic/apm-rum'; import { ApmSystem } from './apm_system'; import { Subject } from 'rxjs'; import { InternalApplicationStart } from './application/types'; +import { ExecutionContextStart } from './execution_context'; const initMock = init as jest.Mocked; const apmMock = apm as DeeplyMockedKeys; @@ -96,6 +97,7 @@ describe('ApmSystem', () => { application: { currentAppId$, } as any as InternalApplicationStart, + executionContext: {} as any as ExecutionContextStart, }); expect(mark).toHaveBeenCalledWith('apm-start'); @@ -118,6 +120,7 @@ describe('ApmSystem', () => { application: { currentAppId$, } as any as InternalApplicationStart, + executionContext: {} as any as ExecutionContextStart, }); currentAppId$.next('myapp'); @@ -145,6 +148,7 @@ describe('ApmSystem', () => { application: { currentAppId$, } as any as InternalApplicationStart, + executionContext: {} as any as ExecutionContextStart, }); currentAppId$.next('myapp'); diff --git a/src/core/public/execution_context/execution_context_container.test.ts b/src/core/public/execution_context/execution_context_container.test.ts index 5e4e34d102e5b5..189dc35e9d7303 100644 --- a/src/core/public/execution_context/execution_context_container.test.ts +++ b/src/core/public/execution_context/execution_context_container.test.ts @@ -29,26 +29,26 @@ describe('KibanaExecutionContext', () => { `); }); - it('includes a parent context to string representation', () => { - const parentContext: KibanaExecutionContext = { - type: 'parent-type', - name: 'parent-name', - id: '41', - description: 'parent-descripton', + it('includes a child context to string representation', () => { + const childContext: KibanaExecutionContext = { + type: 'child-test-type', + name: 'child-test-name', + id: '42', + description: 'child-test-descripton', }; const context: KibanaExecutionContext = { - type: 'test-type', - name: 'test-name', - id: '42', - description: 'test-descripton', - parent: parentContext, + type: 'type', + name: 'name', + id: '41', + description: 'descripton', + child: childContext, }; const value = new ExecutionContextContainer(context).toHeader(); expect(value).toMatchInlineSnapshot(` Object { - "x-kbn-context": "%7B%22type%22%3A%22test-type%22%2C%22name%22%3A%22test-name%22%2C%22id%22%3A%2242%22%2C%22description%22%3A%22test-descripton%22%2C%22parent%22%3A%7B%22type%22%3A%22parent-type%22%2C%22name%22%3A%22parent-name%22%2C%22id%22%3A%2241%22%2C%22description%22%3A%22parent-descripton%22%7D%7D", + "x-kbn-context": "%7B%22type%22%3A%22type%22%2C%22name%22%3A%22name%22%2C%22id%22%3A%2241%22%2C%22description%22%3A%22descripton%22%2C%22child%22%3A%7B%22type%22%3A%22child-test-type%22%2C%22name%22%3A%22child-test-name%22%2C%22id%22%3A%2242%22%2C%22description%22%3A%22child-test-descripton%22%7D%7D", } `); }); @@ -103,35 +103,35 @@ describe('KibanaExecutionContext', () => { }); it('returns JSON representation when the parent context if provided', () => { - const parentAContext: KibanaExecutionContext = { - type: 'parent-a-type', - name: 'parent-a-name', - id: '40', - description: 'parent-a-descripton', + const childBContext: KibanaExecutionContext = { + type: 'child-b-type', + name: 'child-b-name', + id: '42', + description: 'child-b-descripton', }; - const parentBContext: KibanaExecutionContext = { - type: 'parent-b-type', - name: 'parent-b-name', + const childAContext: KibanaExecutionContext = { + type: 'child-a-type', + name: 'child-a-name', id: '41', - description: 'parent-b-descripton', - parent: parentAContext, + description: 'child-a-descripton', + child: childBContext, }; const context: KibanaExecutionContext = { - type: 'test-type', - name: 'test-name', - id: '42', - description: 'test-descripton', - parent: parentBContext, + type: 'type', + name: 'name', + id: '40', + description: 'descripton', + child: childAContext, }; const value = new ExecutionContextContainer(context).toJSON(); expect(value).toEqual({ ...context, - parent: { - ...parentBContext, - parent: parentAContext, + child: { + ...childAContext, + child: childBContext, }, }); }); diff --git a/src/core/public/http/fetch.test.ts b/src/core/public/http/fetch.test.ts index e897d69057e029..ad8364b5649683 100644 --- a/src/core/public/http/fetch.test.ts +++ b/src/core/public/http/fetch.test.ts @@ -15,6 +15,7 @@ import { first } from 'rxjs/operators'; import { Fetch } from './fetch'; import { BasePath } from './base_path'; import { HttpResponse, HttpFetchOptionsWithPath } from './types'; +import { executionContextServiceMock } from '../execution_context/execution_context_service.mock'; function delay(duration: number) { return new Promise((r) => setTimeout(r, duration)); @@ -26,6 +27,7 @@ describe('Fetch', () => { const fetchInstance = new Fetch({ basePath: new BasePath(BASE_PATH), kibanaVersion: 'VERSION', + executionContext: executionContextServiceMock.createSetupContract(), }); afterEach(() => { fetchMock.restore(); diff --git a/src/core/public/http/http_service.test.ts b/src/core/public/http/http_service.test.ts index 2b41991904d974..698fa876433d41 100644 --- a/src/core/public/http/http_service.test.ts +++ b/src/core/public/http/http_service.test.ts @@ -14,6 +14,7 @@ import { fatalErrorsServiceMock } from '../fatal_errors/fatal_errors_service.moc import { injectedMetadataServiceMock } from '../injected_metadata/injected_metadata_service.mock'; import { HttpService } from './http_service'; import { Observable } from 'rxjs'; +import { executionContextServiceMock } from '../execution_context/execution_context_service.mock'; describe('interceptors', () => { afterEach(() => fetchMock.restore()); @@ -22,9 +23,10 @@ describe('interceptors', () => { fetchMock.get('*', {}); const injectedMetadata = injectedMetadataServiceMock.createSetupContract(); const fatalErrors = fatalErrorsServiceMock.createSetupContract(); + const executionContext = executionContextServiceMock.createSetupContract(); const httpService = new HttpService(); - const setup = httpService.setup({ fatalErrors, injectedMetadata }); + const setup = httpService.setup({ fatalErrors, injectedMetadata, executionContext }); const setupInterceptor = jest.fn(); setup.intercept({ request: setupInterceptor }); @@ -47,7 +49,8 @@ describe('#setup()', () => { const injectedMetadata = injectedMetadataServiceMock.createSetupContract(); const fatalErrors = fatalErrorsServiceMock.createSetupContract(); const httpService = new HttpService(); - httpService.setup({ fatalErrors, injectedMetadata }); + const executionContext = executionContextServiceMock.createSetupContract(); + httpService.setup({ fatalErrors, injectedMetadata, executionContext }); const loadingServiceSetup = loadingServiceMock.setup.mock.results[0].value; // We don't verify that this Observable comes from Fetch#getLoadingCount$() to avoid complex mocking expect(loadingServiceSetup.addLoadingCountSource).toHaveBeenCalledWith(expect.any(Observable)); @@ -59,7 +62,8 @@ describe('#stop()', () => { const injectedMetadata = injectedMetadataServiceMock.createSetupContract(); const fatalErrors = fatalErrorsServiceMock.createSetupContract(); const httpService = new HttpService(); - httpService.setup({ fatalErrors, injectedMetadata }); + const executionContext = executionContextServiceMock.createSetupContract(); + httpService.setup({ fatalErrors, injectedMetadata, executionContext }); httpService.start(); httpService.stop(); expect(loadingServiceMock.stop).toHaveBeenCalled(); diff --git a/src/core/public/plugins/plugins_service.test.ts b/src/core/public/plugins/plugins_service.test.ts index c4e3b7990ba32b..40976424b7edd7 100644 --- a/src/core/public/plugins/plugins_service.test.ts +++ b/src/core/public/plugins/plugins_service.test.ts @@ -36,6 +36,7 @@ import { docLinksServiceMock } from '../doc_links/doc_links_service.mock'; import { savedObjectsServiceMock } from '../saved_objects/saved_objects_service.mock'; import { deprecationsServiceMock } from '../deprecations/deprecations_service.mock'; import { themeServiceMock } from '../theme/theme_service.mock'; +import { executionContextServiceMock } from '../execution_context/execution_context_service.mock'; export let mockPluginInitializers: Map; @@ -85,6 +86,7 @@ describe('PluginsService', () => { mockSetupDeps = { application: applicationServiceMock.createInternalSetupContract(), fatalErrors: fatalErrorsServiceMock.createSetupContract(), + executionContext: executionContextServiceMock.createSetupContract(), http: httpServiceMock.createSetupContract(), injectedMetadata: injectedMetadataServiceMock.createStartContract(), notifications: notificationServiceMock.createSetupContract(), @@ -100,6 +102,7 @@ describe('PluginsService', () => { mockStartDeps = { application: applicationServiceMock.createInternalStartContract(), docLinks: docLinksServiceMock.createStartContract(), + executionContext: executionContextServiceMock.createStartContract(), http: httpServiceMock.createStartContract(), chrome: chromeServiceMock.createStartContract(), i18n: i18nServiceMock.createStartContract(), diff --git a/src/core/test_helpers/http_test_setup.ts b/src/core/test_helpers/http_test_setup.ts index 468034dffceb9b..9d757668546b54 100644 --- a/src/core/test_helpers/http_test_setup.ts +++ b/src/core/test_helpers/http_test_setup.ts @@ -9,6 +9,8 @@ import { HttpService } from '../public/http'; import { fatalErrorsServiceMock } from '../public/fatal_errors/fatal_errors_service.mock'; import { injectedMetadataServiceMock } from '../public/injected_metadata/injected_metadata_service.mock'; +import { ExecutionContextService } from '../public/execution_context'; +import { executionContextServiceMock } from '../public/execution_context/execution_context_service.mock'; export type SetupTap = ( injectedMetadata: ReturnType, @@ -28,7 +30,8 @@ export function setup(tap: SetupTap = defaultTap) { tap(injectedMetadata, fatalErrors); const httpService = new HttpService(); - const http = httpService.setup({ fatalErrors, injectedMetadata }); + const executionContext = executionContextServiceMock.createSetupContract(); + const http = httpService.setup({ fatalErrors, injectedMetadata, executionContext }); return { httpService, injectedMetadata, fatalErrors, http }; } From b64e5e25f68c544fb4ef2408089844ad2ee28aba Mon Sep 17 00:00:00 2001 From: lizozom Date: Wed, 9 Feb 2022 16:09:21 +0200 Subject: [PATCH 13/57] server jest --- .../execution_context_container.test.ts | 59 ++++++++++--------- src/core/test_helpers/http_test_setup.ts | 1 - 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/core/server/execution_context/execution_context_container.test.ts b/src/core/server/execution_context/execution_context_container.test.ts index c332913b2f4015..dd38a336cef9e0 100644 --- a/src/core/server/execution_context/execution_context_container.test.ts +++ b/src/core/server/execution_context/execution_context_container.test.ts @@ -18,9 +18,9 @@ describe('KibanaExecutionContext', () => { describe('constructor', () => { it('allows context to define parent explicitly', () => { const parentContext: KibanaExecutionContext = { - type: 'parent-type', - name: 'parent-name', - id: '44', + type: 'test-type', + name: 'test-name', + id: '42', description: 'parent-descripton', }; const parentContainer = new ExecutionContextContainer(parentContext); @@ -30,11 +30,11 @@ describe('KibanaExecutionContext', () => { name: 'test-name', id: '42', description: 'test-descripton', - parent: { - type: 'custom-parent-type', - name: 'custom-parent-name', + child: { + type: 'custom-child-type', + name: 'custom-child-name', id: '41', - description: 'custom-parent-descripton', + description: 'custom-child-descripton', }, }; @@ -56,24 +56,25 @@ describe('KibanaExecutionContext', () => { expect(value).toBe('test-type:test-name:42'); }); - it('includes a parent context to string representation', () => { - const parentContext: KibanaExecutionContext = { - type: 'parent-type', - name: 'parent-name', + it('includes a child context to string representation', () => { + const context: KibanaExecutionContext = { + type: 'type', + name: 'name', id: '41', - description: 'parent-descripton', + description: 'descripton', }; - const parentContainer = new ExecutionContextContainer(parentContext); - const context: KibanaExecutionContext = { - type: 'test-type', - name: 'test-name', + const childContext: KibanaExecutionContext = { + type: 'child-test-type', + name: 'child-test-name', id: '42', description: 'test-descripton', }; - const value = new ExecutionContextContainer(context, parentContainer).toString(); - expect(value).toBe('parent-type:parent-name:41;test-type:test-name:42'); + const childContainer = new ExecutionContextContainer(childContext); + + const value = new ExecutionContextContainer(context, childContainer).toString(); + expect(value).toBe('type:name:41;child-test-type:child-test-name:42'); }); it('returns an escaped string representation of provided execution contextStringified', () => { @@ -115,24 +116,24 @@ describe('KibanaExecutionContext', () => { expect(value).toEqual(context); }); - it('returns a context object with registered parent object', () => { - const parentContext: KibanaExecutionContext = { - type: 'parent-type', - name: 'parent-name', + it('returns a context object with registered context object', () => { + const context: KibanaExecutionContext = { + type: 'type', + name: 'name', id: '41', - description: 'parent-descripton', + description: 'descripton', }; - const parentContainer = new ExecutionContextContainer(parentContext); - const context: KibanaExecutionContext = { - type: 'test-type', - name: 'test-name', + const childContext: KibanaExecutionContext = { + type: 'child-test-type', + name: 'child-test-name', id: '42', description: 'test-descripton', }; + const childContainer = new ExecutionContextContainer(childContext); - const value = new ExecutionContextContainer(context, parentContainer).toJSON(); - expect(value).toEqual({ ...context, parent: parentContext }); + const value = new ExecutionContextContainer(context, childContainer).toJSON(); + expect(value).toEqual({ child: childContext, ...context }); }); }); }); diff --git a/src/core/test_helpers/http_test_setup.ts b/src/core/test_helpers/http_test_setup.ts index 9d757668546b54..67b340898aab47 100644 --- a/src/core/test_helpers/http_test_setup.ts +++ b/src/core/test_helpers/http_test_setup.ts @@ -9,7 +9,6 @@ import { HttpService } from '../public/http'; import { fatalErrorsServiceMock } from '../public/fatal_errors/fatal_errors_service.mock'; import { injectedMetadataServiceMock } from '../public/injected_metadata/injected_metadata_service.mock'; -import { ExecutionContextService } from '../public/execution_context'; import { executionContextServiceMock } from '../public/execution_context/execution_context_service.mock'; export type SetupTap = ( From f1fc110dd3c77a62e444a5310b4cfcd8c80c2105 Mon Sep 17 00:00:00 2001 From: lizozom Date: Wed, 9 Feb 2022 16:27:42 +0200 Subject: [PATCH 14/57] check --- .../public/search/search_interceptor/search_interceptor.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts b/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts index 968dd870489fe0..6bedc313d6b6f1 100644 --- a/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts +++ b/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts @@ -119,6 +119,7 @@ describe('SearchInterceptor', () => { }), uiSettings: mockCoreSetup.uiSettings, http: mockCoreSetup.http, + executionContext: mockCoreSetup.executionContext, session: sessionService, theme: themeServiceMock.createSetupContract(), }); From f413c380e63e3a6e31efc978073fcc90fb47c94f Mon Sep 17 00:00:00 2001 From: lizozom Date: Wed, 9 Feb 2022 16:56:33 +0200 Subject: [PATCH 15/57] jest --- .../index_lifecycle_management/__jest__/policy_table.test.tsx | 2 ++ x-pack/plugins/lens/public/mocks/services_mock.tsx | 1 + 2 files changed, 3 insertions(+) diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/policy_table.test.tsx b/x-pack/plugins/index_lifecycle_management/__jest__/policy_table.test.tsx index 3a1c2dd36812f6..89f7d4795429a5 100644 --- a/x-pack/plugins/index_lifecycle_management/__jest__/policy_table.test.tsx +++ b/x-pack/plugins/index_lifecycle_management/__jest__/policy_table.test.tsx @@ -25,11 +25,13 @@ import { init as initHttp } from '../public/application/services/http'; import { init as initUiMetric } from '../public/application/services/ui_metric'; import { KibanaContextProvider } from '../public/shared_imports'; import { PolicyListContextProvider } from '../public/application/sections/policy_list/policy_list_context'; +import { executionContextServiceMock } from 'src/core/public/execution_context/execution_context_service.mock'; initHttp( new HttpService().setup({ injectedMetadata: injectedMetadataServiceMock.createSetupContract(), fatalErrors: fatalErrorsServiceMock.createSetupContract(), + executionContext: executionContextServiceMock.createSetupContract(), }) ); initUiMetric(usageCollectionPluginMock.createSetupContract()); diff --git a/x-pack/plugins/lens/public/mocks/services_mock.tsx b/x-pack/plugins/lens/public/mocks/services_mock.tsx index 9fa6d61370a17c..6681811744da42 100644 --- a/x-pack/plugins/lens/public/mocks/services_mock.tsx +++ b/x-pack/plugins/lens/public/mocks/services_mock.tsx @@ -112,6 +112,7 @@ export function makeDefaultServices( chrome: core.chrome, overlays: core.overlays, uiSettings: core.uiSettings, + executionContext: core.executionContext, navigation: navigationStartMock, notifications: core.notifications, attributeService: makeAttributeService(), From 97350de901fd68c21ca616fed8a882ec144ef7f2 Mon Sep 17 00:00:00 2001 From: lizozom Date: Wed, 9 Feb 2022 18:11:09 +0200 Subject: [PATCH 16/57] storybook --- .../.storybook/context/execution_context.ts | 21 +++++++++++++++++++ .../fleet/.storybook/context/index.tsx | 2 ++ 2 files changed, 23 insertions(+) create mode 100644 x-pack/plugins/fleet/.storybook/context/execution_context.ts diff --git a/x-pack/plugins/fleet/.storybook/context/execution_context.ts b/x-pack/plugins/fleet/.storybook/context/execution_context.ts new file mode 100644 index 00000000000000..03c2dd0cee3466 --- /dev/null +++ b/x-pack/plugins/fleet/.storybook/context/execution_context.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import type { CoreStart } from 'kibana/public'; +import { of } from 'rxjs'; + +export const getExecutionContext = () => { + const exec: CoreStart['executionContext'] = { + context$: of({}), + getAll: () => { + return {}; + }, + clear: () => {}, + set: (context: Record) => {}, + }; + + return exec; +}; diff --git a/x-pack/plugins/fleet/.storybook/context/index.tsx b/x-pack/plugins/fleet/.storybook/context/index.tsx index eb19a1145ba751..fbcbd4fd3a0811 100644 --- a/x-pack/plugins/fleet/.storybook/context/index.tsx +++ b/x-pack/plugins/fleet/.storybook/context/index.tsx @@ -31,6 +31,7 @@ import { stubbedStartServices } from './stubs'; import { getDocLinks } from './doc_links'; import { getCloud } from './cloud'; import { getShare } from './share'; +import { getExecutionContext } from './execution_context'; // TODO: clintandrewhall - this is not ideal, or complete. The root context of Fleet applications // requires full start contracts of its dependencies. As a result, we have to mock all of those contracts @@ -52,6 +53,7 @@ export const StorybookContext: React.FC<{ storyContext?: StoryContext }> = ({ () => ({ ...stubbedStartServices, application: getApplication(), + executionContext: getExecutionContext(), chrome: getChrome(), cloud: { ...getCloud({ isCloudEnabled }), From cf33228878c591566bea7bc8cdcc94f3ffd75b29 Mon Sep 17 00:00:00 2001 From: lizozom Date: Wed, 9 Feb 2022 19:24:09 +0200 Subject: [PATCH 17/57] jest --- .../tests/browser.ts | 198 +++++++++--------- 1 file changed, 99 insertions(+), 99 deletions(-) diff --git a/x-pack/test/functional_execution_context/tests/browser.ts b/x-pack/test/functional_execution_context/tests/browser.ts index f6e46a6bc22801..b402c31fddc526 100644 --- a/x-pack/test/functional_execution_context/tests/browser.ts +++ b/x-pack/test/functional_execution_context/tests/browser.ts @@ -98,18 +98,18 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { description: 'execution context propagates to Kibana logs', predicate: (record) => isExecutionContextLog(record?.message, { - parent: { - type: 'application', - name: 'dashboard', - id: '7adfa750-4c81-11e8-b3d7-01146121b73d', - description: '[Flights] Global Flight Dashboard', - url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d', + type: 'application', + name: 'dashboard', + id: '7adfa750-4c81-11e8-b3d7-01146121b73d', + description: '[Flights] Global Flight Dashboard', + url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d', + child: { + type: 'lens', + name: 'lnsXY', + id: '086ac2e9-dd16-4b45-92b8-1e43ff7e3f65', + description: '[Flights] Flight count', + url: '/app/lens#/edit_by_value', }, - type: 'lens', - name: 'lnsXY', - id: '086ac2e9-dd16-4b45-92b8-1e43ff7e3f65', - description: '[Flights] Flight count', - url: '/app/lens#/edit_by_value', }), retry, }); @@ -131,18 +131,18 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { description: 'execution context propagates to Kibana logs', predicate: (record) => isExecutionContextLog(record?.message, { - parent: { - type: 'application', - name: 'dashboard', - id: '7adfa750-4c81-11e8-b3d7-01146121b73d', - description: '[Flights] Global Flight Dashboard', - url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d', + type: 'application', + name: 'dashboard', + id: '7adfa750-4c81-11e8-b3d7-01146121b73d', + description: '[Flights] Global Flight Dashboard', + url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d', + child: { + type: 'lens', + name: 'lnsMetric', + id: '2e33ade5-96e5-40b4-b460-493e5d4fa834', + description: '', + url: '/app/lens#/edit_by_value', }, - type: 'lens', - name: 'lnsMetric', - id: '2e33ade5-96e5-40b4-b460-493e5d4fa834', - description: '', - url: '/app/lens#/edit_by_value', }), retry, }); @@ -164,18 +164,18 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { description: 'execution context propagates to Kibana logs', predicate: (record) => isExecutionContextLog(record?.message, { - parent: { - type: 'application', - name: 'dashboard', - id: '7adfa750-4c81-11e8-b3d7-01146121b73d', - description: '[Flights] Global Flight Dashboard', - url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d', + type: 'application', + name: 'dashboard', + id: '7adfa750-4c81-11e8-b3d7-01146121b73d', + description: '[Flights] Global Flight Dashboard', + url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d', + child: { + type: 'lens', + name: 'lnsDatatable', + id: 'fb86b32f-fb7a-45cf-9511-f366fef51bbd', + description: 'Cities by delay, cancellation', + url: '/app/lens#/edit_by_value', }, - type: 'lens', - name: 'lnsDatatable', - id: 'fb86b32f-fb7a-45cf-9511-f366fef51bbd', - description: 'Cities by delay, cancellation', - url: '/app/lens#/edit_by_value', }), retry, }); @@ -196,18 +196,18 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { description: 'execution context propagates to Kibana logs', predicate: (record) => isExecutionContextLog(record?.message, { - parent: { - type: 'application', - name: 'dashboard', - id: '7adfa750-4c81-11e8-b3d7-01146121b73d', - description: '[Flights] Global Flight Dashboard', - url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d', + type: 'application', + name: 'dashboard', + id: '7adfa750-4c81-11e8-b3d7-01146121b73d', + description: '[Flights] Global Flight Dashboard', + url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d', + child: { + type: 'lens', + name: 'lnsPie', + id: '5d53db36-2d5a-4adc-af7b-cec4c1a294e0', + description: '[Flights] Delay Type', + url: '/app/lens#/edit_by_value', }, - type: 'lens', - name: 'lnsPie', - id: '5d53db36-2d5a-4adc-af7b-cec4c1a294e0', - description: '[Flights] Delay Type', - url: '/app/lens#/edit_by_value', }), retry, }); @@ -229,18 +229,18 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { description: 'execution context propagates to Kibana logs', predicate: (record) => isExecutionContextLog(record?.message, { - parent: { - type: 'application', - name: 'dashboard', - id: '7adfa750-4c81-11e8-b3d7-01146121b73d', - description: '[Flights] Global Flight Dashboard', - url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d', + type: 'application', + name: 'dashboard', + id: '7adfa750-4c81-11e8-b3d7-01146121b73d', + description: '[Flights] Global Flight Dashboard', + url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d', + child: { + type: 'search', + name: 'discover', + id: '571aaf70-4c88-11e8-b3d7-01146121b73d', + description: '[Flights] Flight Log', + url: '/app/discover#/view/571aaf70-4c88-11e8-b3d7-01146121b73d', }, - type: 'search', - name: 'discover', - id: '571aaf70-4c88-11e8-b3d7-01146121b73d', - description: '[Flights] Flight Log', - url: '/app/discover#/view/571aaf70-4c88-11e8-b3d7-01146121b73d', }), retry, }); @@ -262,18 +262,18 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { description: 'execution context propagates to Kibana logs', predicate: (record) => isExecutionContextLog(record?.message, { - parent: { - type: 'application', - name: 'dashboard', - id: '7adfa750-4c81-11e8-b3d7-01146121b73d', - description: '[Flights] Global Flight Dashboard', - url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d', + type: 'application', + name: 'dashboard', + id: '7adfa750-4c81-11e8-b3d7-01146121b73d', + description: '[Flights] Global Flight Dashboard', + url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d', + child: { + type: 'visualization', + name: 'TSVB', + id: 'bcb63b50-4c89-11e8-b3d7-01146121b73d', + description: '[Flights] Delays & Cancellations', + url: '/app/visualize#/edit/bcb63b50-4c89-11e8-b3d7-01146121b73d', }, - type: 'visualization', - name: 'TSVB', - id: 'bcb63b50-4c89-11e8-b3d7-01146121b73d', - description: '[Flights] Delays & Cancellations', - url: '/app/visualize#/edit/bcb63b50-4c89-11e8-b3d7-01146121b73d', }), retry, }); @@ -295,18 +295,18 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { description: 'execution context propagates to Kibana logs', predicate: (record) => isExecutionContextLog(record?.message, { - parent: { - type: 'application', - name: 'dashboard', - id: '7adfa750-4c81-11e8-b3d7-01146121b73d', - description: '[Flights] Global Flight Dashboard', - url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d', + type: 'application', + name: 'dashboard', + id: '7adfa750-4c81-11e8-b3d7-01146121b73d', + description: '[Flights] Global Flight Dashboard', + url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d', + child: { + type: 'visualization', + name: 'Vega', + id: 'ed78a660-53a0-11e8-acbd-0be0ad9d822b', + description: '[Flights] Airport Connections (Hover Over Airport)', + url: '/app/visualize#/edit/ed78a660-53a0-11e8-acbd-0be0ad9d822b', }, - type: 'visualization', - name: 'Vega', - id: 'ed78a660-53a0-11e8-acbd-0be0ad9d822b', - description: '[Flights] Airport Connections (Hover Over Airport)', - url: '/app/visualize#/edit/ed78a660-53a0-11e8-acbd-0be0ad9d822b', }), retry, }); @@ -328,18 +328,18 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { description: 'execution context propagates to Kibana logs', predicate: (record) => isExecutionContextLog(record?.message, { - parent: { - type: 'application', - name: 'dashboard', - id: '7adfa750-4c81-11e8-b3d7-01146121b73d', - description: '[Flights] Global Flight Dashboard', - url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d', + type: 'application', + name: 'dashboard', + id: '7adfa750-4c81-11e8-b3d7-01146121b73d', + description: '[Flights] Global Flight Dashboard', + url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d', + child: { + type: 'visualization', + name: 'Tag cloud', + id: '293b5a30-4c8f-11e8-b3d7-01146121b73d', + description: '[Flights] Destination Weather', + url: '/app/visualize#/edit/293b5a30-4c8f-11e8-b3d7-01146121b73d', }, - type: 'visualization', - name: 'Tag cloud', - id: '293b5a30-4c8f-11e8-b3d7-01146121b73d', - description: '[Flights] Destination Weather', - url: '/app/visualize#/edit/293b5a30-4c8f-11e8-b3d7-01146121b73d', }), retry, }); @@ -361,18 +361,18 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { description: 'execution context propagates to Kibana logs', predicate: (record) => isExecutionContextLog(record?.message, { - parent: { - type: 'application', - name: 'dashboard', - id: '7adfa750-4c81-11e8-b3d7-01146121b73d', - description: '[Flights] Global Flight Dashboard', - url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d', + type: 'application', + name: 'dashboard', + id: '7adfa750-4c81-11e8-b3d7-01146121b73d', + description: '[Flights] Global Flight Dashboard', + url: '/view/7adfa750-4c81-11e8-b3d7-01146121b73d', + child: { + type: 'visualization', + name: 'Vertical bar', + id: '9886b410-4c8b-11e8-b3d7-01146121b73d', + description: '[Flights] Delay Buckets', + url: '/app/visualize#/edit/9886b410-4c8b-11e8-b3d7-01146121b73d', }, - type: 'visualization', - name: 'Vertical bar', - id: '9886b410-4c8b-11e8-b3d7-01146121b73d', - description: '[Flights] Delay Buckets', - url: '/app/visualize#/edit/9886b410-4c8b-11e8-b3d7-01146121b73d', }), retry, }); From 666441c2ca1f824f9a53b42703c7c539203f9ef7 Mon Sep 17 00:00:00 2001 From: lizozom Date: Thu, 10 Feb 2022 18:27:16 +0200 Subject: [PATCH 18/57] report the current space --- .../execution_context_service.ts | 50 +++++++++++++++---- src/core/server/http/http_server.ts | 1 + src/core/tsconfig.json | 3 ++ src/core/types/execution_context.ts | 2 + .../main/utils/fetch_documents.test.ts | 4 -- .../tests/server.ts | 20 ++++---- 6 files changed, 56 insertions(+), 24 deletions(-) diff --git a/src/core/public/execution_context/execution_context_service.ts b/src/core/public/execution_context/execution_context_service.ts index bbc592050fa392..1c399fc9c1d075 100644 --- a/src/core/public/execution_context/execution_context_service.ts +++ b/src/core/public/execution_context/execution_context_service.ts @@ -9,7 +9,9 @@ import { isEqual } from 'lodash'; import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { distinctUntilChanged } from 'rxjs/operators'; +import { CoreSetup } from '..'; import { CoreService } from '../../types'; +import type { SpacesPluginStart } from '../../../../x-pack/plugins/spaces/public'; export type ExecutionContext = Record; @@ -27,20 +29,41 @@ export interface ExecutionContextSetup { */ export type ExecutionContextStart = ExecutionContextSetup; +export interface SetupDeps { + core: CoreSetup; +} + export interface StartDeps { curApp$: Observable; } +export interface ExecutionContextStartDependencies { + spaces?: SpacesPluginStart; +} + /** @internal */ export class ExecutionContextService implements CoreService { private context$: BehaviorSubject = new BehaviorSubject({}); private appId?: string; - private subscription?: Subscription; + private space: string = ''; + private subscription: Subscription = new Subscription(); + private contract?: ExecutionContextSetup; - public setup() { - return { + public setup({ core }: SetupDeps) { + // Track space changes + core.getStartServices().then(([_, pluginDeps]) => { + const spacesApi = pluginDeps.spaces; + if (spacesApi) { + this.subscription.add( + spacesApi.getActiveSpace$().subscribe((space) => { + this.space = space.id; + }) + ); + } + }); + this.contract = { context$: this.context$, clear: () => { this.context$.next({}); @@ -49,6 +72,7 @@ export class ExecutionContextService const newVal = { url: window.location.pathname, name: this.appId, + space: this.space, ...this.context$.value, ...c, }; @@ -60,19 +84,25 @@ export class ExecutionContextService return this.context$.value; }, }; + + return this.contract; } public start({ curApp$ }: StartDeps) { - const start = this.setup(); - // Clear context on app change - this.subscription = curApp$.pipe(distinctUntilChanged()).subscribe((appId) => { - start.clear(); - this.appId = appId; - }); + const start = this.contract!; + + // Track app id changes and clear context on app change + this.subscription.add( + curApp$.pipe(distinctUntilChanged()).subscribe((appId) => { + start.clear(); + this.appId = appId; + }) + ); + return start; } public stop() { - this.subscription?.unsubscribe(); + this.subscription.unsubscribe(); } } diff --git a/src/core/server/http/http_server.ts b/src/core/server/http/http_server.ts index 0f59f66d4fa835..f72aea4fce532d 100644 --- a/src/core/server/http/http_server.ts +++ b/src/core/server/http/http_server.ts @@ -342,6 +342,7 @@ export class HttpServer { if (parentContext) { const apmContext = { + space: parentContext.space, appId: parentContext.name, page: parentContext.page, id: parentContext.id, diff --git a/src/core/tsconfig.json b/src/core/tsconfig.json index 9c042577cfe214..793e9a367cc738 100644 --- a/src/core/tsconfig.json +++ b/src/core/tsconfig.json @@ -14,5 +14,8 @@ "test_helpers/**/*", "utils/**/*", "index.ts" + ], + "references": [ + { "path": "../../x-pack/plugins/spaces/tsconfig.json" } ] } diff --git a/src/core/types/execution_context.ts b/src/core/types/execution_context.ts index 0ff8f4a6a19397..0f27a7183becc3 100644 --- a/src/core/types/execution_context.ts +++ b/src/core/types/execution_context.ts @@ -21,6 +21,8 @@ export type KibanaExecutionContext = { readonly name?: string; // 'TSVB' | 'Lens' | 'action_execution' | ..; /** a stand alone, logical unit such as an application page or tab */ readonly page?: string; // + /** space identifier */ + readonly space?: string; /** unique value to identify the source */ readonly id?: string; /** human readable description. For example, a vis title, action name */ diff --git a/src/plugins/discover/public/application/main/utils/fetch_documents.test.ts b/src/plugins/discover/public/application/main/utils/fetch_documents.test.ts index 000d3282c38b3c..1e73f5de3a3f66 100644 --- a/src/plugins/discover/public/application/main/utils/fetch_documents.test.ts +++ b/src/plugins/discover/public/application/main/utils/fetch_documents.test.ts @@ -57,10 +57,6 @@ describe('test fetchDocuments', () => { expect(fetch$Mock.mock.calls[0][0].executionContext).toMatchInlineSnapshot(` Object { "description": "fetch total hits", - "id": "the-saved-search-id", - "name": "discover", - "type": "application", - "url": "/", } `); }); diff --git a/x-pack/test/functional_execution_context/tests/server.ts b/x-pack/test/functional_execution_context/tests/server.ts index 8997c83f4f6965..fd10118a03627b 100644 --- a/x-pack/test/functional_execution_context/tests/server.ts +++ b/x-pack/test/functional_execution_context/tests/server.ts @@ -93,17 +93,17 @@ export default function ({ getService }: FtrProviderContext) { description: 'execution context propagates to Kibana logs', predicate: (record) => isExecutionContextLog(record?.message, { - parent: { - type: 'task manager', - name: 'run alerting:test.executionContext', - // @ts-expect-error. it accepts strings only - id: ANY, - description: 'run task', + type: 'task manager', + name: 'run alerting:test.executionContext', + // @ts-expect-error. it accepts strings only + id: ANY, + description: 'run task', + child: { + type: 'alert', + name: 'execute test.executionContext', + id: alertId, + description: 'execute [test.executionContext] with name [abc] in [default] namespace', }, - type: 'alert', - name: 'execute test.executionContext', - id: alertId, - description: 'execute [test.executionContext] with name [abc] in [default] namespace', }), retry, }); From d8c69c4807e1300da1e4e5f3c95ec05ce712d37b Mon Sep 17 00:00:00 2001 From: lizozom Date: Thu, 10 Feb 2022 18:57:23 +0200 Subject: [PATCH 19/57] fix server side context container --- .../execution_context_container.test.ts | 10 ++-- .../execution_context_container.ts | 4 +- .../execution_context_service.test.ts | 48 ++++++++++--------- .../integration_tests/tracing.test.ts | 4 +- 4 files changed, 34 insertions(+), 32 deletions(-) diff --git a/src/core/server/execution_context/execution_context_container.test.ts b/src/core/server/execution_context/execution_context_container.test.ts index dd38a336cef9e0..37df99465152ba 100644 --- a/src/core/server/execution_context/execution_context_container.test.ts +++ b/src/core/server/execution_context/execution_context_container.test.ts @@ -16,7 +16,7 @@ import { describe('KibanaExecutionContext', () => { describe('constructor', () => { - it('allows context to define parent explicitly', () => { + it.skip('allows context to define parent explicitly', () => { const parentContext: KibanaExecutionContext = { type: 'test-type', name: 'test-name', @@ -71,9 +71,9 @@ describe('KibanaExecutionContext', () => { description: 'test-descripton', }; - const childContainer = new ExecutionContextContainer(childContext); + const contextContainer = new ExecutionContextContainer(context); - const value = new ExecutionContextContainer(context, childContainer).toString(); + const value = new ExecutionContextContainer(childContext, contextContainer).toString(); expect(value).toBe('type:name:41;child-test-type:child-test-name:42'); }); @@ -130,9 +130,9 @@ describe('KibanaExecutionContext', () => { id: '42', description: 'test-descripton', }; - const childContainer = new ExecutionContextContainer(childContext); + const contextContainer = new ExecutionContextContainer(context); - const value = new ExecutionContextContainer(context, childContainer).toJSON(); + const value = new ExecutionContextContainer(childContext, contextContainer).toJSON(); expect(value).toEqual({ child: childContext, ...context }); }); }); diff --git a/src/core/server/execution_context/execution_context_container.ts b/src/core/server/execution_context/execution_context_container.ts index 0d63789398e003..066248a26ad7b9 100644 --- a/src/core/server/execution_context/execution_context_container.ts +++ b/src/core/server/execution_context/execution_context_container.ts @@ -56,8 +56,8 @@ function stringify(ctx: KibanaExecutionContext): string { export class ExecutionContextContainer implements IExecutionContextContainer { readonly #context: Readonly; - constructor(context: KibanaExecutionContext, child?: IExecutionContextContainer) { - this.#context = { child: child?.toJSON(), ...context }; + constructor(context: KibanaExecutionContext, parent?: IExecutionContextContainer) { + this.#context = parent ? { ...parent.toJSON(), child: context } : context; } toString(): string { return enforceMaxLength(stringify(this.#context)); diff --git a/src/core/server/execution_context/execution_context_service.test.ts b/src/core/server/execution_context/execution_context_service.test.ts index 9bb76ad78c49a6..6e01dd5a1a2129 100644 --- a/src/core/server/execution_context/execution_context_service.test.ts +++ b/src/core/server/execution_context/execution_context_service.test.ts @@ -32,6 +32,7 @@ describe('ExecutionContextService', () => { type: 'type-a', name: 'name-a', id: 'id-a', + space: 'a', description: 'description-a', }); await delay(500); @@ -43,6 +44,7 @@ describe('ExecutionContextService', () => { type: 'type-b', name: 'name-b', id: 'id-b', + space: 'a', description: 'description-b', }); await delay(100); @@ -57,17 +59,19 @@ describe('ExecutionContextService', () => { { type: 'type-a', name: 'name-a', + space: 'a', id: 'id-a', description: 'description-a', - parent: undefined, + child: undefined, }, { type: 'type-b', name: 'name-b', + space: 'a', id: 'id-b', description: 'description-b', - parent: undefined, + child: undefined, }, ]); }); @@ -271,17 +275,17 @@ describe('ExecutionContextService', () => { ); expect(result?.toJSON()).toEqual({ - type: 'type-b', - name: 'name-b', - id: 'id-b', - description: 'description-b', - parent: { - type: 'type-a', - name: 'name-a', - id: 'id-a', - description: 'description-a', - parent: undefined, + child: { + child: undefined, + type: 'type-b', + name: 'name-b', + id: 'id-b', + description: 'description-b', }, + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', }); }); @@ -306,16 +310,16 @@ describe('ExecutionContextService', () => { ); expect(result?.toJSON()).toEqual({ - type: 'type-b', - name: 'name-b', - id: 'id-b', - description: 'description-b', - parent: { - type: 'type-a', - name: 'name-a', - id: 'id-a', - description: 'description-a', - parent: undefined, + type: 'type-a', + name: 'name-a', + id: 'id-a', + description: 'description-a', + child: { + child: undefined, + type: 'type-b', + name: 'name-b', + id: 'id-b', + description: 'description-b', }, }); }); diff --git a/src/core/server/execution_context/integration_tests/tracing.test.ts b/src/core/server/execution_context/integration_tests/tracing.test.ts index afcac1129f512d..d329b2216f2ecd 100644 --- a/src/core/server/execution_context/integration_tests/tracing.test.ts +++ b/src/core/server/execution_context/integration_tests/tracing.test.ts @@ -604,9 +604,7 @@ describe('trace', () => { .expect(200); const header = response.body['x-opaque-id']; - expect(header).toContain( - 'de16b1df-510a-43e2-bf83-b658af27f168;kibana:new-type:new-name:41;test-type:test-name:42' - ); + expect(header).toContain('kibana:test-type:test-name:42;new-type:new-name:41'); }); }); }); From abcccdc5133043b0e1064a9c13b3a9740faf36a1 Mon Sep 17 00:00:00 2001 From: lizozom Date: Thu, 10 Feb 2022 19:40:06 +0200 Subject: [PATCH 20/57] Remove spaces for now --- src/core/public/apm_system.ts | 8 +++++- .../execution_context_service.ts | 25 +------------------ src/core/server/http/http_server.ts | 1 - src/core/tsconfig.json | 3 --- 4 files changed, 8 insertions(+), 29 deletions(-) diff --git a/src/core/public/apm_system.ts b/src/core/public/apm_system.ts index 8a4c0efe3772c7..198c7f3c25a761 100644 --- a/src/core/public/apm_system.ts +++ b/src/core/public/apm_system.ts @@ -70,7 +70,13 @@ export class ApmSystem { start.executionContext.context$.subscribe((c) => { // We're using labels because we want the context to be indexed // https://www.elastic.co/guide/en/apm/get-started/current/metadata.html - this.apm?.addLabels(c); + const apmContext = { + appId: c.name, + page: c.page, + id: c.id, + }; + + this.apm?.addLabels(apmContext); }); // TODO: Start a new transaction every page change instead of every app change. diff --git a/src/core/public/execution_context/execution_context_service.ts b/src/core/public/execution_context/execution_context_service.ts index 1c399fc9c1d075..b796d21152b774 100644 --- a/src/core/public/execution_context/execution_context_service.ts +++ b/src/core/public/execution_context/execution_context_service.ts @@ -9,9 +9,7 @@ import { isEqual } from 'lodash'; import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { distinctUntilChanged } from 'rxjs/operators'; -import { CoreSetup } from '..'; import { CoreService } from '../../types'; -import type { SpacesPluginStart } from '../../../../x-pack/plugins/spaces/public'; export type ExecutionContext = Record; @@ -29,40 +27,20 @@ export interface ExecutionContextSetup { */ export type ExecutionContextStart = ExecutionContextSetup; -export interface SetupDeps { - core: CoreSetup; -} - export interface StartDeps { curApp$: Observable; } -export interface ExecutionContextStartDependencies { - spaces?: SpacesPluginStart; -} - /** @internal */ export class ExecutionContextService implements CoreService { private context$: BehaviorSubject = new BehaviorSubject({}); private appId?: string; - private space: string = ''; private subscription: Subscription = new Subscription(); private contract?: ExecutionContextSetup; - public setup({ core }: SetupDeps) { - // Track space changes - core.getStartServices().then(([_, pluginDeps]) => { - const spacesApi = pluginDeps.spaces; - if (spacesApi) { - this.subscription.add( - spacesApi.getActiveSpace$().subscribe((space) => { - this.space = space.id; - }) - ); - } - }); + public setup() { this.contract = { context$: this.context$, clear: () => { @@ -72,7 +50,6 @@ export class ExecutionContextService const newVal = { url: window.location.pathname, name: this.appId, - space: this.space, ...this.context$.value, ...c, }; diff --git a/src/core/server/http/http_server.ts b/src/core/server/http/http_server.ts index f72aea4fce532d..0f59f66d4fa835 100644 --- a/src/core/server/http/http_server.ts +++ b/src/core/server/http/http_server.ts @@ -342,7 +342,6 @@ export class HttpServer { if (parentContext) { const apmContext = { - space: parentContext.space, appId: parentContext.name, page: parentContext.page, id: parentContext.id, diff --git a/src/core/tsconfig.json b/src/core/tsconfig.json index 793e9a367cc738..9c042577cfe214 100644 --- a/src/core/tsconfig.json +++ b/src/core/tsconfig.json @@ -14,8 +14,5 @@ "test_helpers/**/*", "utils/**/*", "index.ts" - ], - "references": [ - { "path": "../../x-pack/plugins/spaces/tsconfig.json" } ] } From 824cb2a428ec405f0b1d5d2da1c259d74c53f6cd Mon Sep 17 00:00:00 2001 From: lizozom Date: Thu, 10 Feb 2022 20:33:21 +0200 Subject: [PATCH 21/57] docssss --- ...kibana-plugin-core-public.kibanaexecutioncontext.md | 1 + ...kibana-plugin-core-server.kibanaexecutioncontext.md | 1 + src/core/public/public.api.md | 10 ++-------- src/core/server/server.api.md | 1 + 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.md b/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.md index d8f8a77d84b2f4..8967cc68815b83 100644 --- a/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.md +++ b/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.md @@ -13,6 +13,7 @@ export declare type KibanaExecutionContext = { readonly type?: string; readonly name?: string; readonly page?: string; + readonly space?: string; readonly id?: string; readonly description?: string; readonly url?: string; diff --git a/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.md b/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.md index 792af8f693869f..e16baa43732081 100644 --- a/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.md +++ b/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.md @@ -13,6 +13,7 @@ export declare type KibanaExecutionContext = { readonly type?: string; readonly name?: string; readonly page?: string; + readonly space?: string; readonly id?: string; readonly description?: string; readonly url?: string; diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 403ce8445d95ee..4ffe165d724f1d 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -7,7 +7,6 @@ /// import { Action } from 'history'; -import { BehaviorSubject } from 'rxjs'; import Boom from '@hapi/boom'; import { ByteSizeValue } from '@kbn/config-schema'; import { ConfigPath } from '@kbn/config'; @@ -470,12 +469,7 @@ export class CoreSystem { // (undocumented) start(): Promise<{ application: InternalApplicationStart; - executionContext: { - context$: BehaviorSubject; - clear: () => void; - set: (c: ExecutionContext) => void; - getAll: () => ExecutionContext; - }; + executionContext: ExecutionContextSetup; } | undefined>; // (undocumented) stop(): void; @@ -769,6 +763,7 @@ export type KibanaExecutionContext = { readonly type?: string; readonly name?: string; readonly page?: string; + readonly space?: string; readonly id?: string; readonly description?: string; readonly url?: string; @@ -1539,6 +1534,5 @@ export interface UserProvidedValues { // Warnings were encountered during analysis: // // src/core/public/core_system.ts:183:21 - (ae-forgotten-export) The symbol "InternalApplicationStart" needs to be exported by the entry point index.d.ts -// src/core/public/core_system.ts:186:24 - (ae-forgotten-export) The symbol "ExecutionContext" needs to be exported by the entry point index.d.ts ``` diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 6b4f2c4d3a7965..b17a7ec276be9e 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -1329,6 +1329,7 @@ export type KibanaExecutionContext = { readonly type?: string; readonly name?: string; readonly page?: string; + readonly space?: string; readonly id?: string; readonly description?: string; readonly url?: string; From 89d70645723236276950f78fc6967e629e247141 Mon Sep 17 00:00:00 2001 From: lizozom Date: Thu, 10 Feb 2022 21:40:09 +0200 Subject: [PATCH 22/57] jest --- .../public/search/search_interceptor/search_interceptor.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts b/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts index 6bedc313d6b6f1..569c1670c9d5ba 100644 --- a/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts +++ b/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts @@ -544,7 +544,7 @@ describe('SearchInterceptor', () => { .catch(() => {}); expect(fetchMock.mock.calls[0][0]).toEqual( expect.objectContaining({ - options: { sessionId, isStored: true, isRestore: true, strategy: 'ese' }, + options: { executionContext: {}, sessionId, isStored: true, isRestore: true, strategy: 'ese' }, }) ); From e32f86990b0f4b2dd0697edebfe8be80b7d45951 Mon Sep 17 00:00:00 2001 From: lizozom Date: Thu, 10 Feb 2022 23:13:05 +0200 Subject: [PATCH 23/57] lint --- .../search/search_interceptor/search_interceptor.test.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts b/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts index 569c1670c9d5ba..95fd6f15af3c35 100644 --- a/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts +++ b/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts @@ -544,7 +544,13 @@ describe('SearchInterceptor', () => { .catch(() => {}); expect(fetchMock.mock.calls[0][0]).toEqual( expect.objectContaining({ - options: { executionContext: {}, sessionId, isStored: true, isRestore: true, strategy: 'ese' }, + options: { + executionContext: {}, + sessionId, + isStored: true, + isRestore: true, + strategy: 'ese', + }, }) ); From 756e7f5ea0dbc5f5e603461e0cdc63910f2493f9 Mon Sep 17 00:00:00 2001 From: lizozom Date: Fri, 11 Feb 2022 13:47:14 +0200 Subject: [PATCH 24/57] test --- src/core/public/apm_system.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/public/apm_system.test.ts b/src/core/public/apm_system.test.ts index 9414a00456fd00..0a3a1dee63e57e 100644 --- a/src/core/public/apm_system.test.ts +++ b/src/core/public/apm_system.test.ts @@ -13,7 +13,7 @@ import type { Transaction } from '@elastic/apm-rum'; import { ApmSystem } from './apm_system'; import { Subject } from 'rxjs'; import { InternalApplicationStart } from './application/types'; -import { ExecutionContextStart } from './execution_context'; +import { executionContextServiceMock } from './execution_context/execution_context_service.mock'; const initMock = init as jest.Mocked; const apmMock = apm as DeeplyMockedKeys; @@ -97,7 +97,7 @@ describe('ApmSystem', () => { application: { currentAppId$, } as any as InternalApplicationStart, - executionContext: {} as any as ExecutionContextStart, + executionContext: executionContextServiceMock.createInternalStartContract(), }); expect(mark).toHaveBeenCalledWith('apm-start'); @@ -120,7 +120,7 @@ describe('ApmSystem', () => { application: { currentAppId$, } as any as InternalApplicationStart, - executionContext: {} as any as ExecutionContextStart, + executionContext: executionContextServiceMock.createInternalStartContract(), }); currentAppId$.next('myapp'); @@ -148,7 +148,7 @@ describe('ApmSystem', () => { application: { currentAppId$, } as any as InternalApplicationStart, - executionContext: {} as any as ExecutionContextStart, + executionContext: executionContextServiceMock.createInternalStartContract(), }); currentAppId$.next('myapp'); From 8efe9ad33a07a6d02b5bd92787296d87fe95e225 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 15 Feb 2022 14:26:56 +0200 Subject: [PATCH 25/57] docs --- .../user/troubleshooting/trace-query.asciidoc | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/user/troubleshooting/trace-query.asciidoc b/docs/user/troubleshooting/trace-query.asciidoc index f037b26ade630f..24f8cc487bf755 100644 --- a/docs/user/troubleshooting/trace-query.asciidoc +++ b/docs/user/troubleshooting/trace-query.asciidoc @@ -29,16 +29,16 @@ Now, you can see the request to {es} has been initiated by the `[Logs] Unique Vi [source,text] ---- [DEBUG][execution_context] stored the execution context: { - "parent": { - "type": "application", - "name": "dashboard", - "id": "edf84fe0-e1a0-11e7-b6d5-4dc382ef7f5b", - "description": "[Logs] Web Traffic","url":"/view/edf84fe0-e1a0-11e7-b6d5-4dc382ef7f5b" + "type": "application", + "name": "dashboard", + "id": "edf84fe0-e1a0-11e7-b6d5-4dc382ef7f5b", + "description": "[Logs] Web Traffic","url":"/view/edf84fe0-e1a0-11e7-b6d5-4dc382ef7f5b" + "child": { + "type": "visualization", + "name": "Vega", + "id": "cb099a20-ea66-11eb-9425-113343a037e3", + "description": "[Logs] Unique Visitor Heatmap", + "url": "/app/visualize#/edit/cb099a20-ea66-11eb-9425-113343a037e3" }, - "type": "visualization", - "name": "Vega", - "id": "cb099a20-ea66-11eb-9425-113343a037e3", - "description": "[Logs] Unique Visitor Heatmap", - "url": "/app/visualize#/edit/cb099a20-ea66-11eb-9425-113343a037e3" } ---- From c9fa18da0e56e28069880ba7d9fb1785557ba074 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 15 Feb 2022 16:40:12 +0200 Subject: [PATCH 26/57] revert file --- .../execution_context/execution_context_service.test.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/core/server/execution_context/execution_context_service.test.ts b/src/core/server/execution_context/execution_context_service.test.ts index 6e01dd5a1a2129..c39769133cede1 100644 --- a/src/core/server/execution_context/execution_context_service.test.ts +++ b/src/core/server/execution_context/execution_context_service.test.ts @@ -32,7 +32,6 @@ describe('ExecutionContextService', () => { type: 'type-a', name: 'name-a', id: 'id-a', - space: 'a', description: 'description-a', }); await delay(500); @@ -44,7 +43,6 @@ describe('ExecutionContextService', () => { type: 'type-b', name: 'name-b', id: 'id-b', - space: 'a', description: 'description-b', }); await delay(100); @@ -59,7 +57,6 @@ describe('ExecutionContextService', () => { { type: 'type-a', name: 'name-a', - space: 'a', id: 'id-a', description: 'description-a', child: undefined, @@ -68,7 +65,6 @@ describe('ExecutionContextService', () => { { type: 'type-b', name: 'name-b', - space: 'a', id: 'id-b', description: 'description-b', child: undefined, From 4b29f042856bfd777f1b9a63b7c443bfd3efa9e0 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 15 Feb 2022 16:44:26 +0200 Subject: [PATCH 27/57] doc --- src/core/types/execution_context.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/types/execution_context.ts b/src/core/types/execution_context.ts index 1d99e249318b47..91d6375b0522c1 100644 --- a/src/core/types/execution_context.ts +++ b/src/core/types/execution_context.ts @@ -17,7 +17,7 @@ export type KibanaExecutionContext = { * Kibana application initated an operation. * */ readonly type: string; // 'visualization' | 'actions' | 'server' | ..; - /** public name of an application or an user-facing feature */ + /** public name of an application or a user-facing feature */ readonly name: string; // 'TSVB' | 'Lens' | 'action_execution' | ..; /** a stand alone, logical unit such as an application page or tab */ readonly page?: string; // From b600cc00af900d8a8070841267c1a71b28df580c Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 15 Feb 2022 17:13:57 +0200 Subject: [PATCH 28/57] all context params are optional --- .../kibana-plugin-core-public.kibanaexecutioncontext.md | 6 +++--- .../kibana-plugin-core-server.kibanaexecutioncontext.md | 6 +++--- src/core/public/public.api.md | 6 +++--- .../server/execution_context/execution_context_container.ts | 2 +- src/core/server/server.api.md | 6 +++--- src/core/types/execution_context.ts | 6 +++--- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.md b/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.md index 9189882d39521a..d8f8a77d84b2f4 100644 --- a/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.md +++ b/docs/development/core/public/kibana-plugin-core-public.kibanaexecutioncontext.md @@ -10,10 +10,10 @@ Represents a meta-information about a Kibana entity initiating a search request. ```typescript export declare type KibanaExecutionContext = { - readonly type: string; - readonly name: string; + readonly type?: string; + readonly name?: string; readonly page?: string; - readonly id: string; + readonly id?: string; readonly description?: string; readonly url?: string; child?: KibanaExecutionContext; diff --git a/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.md b/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.md index b517b91557357e..792af8f693869f 100644 --- a/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.md +++ b/docs/development/core/server/kibana-plugin-core-server.kibanaexecutioncontext.md @@ -10,10 +10,10 @@ Represents a meta-information about a Kibana entity initiating a search request. ```typescript export declare type KibanaExecutionContext = { - readonly type: string; - readonly name: string; + readonly type?: string; + readonly name?: string; readonly page?: string; - readonly id: string; + readonly id?: string; readonly description?: string; readonly url?: string; child?: KibanaExecutionContext; diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 0c8cbe93d119ce..5bffc3f2e707e9 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -762,10 +762,10 @@ export interface IUiSettingsClient { // @public export type KibanaExecutionContext = { - readonly type: string; - readonly name: string; + readonly type?: string; + readonly name?: string; readonly page?: string; - readonly id: string; + readonly id?: string; readonly description?: string; readonly url?: string; child?: KibanaExecutionContext; diff --git a/src/core/server/execution_context/execution_context_container.ts b/src/core/server/execution_context/execution_context_container.ts index 066248a26ad7b9..9dfa61c06c6b1b 100644 --- a/src/core/server/execution_context/execution_context_container.ts +++ b/src/core/server/execution_context/execution_context_container.ts @@ -50,7 +50,7 @@ export interface IExecutionContextContainer { } function stringify(ctx: KibanaExecutionContext): string { - const stringifiedCtx = `${ctx.type}:${ctx.name}:${encodeURIComponent(ctx.id!)}`; + const stringifiedCtx = `${ctx.type}:${ctx.name}:${encodeURIComponent(ctx.id || '')}`; return ctx.child ? `${stringifiedCtx};${stringify(ctx.child)}` : stringifiedCtx; } diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 7f07769d45ea45..0f5107509ba724 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -1319,10 +1319,10 @@ export interface IUiSettingsClient { // @public export type KibanaExecutionContext = { - readonly type: string; - readonly name: string; + readonly type?: string; + readonly name?: string; readonly page?: string; - readonly id: string; + readonly id?: string; readonly description?: string; readonly url?: string; child?: KibanaExecutionContext; diff --git a/src/core/types/execution_context.ts b/src/core/types/execution_context.ts index 91d6375b0522c1..f885f8ad740ff1 100644 --- a/src/core/types/execution_context.ts +++ b/src/core/types/execution_context.ts @@ -16,14 +16,14 @@ export type KibanaExecutionContext = { /** * Kibana application initated an operation. * */ - readonly type: string; // 'visualization' | 'actions' | 'server' | ..; + readonly type?: string; // 'visualization' | 'actions' | 'server' | ..; /** public name of an application or a user-facing feature */ - readonly name: string; // 'TSVB' | 'Lens' | 'action_execution' | ..; + readonly name?: string; // 'TSVB' | 'Lens' | 'action_execution' | ..; /** a stand alone, logical unit such as an application page or tab */ readonly page?: string; // /** space identifier */ /** unique value to identify the source */ - readonly id: string; + readonly id?: string; /** human readable description. For example, a vis title, action name */ readonly description?: string; /** in browser - url to navigate to a current page, on server - endpoint path, for task: task SO url */ From 7cfd118178704b6e1d4bf2e1877cecd202e5dd52 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 15 Feb 2022 17:49:29 +0200 Subject: [PATCH 29/57] clear on page change --- .../public/application/dashboard_app.tsx | 4 +-- .../application/listing/dashboard_listing.tsx | 5 ++-- src/plugins/dev_tools/public/application.tsx | 6 ++-- .../application/context/context_app.tsx | 3 +- .../application/doc/single_doc_route.tsx | 3 +- .../application/main/discover_main_route.tsx | 3 +- src/plugins/kibana_react/public/index.ts | 2 ++ .../public/use_execution_context/index.ts | 9 ++++++ .../use_execution_context.ts | 28 +++++++++++++++++++ .../components/visualize_editor.tsx | 4 +-- .../components/visualize_listing.tsx | 5 ++-- x-pack/plugins/lens/public/app_plugin/app.tsx | 4 +-- 12 files changed, 58 insertions(+), 18 deletions(-) create mode 100644 src/plugins/kibana_react/public/use_execution_context/index.ts create mode 100644 src/plugins/kibana_react/public/use_execution_context/use_execution_context.ts diff --git a/src/plugins/dashboard/public/application/dashboard_app.tsx b/src/plugins/dashboard/public/application/dashboard_app.tsx index 7f9f85e4aa7e46..a32e6643a4e3a1 100644 --- a/src/plugins/dashboard/public/application/dashboard_app.tsx +++ b/src/plugins/dashboard/public/application/dashboard_app.tsx @@ -11,7 +11,7 @@ import React, { useEffect, useMemo } from 'react'; import { useDashboardSelector } from './state'; import { useDashboardAppState } from './hooks'; -import { useKibana } from '../../../kibana_react/public'; +import { useKibana, useExecutionContext } from '../../../kibana_react/public'; import { getDashboardBreadcrumb, getDashboardTitle, @@ -48,7 +48,7 @@ export function DashboardApp({ [core.notifications.toasts, history, uiSettings] ); - core.executionContext.set({ + useExecutionContext(core.executionContext, { type: 'application', page: 'app', id: savedDashboardId || 'new', diff --git a/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx b/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx index cd5e70efae7b5b..84460d2380d6de 100644 --- a/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx +++ b/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx @@ -29,7 +29,7 @@ import { import { ApplicationStart, SavedObjectsFindOptionsReference } from '../../../../../core/public'; import { syncQueryStateWithUrl } from '../../services/data'; import { IKbnUrlStateStorage } from '../../services/kibana_utils'; -import { TableListView, useKibana } from '../../services/kibana_react'; +import { TableListView, useKibana, useExecutionContext } from '../../services/kibana_react'; import { SavedObjectsTaggingApi } from '../../services/saved_objects_tagging_oss'; import { DashboardUnsavedListing } from './dashboard_unsaved_listing'; import { confirmCreateWithUnsaved, confirmDiscardUnsavedChanges } from './confirm_overlays'; @@ -67,10 +67,9 @@ export const DashboardListing = ({ dashboardSessionStorage.getDashboardIdsWithUnsavedChanges() ); - core.executionContext.set({ + useExecutionContext(core.executionContext, { type: 'application', page: 'list', - id: '', }); // Set breadcrumbs useEffect diff --git a/src/plugins/dev_tools/public/application.tsx b/src/plugins/dev_tools/public/application.tsx index beebe9334738e3..d260f0677d95e9 100644 --- a/src/plugins/dev_tools/public/application.tsx +++ b/src/plugins/dev_tools/public/application.tsx @@ -22,7 +22,7 @@ import { CoreTheme, CoreStart, } from 'src/core/public'; -import { KibanaThemeProvider } from '../../kibana_react/public'; +import { KibanaThemeProvider, useExecutionContext } from '../../kibana_react/public'; import type { DocTitleService, BreadcrumbService } from './services'; import { DevToolApp } from './dev_tool'; @@ -71,9 +71,9 @@ function DevToolsWrapper({ breadcrumbService.setBreadcrumbs(activeDevTool.title); }, [activeDevTool, docTitleService, breadcrumbService]); - appServices.executionContext.set({ + useExecutionContext(appServices.executionContext, { type: 'application', - page: activeDevTool, + page: activeDevTool.id, }); return ( diff --git a/src/plugins/discover/public/application/context/context_app.tsx b/src/plugins/discover/public/application/context/context_app.tsx index a33238d6439527..36ee03e17894db 100644 --- a/src/plugins/discover/public/application/context/context_app.tsx +++ b/src/plugins/discover/public/application/context/context_app.tsx @@ -26,6 +26,7 @@ import { ContextAppContent } from './context_app_content'; import { SurrDocType } from './services/context'; import { DocViewFilterFn } from '../../services/doc_views/doc_views_types'; import { useDiscoverServices } from '../../utils/use_discover_services'; +import { useExecutionContext } from '../../../../kibana_react/public'; const ContextAppContentMemoized = memo(ContextAppContent); @@ -41,7 +42,7 @@ export const ContextApp = ({ indexPattern, anchorId }: ContextAppProps) => { const isLegacy = useMemo(() => uiSettings.get(DOC_TABLE_LEGACY), [uiSettings]); const useNewFieldsApi = useMemo(() => !uiSettings.get(SEARCH_FIELDS_FROM_SOURCE), [uiSettings]); - core.executionContext.set({ + useExecutionContext(core.executionContext, { type: 'application', page: 'context', id: indexPattern.id || '', diff --git a/src/plugins/discover/public/application/doc/single_doc_route.tsx b/src/plugins/discover/public/application/doc/single_doc_route.tsx index 2ad53051bd5e2b..89e78db1b96c2a 100644 --- a/src/plugins/discover/public/application/doc/single_doc_route.tsx +++ b/src/plugins/discover/public/application/doc/single_doc_route.tsx @@ -16,6 +16,7 @@ import { withQueryParams } from '../../utils/with_query_params'; import { useMainRouteBreadcrumb } from '../../utils/use_navigation_props'; import { Doc } from './components/doc'; import { useDiscoverServices } from '../../utils/use_discover_services'; +import { useExecutionContext } from '../../../../kibana_react/public'; export interface SingleDocRouteProps { /** @@ -36,7 +37,7 @@ const SingleDoc = ({ id }: SingleDocRouteProps) => { const { indexPatternId, index } = useParams(); const breadcrumb = useMainRouteBreadcrumb(); - core.executionContext.set({ + useExecutionContext(core.executionContext, { type: 'application', page: 'single-doc', id: indexPatternId || '', diff --git a/src/plugins/discover/public/application/main/discover_main_route.tsx b/src/plugins/discover/public/application/main/discover_main_route.tsx index 0585a0fead4d7f..dcf229d36b1e0e 100644 --- a/src/plugins/discover/public/application/main/discover_main_route.tsx +++ b/src/plugins/discover/public/application/main/discover_main_route.tsx @@ -24,6 +24,7 @@ import { LoadingIndicator } from '../../components/common/loading_indicator'; import { DiscoverError } from '../../components/common/error_alert'; import { useDiscoverServices } from '../../utils/use_discover_services'; import { getUrlTracker } from '../../kibana_services'; +import { useExecutionContext } from '../../../../kibana_react/public'; const DiscoverMainAppMemoized = memo(DiscoverMainApp); @@ -50,7 +51,7 @@ export function DiscoverMainRoute() { >([]); const { id } = useParams(); - core.executionContext.set({ + useExecutionContext(core.executionContext, { type: 'application', page: 'app', id: id || 'new', diff --git a/src/plugins/kibana_react/public/index.ts b/src/plugins/kibana_react/public/index.ts index baed839d411239..94e8b505f1dd20 100644 --- a/src/plugins/kibana_react/public/index.ts +++ b/src/plugins/kibana_react/public/index.ts @@ -39,6 +39,8 @@ export { createReactOverlays } from './overlays'; export { useUiSetting, useUiSetting$ } from './ui_settings'; +export { useExecutionContext } from './use_execution_context'; + export type { TableListViewProps, TableListViewState } from './table_list_view'; export { TableListView } from './table_list_view'; diff --git a/src/plugins/kibana_react/public/use_execution_context/index.ts b/src/plugins/kibana_react/public/use_execution_context/index.ts new file mode 100644 index 00000000000000..f36d094eb86d44 --- /dev/null +++ b/src/plugins/kibana_react/public/use_execution_context/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { useExecutionContext } from './use_execution_context'; diff --git a/src/plugins/kibana_react/public/use_execution_context/use_execution_context.ts b/src/plugins/kibana_react/public/use_execution_context/use_execution_context.ts new file mode 100644 index 00000000000000..e2c538056153c3 --- /dev/null +++ b/src/plugins/kibana_react/public/use_execution_context/use_execution_context.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { KibanaExecutionContext, CoreStart } from 'kibana/public'; +import useDeepCompareEffect from 'react-use/lib/useDeepCompareEffect'; + +/** + * Set and clean up application level execution context + * @param executionContext + * @param context + */ +export function useExecutionContext( + executionContext: CoreStart['executionContext'], + context: KibanaExecutionContext +) { + useDeepCompareEffect(() => { + executionContext.set(context); + + return () => { + executionContext.clear(); + }; + }, [context]); +} diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx index d6e6aef2a99a91..c9e2c418488abb 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx @@ -11,7 +11,7 @@ import React, { useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; import { EventEmitter } from 'events'; -import { useKibana } from '../../../../kibana_react/public'; +import { useExecutionContext, useKibana } from '../../../../kibana_react/public'; import { useChromeVisibility, useSavedVisInstance, @@ -33,7 +33,7 @@ export const VisualizeEditor = ({ onAppLeave }: VisualizeAppProps) => { const [eventEmitter] = useState(new EventEmitter()); const [hasUnsavedChanges, setHasUnsavedChanges] = useState(!visualizationIdFromUrl); - services.executionContext.set({ + useExecutionContext(services.executionContext, { type: 'application', page: 'editor', id: visualizationIdFromUrl, diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx index 2a1b36610cc225..a00070d025d79c 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx @@ -21,7 +21,7 @@ import { findListItems } from '../../utils/saved_visualize_utils'; import { showNewVisModal } from '../../wizard'; import { getTypes } from '../../services'; import { SavedObjectsFindOptionsReference } from '../../../../../core/public'; -import { useKibana, TableListView } from '../../../../kibana_react/public'; +import { useKibana, TableListView, useExecutionContext } from '../../../../kibana_react/public'; import { VISUALIZE_ENABLE_LABS_SETTING } from '../../../../visualizations/public'; import { VisualizeServices } from '../types'; import { VisualizeConstants } from '../../../common/constants'; @@ -97,10 +97,9 @@ export const VisualizeListing = () => { [application, history] ); - executionContext.set({ + useExecutionContext(executionContext, { type: 'application', page: 'list', - id: '', }); const noItemsFragment = useMemo(() => getNoItemsMessage(createNewVis), [createNewVis]); diff --git a/x-pack/plugins/lens/public/app_plugin/app.tsx b/x-pack/plugins/lens/public/app_plugin/app.tsx index 3180cd3b1a0a29..5ef9e05cf590b0 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.tsx @@ -13,7 +13,7 @@ import { createKbnUrlStateStorage, withNotifyOnErrors, } from '../../../../../src/plugins/kibana_utils/public'; -import { useKibana } from '../../../../../src/plugins/kibana_react/public'; +import { useExecutionContext, useKibana } from '../../../../../src/plugins/kibana_react/public'; import { OnSaveProps } from '../../../../../src/plugins/saved_objects/public'; import { syncQueryStateWithUrl } from '../../../../../src/plugins/data/public'; import { LensAppProps, LensAppServices } from './types'; @@ -124,7 +124,7 @@ export function App({ setIndicateNoData(true); }, [setIndicateNoData]); - executionContext.set({ + useExecutionContext(executionContext, { type: 'application', id: savedObjectId || 'new', page: 'editor', From 2a1a373da94bf6567c5ce6902bb6a2565373f15c Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 15 Feb 2022 18:06:38 +0200 Subject: [PATCH 30/57] lint --- src/core/public/http/fetch.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/public/http/fetch.ts b/src/core/public/http/fetch.ts index 69be13cffe7c33..8fa4c64efa0faf 100644 --- a/src/core/public/http/fetch.ts +++ b/src/core/public/http/fetch.ts @@ -22,7 +22,11 @@ import { HttpFetchError } from './http_fetch_error'; import { HttpInterceptController } from './http_intercept_controller'; import { interceptRequest, interceptResponse } from './intercept'; import { HttpInterceptHaltError } from './http_intercept_halt_error'; -import { ExecutionContextContainer, ExecutionContextSetup, KibanaExecutionContext } from '../execution_context'; +import { + ExecutionContextContainer, + ExecutionContextSetup, + KibanaExecutionContext, +} from '../execution_context'; interface Params { basePath: IBasePath; From 2b45d23d30278d315baa63160c9188c12dbf9a8b Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 15 Feb 2022 18:29:04 +0200 Subject: [PATCH 31/57] ts --- .../dashboard/public/application/listing/dashboard_listing.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx b/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx index 84460d2380d6de..65374ad723f232 100644 --- a/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx +++ b/src/plugins/dashboard/public/application/listing/dashboard_listing.tsx @@ -29,12 +29,13 @@ import { import { ApplicationStart, SavedObjectsFindOptionsReference } from '../../../../../core/public'; import { syncQueryStateWithUrl } from '../../services/data'; import { IKbnUrlStateStorage } from '../../services/kibana_utils'; -import { TableListView, useKibana, useExecutionContext } from '../../services/kibana_react'; +import { TableListView, useKibana } from '../../services/kibana_react'; import { SavedObjectsTaggingApi } from '../../services/saved_objects_tagging_oss'; import { DashboardUnsavedListing } from './dashboard_unsaved_listing'; import { confirmCreateWithUnsaved, confirmDiscardUnsavedChanges } from './confirm_overlays'; import { getDashboardListItemLink } from './get_dashboard_list_item_link'; import { DASHBOARD_PANELS_UNSAVED_ID } from '../lib/dashboard_session_storage'; +import { useExecutionContext } from '../../../../kibana_react/public'; export interface DashboardListingProps { kbnUrlStateStorage: IKbnUrlStateStorage; From 1cedb9942acd28a426501980ec2881a65736448a Mon Sep 17 00:00:00 2001 From: lizozom Date: Wed, 16 Feb 2022 11:48:02 +0200 Subject: [PATCH 32/57] skipped test again --- x-pack/test/functional_execution_context/tests/browser.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional_execution_context/tests/browser.ts b/x-pack/test/functional_execution_context/tests/browser.ts index ca777e1d4acf32..b402c31fddc526 100644 --- a/x-pack/test/functional_execution_context/tests/browser.ts +++ b/x-pack/test/functional_execution_context/tests/browser.ts @@ -12,7 +12,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const PageObjects = getPageObjects(['common', 'dashboard', 'header', 'home']); const retry = getService('retry'); - describe('Browser apps', () => { + // Failing: See https://github.com/elastic/kibana/issues/112102 + describe.skip('Browser apps', () => { before(async () => { await PageObjects.common.navigateToUrl('home', '/tutorial_directory/sampleData', { useActualUrl: true, From bb58dd25cd0e8cd3dd854846ea01d8c428b79b7b Mon Sep 17 00:00:00 2001 From: lizozom Date: Wed, 16 Feb 2022 17:57:09 +0200 Subject: [PATCH 33/57] testing fixes --- src/core/public/apm_system.ts | 3 ++- .../execution_context/execution_context_service.ts | 7 +++++-- src/core/server/http/http_server.ts | 14 +++++++++----- src/plugins/data/server/search/routes/bsearch.ts | 13 +++++++++++++ .../visualize_app/components/visualize_listing.tsx | 10 +++++----- 5 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/core/public/apm_system.ts b/src/core/public/apm_system.ts index 198c7f3c25a761..55d7c5c4655366 100644 --- a/src/core/public/apm_system.ts +++ b/src/core/public/apm_system.ts @@ -8,6 +8,7 @@ import type { ApmBase, AgentConfigOptions, Transaction } from '@elastic/apm-rum'; import { modifyUrl } from '@kbn/std'; +import { distinctUntilChanged } from 'rxjs/operators'; import { CachedResourceObserver } from './apm_resource_counter'; import type { InternalApplicationStart } from './application'; import { ExecutionContextStart } from './execution_context'; @@ -85,7 +86,7 @@ export class ApmSystem { * Register listeners for navigation changes and capture them as * route-change transactions after Kibana app is bootstrapped */ - start.application.currentAppId$.subscribe((appId) => { + start.application.currentAppId$.pipe(distinctUntilChanged()).subscribe((appId) => { if (appId && this.apm) { this.closePageLoadTransaction(); this.apm.startTransaction(appId, 'app-change', { diff --git a/src/core/public/execution_context/execution_context_service.ts b/src/core/public/execution_context/execution_context_service.ts index b796d21152b774..c296fdb5c8cd92 100644 --- a/src/core/public/execution_context/execution_context_service.ts +++ b/src/core/public/execution_context/execution_context_service.ts @@ -44,7 +44,10 @@ export class ExecutionContextService this.contract = { context$: this.context$, clear: () => { - this.context$.next({}); + this.context$.next({ + url: window.location.pathname, + name: this.appId, + }); }, set: (c: ExecutionContext) => { const newVal = { @@ -71,8 +74,8 @@ export class ExecutionContextService // Track app id changes and clear context on app change this.subscription.add( curApp$.pipe(distinctUntilChanged()).subscribe((appId) => { - start.clear(); this.appId = appId; + start.clear(); }) ); diff --git a/src/core/server/http/http_server.ts b/src/core/server/http/http_server.ts index 0f59f66d4fa835..9bd0f974a592a7 100644 --- a/src/core/server/http/http_server.ts +++ b/src/core/server/http/http_server.ts @@ -22,6 +22,7 @@ import type { Duration } from 'moment'; import { Observable } from 'rxjs'; import { take } from 'rxjs/operators'; import apm from 'elastic-apm-node'; +import { isUndefined, omit, omitBy } from 'lodash'; import { Logger, LoggerFactory } from '../logging'; import { HttpConfig } from './http_config'; import type { InternalExecutionContextSetup } from '../execution_context'; @@ -341,11 +342,14 @@ export class HttpServer { const parentContext = executionContext?.getParentContextFrom(request.headers); if (parentContext) { - const apmContext = { - appId: parentContext.name, - page: parentContext.page, - id: parentContext.id, - }; + const apmContext = omitBy( + { + appId: parentContext.name, + page: parentContext.page, + id: parentContext.id, + }, + isUndefined + ); apm.addLabels(apmContext); executionContext?.set(parentContext); diff --git a/src/plugins/data/server/search/routes/bsearch.ts b/src/plugins/data/server/search/routes/bsearch.ts index 314de4254851fb..9d58f254b6c1e3 100644 --- a/src/plugins/data/server/search/routes/bsearch.ts +++ b/src/plugins/data/server/search/routes/bsearch.ts @@ -9,6 +9,8 @@ import { catchError, first } from 'rxjs/operators'; import { BfetchServerSetup } from 'src/plugins/bfetch/server'; import type { ExecutionContextSetup } from 'src/core/server'; +import apm from 'elastic-apm-node'; +import { isUndefined, omitBy } from 'lodash'; import { IKibanaSearchRequest, IKibanaSearchResponse, @@ -34,6 +36,17 @@ export function registerBsearchRoute( onBatchItem: async ({ request: requestData, options }) => { const { executionContext, ...restOptions } = options || {}; + apm.addLabels( + omitBy( + { + appId: executionContext?.name, + id: executionContext?.id, + page: executionContext?.page, + }, + isUndefined + ) + ); + return executionContextService.withContext(executionContext, () => search .search(requestData, restOptions) diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx index a00070d025d79c..a180cf78feeb2e 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx @@ -50,6 +50,11 @@ export const VisualizeListing = () => { const closeNewVisModal = useRef(() => {}); const listingLimit = savedObjectsPublic.settings.getListingLimit(); + useExecutionContext(executionContext, { + type: 'application', + page: 'list', + }); + useEffect(() => { if (pathname === '/new') { // In case the user navigated to the page via the /visualize/new URL we start the dialog immediately @@ -97,11 +102,6 @@ export const VisualizeListing = () => { [application, history] ); - useExecutionContext(executionContext, { - type: 'application', - page: 'list', - }); - const noItemsFragment = useMemo(() => getNoItemsMessage(createNewVis), [createNewVis]); const tableColumns = useMemo( () => getTableColumns(application, kbnUrlStateStorage, savedObjectsTagging), From 2f2be65dfef0469b78a42d1aedb0fb81b24fcc08 Mon Sep 17 00:00:00 2001 From: lizozom Date: Wed, 16 Feb 2022 18:04:50 +0200 Subject: [PATCH 34/57] oops --- src/core/server/http/http_server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/server/http/http_server.ts b/src/core/server/http/http_server.ts index 9bd0f974a592a7..86d84705e28284 100644 --- a/src/core/server/http/http_server.ts +++ b/src/core/server/http/http_server.ts @@ -22,7 +22,7 @@ import type { Duration } from 'moment'; import { Observable } from 'rxjs'; import { take } from 'rxjs/operators'; import apm from 'elastic-apm-node'; -import { isUndefined, omit, omitBy } from 'lodash'; +import { isUndefined, omitBy } from 'lodash'; import { Logger, LoggerFactory } from '../logging'; import { HttpConfig } from './http_config'; import type { InternalExecutionContextSetup } from '../execution_context'; From 349ef2c50902f8b10ca963c43f9914a299402fd4 Mon Sep 17 00:00:00 2001 From: lizozom Date: Thu, 17 Feb 2022 17:36:12 +0200 Subject: [PATCH 35/57] code review #1 --- ...-core-public.coresetup.executioncontext.md | 1 + .../kibana-plugin-core-public.coresetup.md | 2 +- ...-core-public.corestart.executioncontext.md | 1 + .../kibana-plugin-core-public.corestart.md | 2 +- ...core-public.executioncontextsetup.clear.md | 15 +++++++++++ ...e-public.executioncontextsetup.context_.md | 11 ++++++++ ...ore-public.executioncontextsetup.getall.md | 15 +++++++++++ ...lugin-core-public.executioncontextsetup.md | 27 +++++++++++++++++++ ...n-core-public.executioncontextsetup.set.md | 22 +++++++++++++++ ...lugin-core-public.executioncontextstart.md | 13 +++++++++ .../core/public/kibana-plugin-core-public.md | 2 ++ src/core/public/apm_system.ts | 3 +-- .../execution_context_service.ts | 5 ++-- src/core/public/index.ts | 6 ++++- src/core/public/public.api.md | 23 +++++++++++----- src/core/types/execution_context.ts | 3 +-- src/plugins/dev_tools/public/application.tsx | 2 +- .../plugins/lens/public/app_plugin/types.ts | 4 +-- 18 files changed, 138 insertions(+), 19 deletions(-) create mode 100644 docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.clear.md create mode 100644 docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.context_.md create mode 100644 docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.getall.md create mode 100644 docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.md create mode 100644 docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.set.md create mode 100644 docs/development/core/public/kibana-plugin-core-public.executioncontextstart.md diff --git a/docs/development/core/public/kibana-plugin-core-public.coresetup.executioncontext.md b/docs/development/core/public/kibana-plugin-core-public.coresetup.executioncontext.md index dc1b5e1f336598..be5689ad7b080f 100644 --- a/docs/development/core/public/kibana-plugin-core-public.coresetup.executioncontext.md +++ b/docs/development/core/public/kibana-plugin-core-public.coresetup.executioncontext.md @@ -4,6 +4,7 @@ ## CoreSetup.executionContext property +[ExecutionContextSetup](./kibana-plugin-core-public.executioncontextsetup.md) Signature: diff --git a/docs/development/core/public/kibana-plugin-core-public.coresetup.md b/docs/development/core/public/kibana-plugin-core-public.coresetup.md index 547c2517405726..31793ec6f7a581 100644 --- a/docs/development/core/public/kibana-plugin-core-public.coresetup.md +++ b/docs/development/core/public/kibana-plugin-core-public.coresetup.md @@ -17,7 +17,7 @@ export interface CoreSetupSignature: diff --git a/docs/development/core/public/kibana-plugin-core-public.corestart.md b/docs/development/core/public/kibana-plugin-core-public.corestart.md index 8c0be567eb3230..edd80e1adb9f98 100644 --- a/docs/development/core/public/kibana-plugin-core-public.corestart.md +++ b/docs/development/core/public/kibana-plugin-core-public.corestart.md @@ -20,7 +20,7 @@ export interface CoreStart | [chrome](./kibana-plugin-core-public.corestart.chrome.md) | ChromeStart | [ChromeStart](./kibana-plugin-core-public.chromestart.md) | | [deprecations](./kibana-plugin-core-public.corestart.deprecations.md) | DeprecationsServiceStart | [DeprecationsServiceStart](./kibana-plugin-core-public.deprecationsservicestart.md) | | [docLinks](./kibana-plugin-core-public.corestart.doclinks.md) | DocLinksStart | [DocLinksStart](./kibana-plugin-core-public.doclinksstart.md) | -| [executionContext](./kibana-plugin-core-public.corestart.executioncontext.md) | ExecutionContextStart | | +| [executionContext](./kibana-plugin-core-public.corestart.executioncontext.md) | ExecutionContextStart | [ExecutionContextStart](./kibana-plugin-core-public.executioncontextstart.md) | | [fatalErrors](./kibana-plugin-core-public.corestart.fatalerrors.md) | FatalErrorsStart | [FatalErrorsStart](./kibana-plugin-core-public.fatalerrorsstart.md) | | [http](./kibana-plugin-core-public.corestart.http.md) | HttpStart | [HttpStart](./kibana-plugin-core-public.httpstart.md) | | [i18n](./kibana-plugin-core-public.corestart.i18n.md) | I18nStart | [I18nStart](./kibana-plugin-core-public.i18nstart.md) | diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.clear.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.clear.md new file mode 100644 index 00000000000000..9e9958dd2bd75f --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.clear.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ExecutionContextSetup](./kibana-plugin-core-public.executioncontextsetup.md) > [clear](./kibana-plugin-core-public.executioncontextsetup.clear.md) + +## ExecutionContextSetup.clear() method + +Signature: + +```typescript +clear(): void; +``` +Returns: + +void + diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.context_.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.context_.md new file mode 100644 index 00000000000000..d0d389f96cb335 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.context_.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ExecutionContextSetup](./kibana-plugin-core-public.executioncontextsetup.md) > [context$](./kibana-plugin-core-public.executioncontextsetup.context_.md) + +## ExecutionContextSetup.context$ property + +Signature: + +```typescript +context$: Observable; +``` diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.getall.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.getall.md new file mode 100644 index 00000000000000..bedb0e148579b2 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.getall.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ExecutionContextSetup](./kibana-plugin-core-public.executioncontextsetup.md) > [getAll](./kibana-plugin-core-public.executioncontextsetup.getall.md) + +## ExecutionContextSetup.getAll() method + +Signature: + +```typescript +getAll(): ExecutionContext; +``` +Returns: + +ExecutionContext + diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.md new file mode 100644 index 00000000000000..c89712b2342ea1 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.md @@ -0,0 +1,27 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ExecutionContextSetup](./kibana-plugin-core-public.executioncontextsetup.md) + +## ExecutionContextSetup interface + + +Signature: + +```typescript +export interface ExecutionContextSetup +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [context$](./kibana-plugin-core-public.executioncontextsetup.context_.md) | Observable<ExecutionContext> | | + +## Methods + +| Method | Description | +| --- | --- | +| [clear()](./kibana-plugin-core-public.executioncontextsetup.clear.md) | | +| [getAll()](./kibana-plugin-core-public.executioncontextsetup.getall.md) | | +| [set(c$)](./kibana-plugin-core-public.executioncontextsetup.set.md) | | + diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.set.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.set.md new file mode 100644 index 00000000000000..fbf6650eaae388 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.set.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ExecutionContextSetup](./kibana-plugin-core-public.executioncontextsetup.md) > [set](./kibana-plugin-core-public.executioncontextsetup.set.md) + +## ExecutionContextSetup.set() method + +Signature: + +```typescript +set(c$: ExecutionContext): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| c$ | ExecutionContext | | + +Returns: + +void + diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextstart.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextstart.md new file mode 100644 index 00000000000000..0d210ba5bb1c4d --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextstart.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ExecutionContextStart](./kibana-plugin-core-public.executioncontextstart.md) + +## ExecutionContextStart type + +See [ExecutionContextSetup](./kibana-plugin-core-public.executioncontextsetup.md). + +Signature: + +```typescript +export declare type ExecutionContextStart = ExecutionContextSetup; +``` diff --git a/docs/development/core/public/kibana-plugin-core-public.md b/docs/development/core/public/kibana-plugin-core-public.md index b51f5ed833fd37..407f80c5502040 100644 --- a/docs/development/core/public/kibana-plugin-core-public.md +++ b/docs/development/core/public/kibana-plugin-core-public.md @@ -62,6 +62,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [DeprecationsServiceStart](./kibana-plugin-core-public.deprecationsservicestart.md) | DeprecationsService provides methods to fetch domain deprecation details from the Kibana server. | | [DocLinksStart](./kibana-plugin-core-public.doclinksstart.md) | | | [ErrorToastOptions](./kibana-plugin-core-public.errortoastoptions.md) | Options available for [IToasts](./kibana-plugin-core-public.itoasts.md) error APIs. | +| [ExecutionContextSetup](./kibana-plugin-core-public.executioncontextsetup.md) | | | [FatalErrorInfo](./kibana-plugin-core-public.fatalerrorinfo.md) | Represents the message and stack of a fatal Error | | [FatalErrorsSetup](./kibana-plugin-core-public.fatalerrorssetup.md) | FatalErrors stop the Kibana Public Core and displays a fatal error screen with details about the Kibana build and the error. | | [HttpFetchOptions](./kibana-plugin-core-public.httpfetchoptions.md) | All options that may be used with a [HttpHandler](./kibana-plugin-core-public.httphandler.md). | @@ -160,6 +161,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [ChromeBreadcrumb](./kibana-plugin-core-public.chromebreadcrumb.md) | | | [ChromeHelpExtensionLinkBase](./kibana-plugin-core-public.chromehelpextensionlinkbase.md) | | | [ChromeHelpExtensionMenuLink](./kibana-plugin-core-public.chromehelpextensionmenulink.md) | | +| [ExecutionContextStart](./kibana-plugin-core-public.executioncontextstart.md) | See [ExecutionContextSetup](./kibana-plugin-core-public.executioncontextsetup.md). | | [FatalErrorsStart](./kibana-plugin-core-public.fatalerrorsstart.md) | FatalErrors stop the Kibana Public Core and displays a fatal error screen with details about the Kibana build and the error. | | [HttpStart](./kibana-plugin-core-public.httpstart.md) | See [HttpSetup](./kibana-plugin-core-public.httpsetup.md) | | [IToasts](./kibana-plugin-core-public.itoasts.md) | Methods for adding and removing global toast messages. See [ToastsApi](./kibana-plugin-core-public.toastsapi.md). | diff --git a/src/core/public/apm_system.ts b/src/core/public/apm_system.ts index 55d7c5c4655366..198c7f3c25a761 100644 --- a/src/core/public/apm_system.ts +++ b/src/core/public/apm_system.ts @@ -8,7 +8,6 @@ import type { ApmBase, AgentConfigOptions, Transaction } from '@elastic/apm-rum'; import { modifyUrl } from '@kbn/std'; -import { distinctUntilChanged } from 'rxjs/operators'; import { CachedResourceObserver } from './apm_resource_counter'; import type { InternalApplicationStart } from './application'; import { ExecutionContextStart } from './execution_context'; @@ -86,7 +85,7 @@ export class ApmSystem { * Register listeners for navigation changes and capture them as * route-change transactions after Kibana app is bootstrapped */ - start.application.currentAppId$.pipe(distinctUntilChanged()).subscribe((appId) => { + start.application.currentAppId$.subscribe((appId) => { if (appId && this.apm) { this.closePageLoadTransaction(); this.apm.startTransaction(appId, 'app-change', { diff --git a/src/core/public/execution_context/execution_context_service.ts b/src/core/public/execution_context/execution_context_service.ts index c296fdb5c8cd92..8002a763f29de8 100644 --- a/src/core/public/execution_context/execution_context_service.ts +++ b/src/core/public/execution_context/execution_context_service.ts @@ -8,7 +8,6 @@ import { isEqual } from 'lodash'; import { BehaviorSubject, Observable, Subscription } from 'rxjs'; -import { distinctUntilChanged } from 'rxjs/operators'; import { CoreService } from '../../types'; export type ExecutionContext = Record; @@ -42,7 +41,7 @@ export class ExecutionContextService public setup() { this.contract = { - context$: this.context$, + context$: this.context$.asObservable(), clear: () => { this.context$.next({ url: window.location.pathname, @@ -73,7 +72,7 @@ export class ExecutionContextService // Track app id changes and clear context on app change this.subscription.add( - curApp$.pipe(distinctUntilChanged()).subscribe((appId) => { + curApp$.subscribe((appId) => { this.appId = appId; start.clear(); }) diff --git a/src/core/public/index.ts b/src/core/public/index.ts index 87335206fbea27..50d8bf304ddf8f 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -195,7 +195,11 @@ export type { MountPoint, UnmountCallback, PublicUiSettingsParams } from './type export { URL_MAX_LENGTH } from './core_app'; -export type { KibanaExecutionContext } from './execution_context'; +export type { + KibanaExecutionContext, + ExecutionContextSetup, + ExecutionContextStart, +} from './execution_context'; /** * Core services exposed to the `Plugin` setup lifecycle diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 5bffc3f2e707e9..fecbc6f20ce949 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -400,9 +400,6 @@ export interface CoreContext { export interface CoreSetup { // (undocumented) application: ApplicationSetup; - // Warning: (ae-forgotten-export) The symbol "ExecutionContextSetup" needs to be exported by the entry point index.d.ts - // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "ExecutionContextSetup" - // // (undocumented) executionContext: ExecutionContextSetup; // (undocumented) @@ -433,9 +430,6 @@ export interface CoreStart { deprecations: DeprecationsServiceStart; // (undocumented) docLinks: DocLinksStart; - // Warning: (ae-forgotten-export) The symbol "ExecutionContextStart" needs to be exported by the entry point index.d.ts - // Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "ExecutionContextStart" - // // (undocumented) executionContext: ExecutionContextStart; // (undocumented) @@ -522,6 +516,23 @@ export interface ErrorToastOptions extends ToastOptions { toastMessage?: string; } +// @public (undocumented) +export interface ExecutionContextSetup { + // (undocumented) + clear(): void; + // Warning: (ae-forgotten-export) The symbol "ExecutionContext" needs to be exported by the entry point index.d.ts + // + // (undocumented) + context$: Observable; + // (undocumented) + getAll(): ExecutionContext; + // (undocumented) + set(c$: ExecutionContext): void; +} + +// @public +export type ExecutionContextStart = ExecutionContextSetup; + // @public export interface FatalErrorInfo { // (undocumented) diff --git a/src/core/types/execution_context.ts b/src/core/types/execution_context.ts index f885f8ad740ff1..d790b8d855fd4e 100644 --- a/src/core/types/execution_context.ts +++ b/src/core/types/execution_context.ts @@ -20,8 +20,7 @@ export type KibanaExecutionContext = { /** public name of an application or a user-facing feature */ readonly name?: string; // 'TSVB' | 'Lens' | 'action_execution' | ..; /** a stand alone, logical unit such as an application page or tab */ - readonly page?: string; // - /** space identifier */ + readonly page?: string; /** unique value to identify the source */ readonly id?: string; /** human readable description. For example, a vis title, action name */ diff --git a/src/plugins/dev_tools/public/application.tsx b/src/plugins/dev_tools/public/application.tsx index d260f0677d95e9..49aeb03de5c578 100644 --- a/src/plugins/dev_tools/public/application.tsx +++ b/src/plugins/dev_tools/public/application.tsx @@ -15,7 +15,7 @@ import { I18nProvider } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { euiThemeVars } from '@kbn/ui-theme'; -import { +import type { ApplicationStart, ChromeStart, ScopedHistory, diff --git a/x-pack/plugins/lens/public/app_plugin/types.ts b/x-pack/plugins/lens/public/app_plugin/types.ts index ef9d890e250a60..25fff038c4814e 100644 --- a/x-pack/plugins/lens/public/app_plugin/types.ts +++ b/x-pack/plugins/lens/public/app_plugin/types.ts @@ -12,7 +12,7 @@ import type { ApplicationStart, AppMountParameters, ChromeStart, - CoreStart, + ExecutionContextStart, HttpStart, IUiSettingsClient, NotificationsStart, @@ -115,7 +115,7 @@ export interface HistoryLocationState { export interface LensAppServices { http: HttpStart; - executionContext: CoreStart['executionContext']; + executionContext: ExecutionContextStart; chrome: ChromeStart; overlays: OverlayStart; storage: IStorageWrapper; From efd5ea495661ee410cb1acfaa5a686e6697cd74c Mon Sep 17 00:00:00 2001 From: lizozom Date: Mon, 21 Feb 2022 15:30:52 +0200 Subject: [PATCH 36/57] code review #2 --- src/core/public/apm_system.ts | 7 +--- .../execution_context_service.ts | 38 +++++++++++++++---- .../execution_context_service.ts | 23 +++++++++++ src/core/server/http/http_server.ts | 16 ++------ .../search_interceptor/search_interceptor.ts | 6 +-- .../data/server/search/routes/bsearch.ts | 12 +----- 6 files changed, 60 insertions(+), 42 deletions(-) diff --git a/src/core/public/apm_system.ts b/src/core/public/apm_system.ts index 198c7f3c25a761..4e116c0a0182dd 100644 --- a/src/core/public/apm_system.ts +++ b/src/core/public/apm_system.ts @@ -70,12 +70,7 @@ export class ApmSystem { start.executionContext.context$.subscribe((c) => { // We're using labels because we want the context to be indexed // https://www.elastic.co/guide/en/apm/get-started/current/metadata.html - const apmContext = { - appId: c.name, - page: c.page, - id: c.id, - }; - + const apmContext = start.executionContext.getAsLabels(); this.apm?.addLabels(apmContext); }); diff --git a/src/core/public/execution_context/execution_context_service.ts b/src/core/public/execution_context/execution_context_service.ts index 8002a763f29de8..beb54aa905052c 100644 --- a/src/core/public/execution_context/execution_context_service.ts +++ b/src/core/public/execution_context/execution_context_service.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { isEqual } from 'lodash'; +import { isEqual, isUndefined, omitBy } from 'lodash'; import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { CoreService } from '../../types'; @@ -16,8 +16,16 @@ export type ExecutionContext = Record; export interface ExecutionContextSetup { context$: Observable; set(c$: ExecutionContext): void; - getAll(): ExecutionContext; + get(): ExecutionContext; clear(): void; + /** + * returns apm labels + **/ + getAsLabels(): Labels; + /** + * merges the current global context with the specific event context + **/ + withGlobalContext(context?: ExecutionContext): ExecutionContext; } /** @@ -43,10 +51,7 @@ export class ExecutionContextService this.contract = { context$: this.context$.asObservable(), clear: () => { - this.context$.next({ - url: window.location.pathname, - name: this.appId, - }); + this.context$.next({}); }, set: (c: ExecutionContext) => { const newVal = { @@ -59,9 +64,28 @@ export class ExecutionContextService this.context$.next(newVal); } }, - getAll: () => { + get: () => { return this.context$.value; }, + getAsLabels: () => { + const executionContext = this.context$.value; + return omitBy( + { + appId: executionContext?.name, + id: executionContext?.id, + page: executionContext?.page, + }, + isUndefined + ) as Labels; + }, + withGlobalContext: (context: ExecutionContext) => { + return { + appId: this.appId, + url: window.location.pathname, + ...this.context$.value, + ...(context || {}), + }; + }, }; return this.contract; diff --git a/src/core/server/execution_context/execution_context_service.ts b/src/core/server/execution_context/execution_context_service.ts index 6e2b809e230431..69a6348b237c81 100644 --- a/src/core/server/execution_context/execution_context_service.ts +++ b/src/core/server/execution_context/execution_context_service.ts @@ -6,6 +6,8 @@ * Side Public License, v 1. */ import { AsyncLocalStorage } from 'async_hooks'; +import apm from 'elastic-apm-node'; +import { isUndefined, omitBy } from 'lodash'; import type { Subscription } from 'rxjs'; import type { CoreService, KibanaExecutionContext } from '../../types'; @@ -39,6 +41,10 @@ export interface IExecutionContext { * returns serialized representation to send as a header **/ getAsHeader(): string | undefined; + /** + * returns apm labels + **/ + getAsLabels(): apm.Labels; } /** @@ -61,6 +67,7 @@ export interface ExecutionContextSetup { * The nested calls stack the registered context on top of each other. **/ withContext(context: KibanaExecutionContext | undefined, fn: (...args: any[]) => R): R; + getAsLabels(): apm.Labels; } /** @@ -97,6 +104,7 @@ export class ExecutionContextService setRequestId: this.setRequestId.bind(this), get: this.get.bind(this), getAsHeader: this.getAsHeader.bind(this), + getAsLabels: this.getAsLabels.bind(this), }; } @@ -108,6 +116,7 @@ export class ExecutionContextService withContext: this.withContext.bind(this), get: this.get.bind(this), getAsHeader: this.getAsHeader.bind(this), + getAsLabels: this.getAsLabels.bind(this), }; } @@ -161,4 +170,18 @@ export class ExecutionContextService return `${requestId}${executionContextStr}`; } + + private getAsLabels() { + if (!this.enabled) return {}; + const executionContext = this.contextStore.getStore()?.toJSON(); + + return omitBy( + { + appId: executionContext?.name, + id: executionContext?.id, + page: executionContext?.page, + }, + isUndefined + ); + } } diff --git a/src/core/server/http/http_server.ts b/src/core/server/http/http_server.ts index 86d84705e28284..813f8e97843326 100644 --- a/src/core/server/http/http_server.ts +++ b/src/core/server/http/http_server.ts @@ -22,7 +22,6 @@ import type { Duration } from 'moment'; import { Observable } from 'rxjs'; import { take } from 'rxjs/operators'; import apm from 'elastic-apm-node'; -import { isUndefined, omitBy } from 'lodash'; import { Logger, LoggerFactory } from '../logging'; import { HttpConfig } from './http_config'; import type { InternalExecutionContextSetup } from '../execution_context'; @@ -341,18 +340,9 @@ export class HttpServer { const parentContext = executionContext?.getParentContextFrom(request.headers); - if (parentContext) { - const apmContext = omitBy( - { - appId: parentContext.name, - page: parentContext.page, - id: parentContext.id, - }, - isUndefined - ); - - apm.addLabels(apmContext); - executionContext?.set(parentContext); + if (executionContext && parentContext) { + executionContext.set(parentContext); + apm.addLabels(executionContext.getAsLabels()); } executionContext?.setRequestId(requestId); diff --git a/src/plugins/data/public/search/search_interceptor/search_interceptor.ts b/src/plugins/data/public/search/search_interceptor/search_interceptor.ts index 770eb2f0c0a941..251e191d589e3d 100644 --- a/src/plugins/data/public/search/search_interceptor/search_interceptor.ts +++ b/src/plugins/data/public/search/search_interceptor/search_interceptor.ts @@ -25,7 +25,6 @@ import { CoreSetup, CoreStart, IHttpFetchError, - KibanaExecutionContext, ThemeServiceSetup, ToastsSetup, } from 'kibana/public'; @@ -305,10 +304,7 @@ export class SearchInterceptor { request, options: this.getSerializableOptions({ ...rest, - executionContext: { - ...executionContext, - ...this.deps.executionContext.getAll(), - } as KibanaExecutionContext, + executionContext: this.deps.executionContext.withGlobalContext(executionContext), }), }, abortSignal diff --git a/src/plugins/data/server/search/routes/bsearch.ts b/src/plugins/data/server/search/routes/bsearch.ts index 9d58f254b6c1e3..b267944129a478 100644 --- a/src/plugins/data/server/search/routes/bsearch.ts +++ b/src/plugins/data/server/search/routes/bsearch.ts @@ -10,7 +10,6 @@ import { catchError, first } from 'rxjs/operators'; import { BfetchServerSetup } from 'src/plugins/bfetch/server'; import type { ExecutionContextSetup } from 'src/core/server'; import apm from 'elastic-apm-node'; -import { isUndefined, omitBy } from 'lodash'; import { IKibanaSearchRequest, IKibanaSearchResponse, @@ -36,16 +35,7 @@ export function registerBsearchRoute( onBatchItem: async ({ request: requestData, options }) => { const { executionContext, ...restOptions } = options || {}; - apm.addLabels( - omitBy( - { - appId: executionContext?.name, - id: executionContext?.id, - page: executionContext?.page, - }, - isUndefined - ) - ); + apm.addLabels(executionContextService.getAsLabels()); return executionContextService.withContext(executionContext, () => search From 80b1b6833bfaf4ce335ad0a4cf51c99bef9d24aa Mon Sep 17 00:00:00 2001 From: lizozom Date: Mon, 21 Feb 2022 19:27:25 +0200 Subject: [PATCH 37/57] getAsLabels --- src/core/public/apm_system.ts | 5 +-- .../execution_context_service.mock.ts | 4 +- .../execution_context_service.ts | 40 +++++++++---------- src/core/public/http/fetch.ts | 5 +-- .../execution_context_service.mock.ts | 2 + .../execution_context_service.ts | 2 +- src/core/server/plugins/plugin_context.ts | 1 + .../data/server/search/routes/bsearch.ts | 11 +++-- 8 files changed, 34 insertions(+), 36 deletions(-) diff --git a/src/core/public/apm_system.ts b/src/core/public/apm_system.ts index 4e116c0a0182dd..a2fcdb45119e93 100644 --- a/src/core/public/apm_system.ts +++ b/src/core/public/apm_system.ts @@ -83,10 +83,7 @@ export class ApmSystem { start.application.currentAppId$.subscribe((appId) => { if (appId && this.apm) { this.closePageLoadTransaction(); - this.apm.startTransaction(appId, 'app-change', { - managed: true, - canReuse: true, - }); + this.apm.startTransaction(appId, 'app-change'); } }); } diff --git a/src/core/public/execution_context/execution_context_service.mock.ts b/src/core/public/execution_context/execution_context_service.mock.ts index 63444a7d7d0941..3941aa333cfa2a 100644 --- a/src/core/public/execution_context/execution_context_service.mock.ts +++ b/src/core/public/execution_context/execution_context_service.mock.ts @@ -15,7 +15,9 @@ const createContractMock = (): jest.Mocked => ({ context$: new BehaviorSubject({}), clear: jest.fn(), set: jest.fn(), - getAll: jest.fn(), + get: jest.fn(), + getAsLabels: jest.fn(), + withGlobalContext: jest.fn(), }); const createMock = (): jest.Mocked> => ({ diff --git a/src/core/public/execution_context/execution_context_service.ts b/src/core/public/execution_context/execution_context_service.ts index beb54aa905052c..915bf439f99a3d 100644 --- a/src/core/public/execution_context/execution_context_service.ts +++ b/src/core/public/execution_context/execution_context_service.ts @@ -8,15 +8,13 @@ import { isEqual, isUndefined, omitBy } from 'lodash'; import { BehaviorSubject, Observable, Subscription } from 'rxjs'; -import { CoreService } from '../../types'; - -export type ExecutionContext = Record; +import { CoreService, KibanaExecutionContext } from '../../types'; /** @public */ export interface ExecutionContextSetup { - context$: Observable; - set(c$: ExecutionContext): void; - get(): ExecutionContext; + context$: Observable; + set(c$: KibanaExecutionContext): void; + get(): KibanaExecutionContext; clear(): void; /** * returns apm labels @@ -25,7 +23,7 @@ export interface ExecutionContextSetup { /** * merges the current global context with the specific event context **/ - withGlobalContext(context?: ExecutionContext): ExecutionContext; + withGlobalContext(context?: KibanaExecutionContext): KibanaExecutionContext; } /** @@ -42,7 +40,7 @@ export interface StartDeps { export class ExecutionContextService implements CoreService { - private context$: BehaviorSubject = new BehaviorSubject({}); + private context$: BehaviorSubject = new BehaviorSubject({}); private appId?: string; private subscription: Subscription = new Subscription(); private contract?: ExecutionContextSetup; @@ -53,10 +51,8 @@ export class ExecutionContextService clear: () => { this.context$.next({}); }, - set: (c: ExecutionContext) => { + set: (c: KibanaExecutionContext) => { const newVal = { - url: window.location.pathname, - name: this.appId, ...this.context$.value, ...c, }; @@ -68,23 +64,18 @@ export class ExecutionContextService return this.context$.value; }, getAsLabels: () => { - const executionContext = this.context$.value; + const executionContext = this.mergeContext(); return omitBy( { - appId: executionContext?.name, + name: executionContext?.name, id: executionContext?.id, page: executionContext?.page, }, isUndefined ) as Labels; }, - withGlobalContext: (context: ExecutionContext) => { - return { - appId: this.appId, - url: window.location.pathname, - ...this.context$.value, - ...(context || {}), - }; + withGlobalContext: (context: KibanaExecutionContext) => { + return this.mergeContext(context); }, }; @@ -108,4 +99,13 @@ export class ExecutionContextService public stop() { this.subscription.unsubscribe(); } + + private mergeContext(context: KibanaExecutionContext = {}): KibanaExecutionContext { + return { + name: this.appId, + url: window.location.pathname, + ...this.context$.value, + ...context, + }; + } } diff --git a/src/core/public/http/fetch.ts b/src/core/public/http/fetch.ts index 8fa4c64efa0faf..56563af69affca 100644 --- a/src/core/public/http/fetch.ts +++ b/src/core/public/http/fetch.ts @@ -112,10 +112,7 @@ export class Fetch { }; private createRequest(options: HttpFetchOptionsWithPath): Request { - const context = { - ...this.params.executionContext?.getAll(), - ...options.context, - } as KibanaExecutionContext; + const context = this.params.executionContext.withGlobalContext(options.context); // Merge and destructure options out that are not applicable to the Fetch API. const { query, diff --git a/src/core/server/execution_context/execution_context_service.mock.ts b/src/core/server/execution_context/execution_context_service.mock.ts index 68aab7a5b84f84..85768eb423f26b 100644 --- a/src/core/server/execution_context/execution_context_service.mock.ts +++ b/src/core/server/execution_context/execution_context_service.mock.ts @@ -26,6 +26,7 @@ const createExecutionContextMock = () => { get: jest.fn(), getParentContextFrom: jest.fn(), getAsHeader: jest.fn(), + getAsLabels: jest.fn(), }; mock.withContext.mockImplementation(withContextMock); return mock; @@ -38,6 +39,7 @@ const createInternalSetupContractMock = () => { const createSetupContractMock = () => { const mock: jest.Mocked = { withContext: jest.fn(), + getAsLabels: jest.fn(), }; mock.withContext.mockImplementation(withContextMock); return mock; diff --git a/src/core/server/execution_context/execution_context_service.ts b/src/core/server/execution_context/execution_context_service.ts index 69a6348b237c81..03ae2cb36c9ec2 100644 --- a/src/core/server/execution_context/execution_context_service.ts +++ b/src/core/server/execution_context/execution_context_service.ts @@ -177,7 +177,7 @@ export class ExecutionContextService return omitBy( { - appId: executionContext?.name, + name: executionContext?.name, id: executionContext?.id, page: executionContext?.page, }, diff --git a/src/core/server/plugins/plugin_context.ts b/src/core/server/plugins/plugin_context.ts index 18abbe88c49135..983a12627b7f38 100644 --- a/src/core/server/plugins/plugin_context.ts +++ b/src/core/server/plugins/plugin_context.ts @@ -161,6 +161,7 @@ export function createPluginSetupContext( }, executionContext: { withContext: deps.executionContext.withContext, + getAsLabels: deps.executionContext.getAsLabels, }, http: { createCookieSessionStorageFactory: deps.http.createCookieSessionStorageFactory, diff --git a/src/plugins/data/server/search/routes/bsearch.ts b/src/plugins/data/server/search/routes/bsearch.ts index b267944129a478..25b1bd0d7009d4 100644 --- a/src/plugins/data/server/search/routes/bsearch.ts +++ b/src/plugins/data/server/search/routes/bsearch.ts @@ -34,11 +34,10 @@ export function registerBsearchRoute( */ onBatchItem: async ({ request: requestData, options }) => { const { executionContext, ...restOptions } = options || {}; + return executionContextService.withContext(executionContext, () => { + apm.addLabels(executionContextService.getAsLabels()); - apm.addLabels(executionContextService.getAsLabels()); - - return executionContextService.withContext(executionContext, () => - search + return search .search(requestData, restOptions) .pipe( first(), @@ -52,8 +51,8 @@ export function registerBsearchRoute( }; }) ) - .toPromise() - ); + .toPromise(); + }); }, }; }); From 3c8a87d80c4bbce501fe934e8de17867b5fc5a03 Mon Sep 17 00:00:00 2001 From: lizozom Date: Mon, 21 Feb 2022 19:29:31 +0200 Subject: [PATCH 38/57] maps inherit dashboard context --- x-pack/plugins/maps/public/util.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/maps/public/util.ts b/x-pack/plugins/maps/public/util.ts index 4adb8b35bfcea2..ac0136b48a8b49 100644 --- a/x-pack/plugins/maps/public/util.ts +++ b/x-pack/plugins/maps/public/util.ts @@ -8,7 +8,13 @@ import { EMSClient, FileLayer, TMSService } from '@elastic/ems-client'; import type { KibanaExecutionContext } from 'kibana/public'; import { FONTS_API_PATH } from '../common/constants'; -import { getHttp, getTilemap, getEMSSettings, getMapsEmsStart } from './kibana_services'; +import { + getHttp, + getTilemap, + getEMSSettings, + getMapsEmsStart, + getExecutionContext, +} from './kibana_services'; import { getLicenseId } from './licensed_features'; import { makeExecutionContext } from '../common/execution_context'; @@ -71,5 +77,14 @@ export function makePublicExecutionContext( id: string, description?: string ): KibanaExecutionContext { - return makeExecutionContext(id, window.location.pathname, description); + const topLevelContext = getExecutionContext().get(); + const context = makeExecutionContext(id, window.location.pathname, description); + + // Distinguish between running in maps app vs. embedded + return topLevelContext.name !== context.name + ? { + ...topLevelContext, + child: context, + } + : context; } From 86b8cba24d540c0999f78e3c68c5edaa1067adef Mon Sep 17 00:00:00 2001 From: lizozom Date: Mon, 21 Feb 2022 19:36:32 +0200 Subject: [PATCH 39/57] docs --- ...e-public.executioncontextsetup.context_.md | 2 +- ...-core-public.executioncontextsetup.get.md} | 8 +++---- ...ublic.executioncontextsetup.getaslabels.md | 17 +++++++++++++ ...lugin-core-public.executioncontextsetup.md | 6 +++-- ...n-core-public.executioncontextsetup.set.md | 4 ++-- ...executioncontextsetup.withglobalcontext.md | 24 +++++++++++++++++++ ...erver.executioncontextsetup.getaslabels.md | 15 ++++++++++++ ...lugin-core-server.executioncontextsetup.md | 1 + src/core/public/public.api.md | 10 ++++---- src/core/server/server.api.md | 3 +++ 10 files changed, 76 insertions(+), 14 deletions(-) rename docs/development/core/public/{kibana-plugin-core-public.executioncontextsetup.getall.md => kibana-plugin-core-public.executioncontextsetup.get.md} (57%) create mode 100644 docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.getaslabels.md create mode 100644 docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.withglobalcontext.md create mode 100644 docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.getaslabels.md diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.context_.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.context_.md index d0d389f96cb335..1ec926f28ea508 100644 --- a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.context_.md +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.context_.md @@ -7,5 +7,5 @@ Signature: ```typescript -context$: Observable; +context$: Observable; ``` diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.getall.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.get.md similarity index 57% rename from docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.getall.md rename to docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.get.md index bedb0e148579b2..6c778142c8500e 100644 --- a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.getall.md +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.get.md @@ -1,15 +1,15 @@ -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ExecutionContextSetup](./kibana-plugin-core-public.executioncontextsetup.md) > [getAll](./kibana-plugin-core-public.executioncontextsetup.getall.md) +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ExecutionContextSetup](./kibana-plugin-core-public.executioncontextsetup.md) > [get](./kibana-plugin-core-public.executioncontextsetup.get.md) -## ExecutionContextSetup.getAll() method +## ExecutionContextSetup.get() method Signature: ```typescript -getAll(): ExecutionContext; +get(): KibanaExecutionContext; ``` Returns: -ExecutionContext +KibanaExecutionContext diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.getaslabels.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.getaslabels.md new file mode 100644 index 00000000000000..0f0bda4e2913e9 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.getaslabels.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ExecutionContextSetup](./kibana-plugin-core-public.executioncontextsetup.md) > [getAsLabels](./kibana-plugin-core-public.executioncontextsetup.getaslabels.md) + +## ExecutionContextSetup.getAsLabels() method + +returns apm labels + +Signature: + +```typescript +getAsLabels(): Labels; +``` +Returns: + +Labels + diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.md index c89712b2342ea1..d67ce2b7091ccd 100644 --- a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.md +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.md @@ -15,13 +15,15 @@ export interface ExecutionContextSetup | Property | Type | Description | | --- | --- | --- | -| [context$](./kibana-plugin-core-public.executioncontextsetup.context_.md) | Observable<ExecutionContext> | | +| [context$](./kibana-plugin-core-public.executioncontextsetup.context_.md) | Observable<KibanaExecutionContext> | | ## Methods | Method | Description | | --- | --- | | [clear()](./kibana-plugin-core-public.executioncontextsetup.clear.md) | | -| [getAll()](./kibana-plugin-core-public.executioncontextsetup.getall.md) | | +| [get()](./kibana-plugin-core-public.executioncontextsetup.get.md) | | +| [getAsLabels()](./kibana-plugin-core-public.executioncontextsetup.getaslabels.md) | returns apm labels | | [set(c$)](./kibana-plugin-core-public.executioncontextsetup.set.md) | | +| [withGlobalContext(context)](./kibana-plugin-core-public.executioncontextsetup.withglobalcontext.md) | merges the current global context with the specific event context | diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.set.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.set.md index fbf6650eaae388..c0fb2cdd60258b 100644 --- a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.set.md +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.set.md @@ -7,14 +7,14 @@ Signature: ```typescript -set(c$: ExecutionContext): void; +set(c$: KibanaExecutionContext): void; ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| c$ | ExecutionContext | | +| c$ | KibanaExecutionContext | | Returns: diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.withglobalcontext.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.withglobalcontext.md new file mode 100644 index 00000000000000..a4e412a5133b85 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.withglobalcontext.md @@ -0,0 +1,24 @@ + + +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ExecutionContextSetup](./kibana-plugin-core-public.executioncontextsetup.md) > [withGlobalContext](./kibana-plugin-core-public.executioncontextsetup.withglobalcontext.md) + +## ExecutionContextSetup.withGlobalContext() method + +merges the current global context with the specific event context + +Signature: + +```typescript +withGlobalContext(context?: KibanaExecutionContext): KibanaExecutionContext; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| context | KibanaExecutionContext | | + +Returns: + +KibanaExecutionContext + diff --git a/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.getaslabels.md b/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.getaslabels.md new file mode 100644 index 00000000000000..c8816a3deee4da --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.getaslabels.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [ExecutionContextSetup](./kibana-plugin-core-server.executioncontextsetup.md) > [getAsLabels](./kibana-plugin-core-server.executioncontextsetup.getaslabels.md) + +## ExecutionContextSetup.getAsLabels() method + +Signature: + +```typescript +getAsLabels(): apm.Labels; +``` +Returns: + +apm.Labels + diff --git a/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.md b/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.md index 24591648ad953b..7fdc4d1ec1d57c 100644 --- a/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.md +++ b/docs/development/core/server/kibana-plugin-core-server.executioncontextsetup.md @@ -15,5 +15,6 @@ export interface ExecutionContextSetup | Method | Description | | --- | --- | +| [getAsLabels()](./kibana-plugin-core-server.executioncontextsetup.getaslabels.md) | | | [withContext(context, fn)](./kibana-plugin-core-server.executioncontextsetup.withcontext.md) | Keeps track of execution context while the passed function is executed. Data are carried over all async operations spawned by the passed function. The nested calls stack the registered context on top of each other. | diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index fecbc6f20ce949..177e0e92b8620f 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -520,14 +520,14 @@ export interface ErrorToastOptions extends ToastOptions { export interface ExecutionContextSetup { // (undocumented) clear(): void; - // Warning: (ae-forgotten-export) The symbol "ExecutionContext" needs to be exported by the entry point index.d.ts - // // (undocumented) - context$: Observable; + context$: Observable; // (undocumented) - getAll(): ExecutionContext; + get(): KibanaExecutionContext; + getAsLabels(): Labels; // (undocumented) - set(c$: ExecutionContext): void; + set(c$: KibanaExecutionContext): void; + withGlobalContext(context?: KibanaExecutionContext): KibanaExecutionContext; } // @public diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 0f5107509ba724..5fe1942ed8453b 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -7,6 +7,7 @@ /// import { AddConfigDeprecation } from '@kbn/config'; +import apm from 'elastic-apm-node'; import Boom from '@hapi/boom'; import { ByteSizeValue } from '@kbn/config-schema'; import { CliArgs } from '@kbn/config'; @@ -994,6 +995,8 @@ export class EventLoopDelaysMonitor { // @public (undocumented) export interface ExecutionContextSetup { + // (undocumented) + getAsLabels(): apm.Labels; withContext(context: KibanaExecutionContext | undefined, fn: (...args: any[]) => R): R; } From 66d6d3c690f85fec11475c45caeb89867b9a6d8f Mon Sep 17 00:00:00 2001 From: lizozom Date: Mon, 21 Feb 2022 19:36:41 +0200 Subject: [PATCH 40/57] ts --- src/core/public/http/fetch.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/public/http/fetch.ts b/src/core/public/http/fetch.ts index 56563af69affca..abaae54e75851f 100644 --- a/src/core/public/http/fetch.ts +++ b/src/core/public/http/fetch.ts @@ -25,7 +25,6 @@ import { HttpInterceptHaltError } from './http_intercept_halt_error'; import { ExecutionContextContainer, ExecutionContextSetup, - KibanaExecutionContext, } from '../execution_context'; interface Params { From 7c500c7d08297fedf0842dd13534c9a625ae695b Mon Sep 17 00:00:00 2001 From: lizozom Date: Mon, 21 Feb 2022 19:46:46 +0200 Subject: [PATCH 41/57] Give common context to all vis editors --- .../public/embeddable/visualize_embeddable.tsx | 16 +++++++--------- src/plugins/visualizations/public/plugin.ts | 2 ++ src/plugins/visualizations/public/services.ts | 4 ++++ 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx index efc3bbf8314f8a..3d3c98ce4aaeae 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx @@ -39,7 +39,7 @@ import { ExpressionAstExpression, } from '../../../../plugins/expressions/public'; import { Vis, SerializedVis } from '../vis'; -import { getExpressions, getTheme, getUiActions } from '../services'; +import { getExecutionContext, getExpressions, getTheme, getUiActions } from '../services'; import { VIS_EVENT_TO_TRIGGER } from './events'; import { VisualizeEmbeddableFactoryDeps } from './visualize_embeddable_factory'; import { getSavedVisualization } from '../utils/saved_visualize_utils'; @@ -398,20 +398,18 @@ export class VisualizeEmbeddable }; private async updateHandler() { - const parentContext = this.parent?.getInput().executionContext; + const parentContext = this.parent?.getInput().executionContext || getExecutionContext().get(); const child: KibanaExecutionContext = { type: 'visualization', name: this.vis.type.name, - id: this.vis.id ?? 'an_unsaved_vis', + id: this.vis.id ?? 'new', description: this.vis.title || this.input.title || this.vis.type.name, url: this.output.editUrl, }; - const context = parentContext - ? { - ...parentContext, - child, - } - : child; + const context = { + ...parentContext, + child, + }; const expressionParams: IExpressionLoaderParams = { searchContext: { diff --git a/src/plugins/visualizations/public/plugin.ts b/src/plugins/visualizations/public/plugin.ts index c8c4d57543a02c..f448c7f90c0163 100644 --- a/src/plugins/visualizations/public/plugin.ts +++ b/src/plugins/visualizations/public/plugin.ts @@ -36,6 +36,7 @@ import { setDocLinks, setSpaces, setTheme, + setExecutionContext, } from './services'; import { createVisEmbeddableFromObject, @@ -365,6 +366,7 @@ export class VisualizationsPlugin setTimeFilter(data.query.timefilter.timefilter); setAggs(data.search.aggs); setOverlays(core.overlays); + setExecutionContext(core.executionContext); setChrome(core.chrome); if (spaces) { diff --git a/src/plugins/visualizations/public/services.ts b/src/plugins/visualizations/public/services.ts index 37aea45fa3f589..8564c8225f1a79 100644 --- a/src/plugins/visualizations/public/services.ts +++ b/src/plugins/visualizations/public/services.ts @@ -16,6 +16,7 @@ import type { SavedObjectsStart, DocLinksStart, ThemeServiceStart, + ExecutionContextSetup, } from '../../../core/public'; import type { TypesStart } from './vis_types'; import { createGetterSetter } from '../../../plugins/kibana_utils/public'; @@ -65,4 +66,7 @@ export const [getOverlays, setOverlays] = createGetterSetter('Over export const [getChrome, setChrome] = createGetterSetter('Chrome'); +export const [getExecutionContext, setExecutionContext] = + createGetterSetter('ExecutionContext'); + export const [getSpaces, setSpaces] = createGetterSetter('Spaces', false); From 358515d1ad933ab805a0db0bfa9f590fe08f0659 Mon Sep 17 00:00:00 2001 From: lizozom Date: Mon, 21 Feb 2022 19:51:30 +0200 Subject: [PATCH 42/57] fix test --- .../public/search/search_interceptor/search_interceptor.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts b/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts index 95fd6f15af3c35..f1e2e903cadde3 100644 --- a/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts +++ b/src/plugins/data/public/search/search_interceptor/search_interceptor.test.ts @@ -545,7 +545,6 @@ describe('SearchInterceptor', () => { expect(fetchMock.mock.calls[0][0]).toEqual( expect.objectContaining({ options: { - executionContext: {}, sessionId, isStored: true, isRestore: true, From cb939d15e76a47d53541197348d974e2675becd3 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 22 Feb 2022 14:31:44 +0200 Subject: [PATCH 43/57] ts \ es \ tests --- src/core/public/http/fetch.ts | 5 +---- .../fleet/.storybook/context/execution_context.ts | 12 +++++++++--- .../es_geo_grid_source/es_geo_grid_source.test.ts | 15 ++++++++++++++- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/core/public/http/fetch.ts b/src/core/public/http/fetch.ts index abaae54e75851f..9a333161e1b7a5 100644 --- a/src/core/public/http/fetch.ts +++ b/src/core/public/http/fetch.ts @@ -22,10 +22,7 @@ import { HttpFetchError } from './http_fetch_error'; import { HttpInterceptController } from './http_intercept_controller'; import { interceptRequest, interceptResponse } from './intercept'; import { HttpInterceptHaltError } from './http_intercept_halt_error'; -import { - ExecutionContextContainer, - ExecutionContextSetup, -} from '../execution_context'; +import { ExecutionContextContainer, ExecutionContextSetup } from '../execution_context'; interface Params { basePath: IBasePath; diff --git a/x-pack/plugins/fleet/.storybook/context/execution_context.ts b/x-pack/plugins/fleet/.storybook/context/execution_context.ts index 03c2dd0cee3466..d3a15e200129bb 100644 --- a/x-pack/plugins/fleet/.storybook/context/execution_context.ts +++ b/x-pack/plugins/fleet/.storybook/context/execution_context.ts @@ -4,17 +4,23 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { CoreStart } from 'kibana/public'; +import type { ExecutionContextSetup } from 'kibana/public'; import { of } from 'rxjs'; export const getExecutionContext = () => { - const exec: CoreStart['executionContext'] = { + const exec: ExecutionContextSetup = { context$: of({}), - getAll: () => { + get: () => { return {}; }, clear: () => {}, set: (context: Record) => {}, + getAsLabels: () => { + return {}; + }, + withGlobalContext: () => { + return {}; + }, }; return exec; diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts index eb8db6c786e292..fc6a0669742511 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts @@ -5,8 +5,14 @@ * 2.0. */ +import { coreMock } from '../../../../../../../src/core/public/mocks'; import { MapExtent, VectorSourceRequestMeta } from '../../../../common/descriptor_types'; -import { getHttp, getIndexPatternService, getSearchService } from '../../../kibana_services'; +import { + getExecutionContext, + getHttp, + getIndexPatternService, + getSearchService, +} from '../../../kibana_services'; import { ESGeoGridSource } from './es_geo_grid_source'; import { ES_GEO_FIELD_TYPE, @@ -129,6 +135,13 @@ describe('ESGeoGridSource', () => { }, }, }); + + const coreStartMock = coreMock.createStart(); + coreStartMock.executionContext.get.mockReturnValue({ + name: 'some-app', + }); + // @ts-expect-error + getExecutionContext.mockReturnValue(coreStartMock.executionContext); }); afterEach(() => { From 84129cbdd8c03f431f9605d384c53c9e452de566 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 22 Feb 2022 15:51:17 +0200 Subject: [PATCH 44/57] labels --- src/core/public/execution_context/execution_context_service.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/public/execution_context/execution_context_service.ts b/src/core/public/execution_context/execution_context_service.ts index 915bf439f99a3d..237ebdfc1de505 100644 --- a/src/core/public/execution_context/execution_context_service.ts +++ b/src/core/public/execution_context/execution_context_service.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import type { Labels } from 'elastic-apm-node'; import { isEqual, isUndefined, omitBy } from 'lodash'; import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { CoreService, KibanaExecutionContext } from '../../types'; From 984abf3cf6e3ca5c7361abad558d40b813cd6003 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 22 Feb 2022 16:13:21 +0200 Subject: [PATCH 45/57] missing types --- .../public/execution_context/execution_context_service.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/core/public/execution_context/execution_context_service.ts b/src/core/public/execution_context/execution_context_service.ts index 237ebdfc1de505..39b318e23374c7 100644 --- a/src/core/public/execution_context/execution_context_service.ts +++ b/src/core/public/execution_context/execution_context_service.ts @@ -6,11 +6,17 @@ * Side Public License, v 1. */ -import type { Labels } from 'elastic-apm-node'; import { isEqual, isUndefined, omitBy } from 'lodash'; import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { CoreService, KibanaExecutionContext } from '../../types'; +// Should be exported from elastic/apm-rum +export type LabelValue = string | number | boolean; + +export interface Labels { + [key: string]: LabelValue; +} + /** @public */ export interface ExecutionContextSetup { context$: Observable; From 77decb1520966ffbbb833a0edbb4025f2d7f74ff Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 22 Feb 2022 16:32:10 +0200 Subject: [PATCH 46/57] docsy docs --- src/core/public/public.api.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 177e0e92b8620f..2a96baf5123cbe 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -524,7 +524,8 @@ export interface ExecutionContextSetup { context$: Observable; // (undocumented) get(): KibanaExecutionContext; - getAsLabels(): Labels; + // Warning: (ae-forgotten-export) The symbol "Labels" needs to be exported by the entry point index.d.ts + getAsLabels(): Labels_2; // (undocumented) set(c$: KibanaExecutionContext): void; withGlobalContext(context?: KibanaExecutionContext): KibanaExecutionContext; From 2c0efd2afd96d03c5affed5fc50c805c41ba5074 Mon Sep 17 00:00:00 2001 From: lizozom Date: Tue, 22 Feb 2022 18:56:47 +0200 Subject: [PATCH 47/57] cr #3 --- .../public/execution_context/execution_context_service.ts | 7 +++---- .../discover/public/application/doc/single_doc_route.tsx | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/core/public/execution_context/execution_context_service.ts b/src/core/public/execution_context/execution_context_service.ts index 39b318e23374c7..14ae69a53e5e88 100644 --- a/src/core/public/execution_context/execution_context_service.ts +++ b/src/core/public/execution_context/execution_context_service.ts @@ -71,12 +71,11 @@ export class ExecutionContextService return this.context$.value; }, getAsLabels: () => { - const executionContext = this.mergeContext(); return omitBy( { - name: executionContext?.name, - id: executionContext?.id, - page: executionContext?.page, + name: this.appId, + id: this.context$.value?.id, + page: this.context$.value?.page, }, isUndefined ) as Labels; diff --git a/src/plugins/discover/public/application/doc/single_doc_route.tsx b/src/plugins/discover/public/application/doc/single_doc_route.tsx index 89e78db1b96c2a..e2bdc6dc799e6d 100644 --- a/src/plugins/discover/public/application/doc/single_doc_route.tsx +++ b/src/plugins/discover/public/application/doc/single_doc_route.tsx @@ -40,7 +40,7 @@ const SingleDoc = ({ id }: SingleDocRouteProps) => { useExecutionContext(core.executionContext, { type: 'application', page: 'single-doc', - id: indexPatternId || '', + id: indexPatternId, }); useEffect(() => { From 8a420c504ff7edbcc7b96a6804f411d6a41a9464 Mon Sep 17 00:00:00 2001 From: lizozom Date: Wed, 23 Feb 2022 10:21:21 +0200 Subject: [PATCH 48/57] improve jest --- src/core/public/http/fetch.test.ts | 40 ++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/src/core/public/http/fetch.test.ts b/src/core/public/http/fetch.test.ts index ad8364b5649683..0691e2443c17f5 100644 --- a/src/core/public/http/fetch.test.ts +++ b/src/core/public/http/fetch.test.ts @@ -24,10 +24,11 @@ function delay(duration: number) { const BASE_PATH = 'http://localhost/myBase'; describe('Fetch', () => { + const executionContextMock = executionContextServiceMock.createSetupContract(); const fetchInstance = new Fetch({ basePath: new BasePath(BASE_PATH), kibanaVersion: 'VERSION', - executionContext: executionContextServiceMock.createSetupContract(), + executionContext: executionContextMock, }); afterEach(() => { fetchMock.restore(); @@ -232,13 +233,15 @@ describe('Fetch', () => { it('should inject context headers if provided', async () => { fetchMock.get('*', {}); + const context = { + type: 'test-type', + name: 'test-name', + description: 'test-description', + id: '42', + }; + executionContextMock.withGlobalContext.mockReturnValue(context); await fetchInstance.fetch('/my/path', { - context: { - type: 'test-type', - name: 'test-name', - description: 'test-description', - id: '42', - }, + context, }); expect(fetchMock.lastOptions()!.headers).toMatchObject({ @@ -247,6 +250,29 @@ describe('Fetch', () => { }); }); + it('should include top level context context headers if provided', async () => { + fetchMock.get('*', {}); + + const context = { + type: 'test-type', + name: 'test-name', + description: 'test-description', + id: '42', + }; + executionContextMock.withGlobalContext.mockReturnValue({ + ...context, + name: 'banana', + }); + await fetchInstance.fetch('/my/path', { + context, + }); + + expect(fetchMock.lastOptions()!.headers).toMatchObject({ + 'x-kbn-context': + '%7B%22type%22%3A%22test-type%22%2C%22name%22%3A%22banana%22%2C%22description%22%3A%22test-description%22%2C%22id%22%3A%2242%22%7D', + }); + }); + it('should return response', async () => { fetchMock.get('*', { foo: 'bar' }); const json = await fetchInstance.fetch('/my/path'); From 5dad2dc8522d4c8e2a01576b5f9e59c32e1cedfe Mon Sep 17 00:00:00 2001 From: lizozom Date: Wed, 23 Feb 2022 14:27:41 +0200 Subject: [PATCH 49/57] Use editor name --- .../components/visualize_editor.tsx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx index c9e2c418488abb..af43ef13f0cd08 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx @@ -33,12 +33,6 @@ export const VisualizeEditor = ({ onAppLeave }: VisualizeAppProps) => { const [eventEmitter] = useState(new EventEmitter()); const [hasUnsavedChanges, setHasUnsavedChanges] = useState(!visualizationIdFromUrl); - useExecutionContext(services.executionContext, { - type: 'application', - page: 'editor', - id: visualizationIdFromUrl, - }); - const isChromeVisible = useChromeVisibility(services.chrome); const { savedVisInstance, visEditorRef, visEditorController } = useSavedVisInstance( services, @@ -47,6 +41,16 @@ export const VisualizeEditor = ({ onAppLeave }: VisualizeAppProps) => { originatingApp, visualizationIdFromUrl ); + + const editorName = savedVisInstance + ? savedVisInstance.vis.type.title.toLowerCase().replace(' ', '_') + : ''; + useExecutionContext(services.executionContext, { + type: 'application', + page: `editor${editorName ? `:${editorName}` : ''}`, + id: visualizationIdFromUrl || 'new', + }); + const { appState, hasUnappliedChanges } = useVisualizeAppState( services, eventEmitter, From 4facdf1bc0c20a7787587f13b6ff21e49d749352 Mon Sep 17 00:00:00 2001 From: Liza Katz Date: Wed, 23 Feb 2022 16:52:31 +0200 Subject: [PATCH 50/57] Update src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx Co-authored-by: Marco Liberati --- .../public/visualize_app/components/visualize_editor.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx index af43ef13f0cd08..c281b211768a10 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_editor.tsx @@ -42,9 +42,7 @@ export const VisualizeEditor = ({ onAppLeave }: VisualizeAppProps) => { visualizationIdFromUrl ); - const editorName = savedVisInstance - ? savedVisInstance.vis.type.title.toLowerCase().replace(' ', '_') - : ''; + const editorName = savedVisInstance?.vis.type.title.toLowerCase().replace(' ', '_') || ''; useExecutionContext(services.executionContext, { type: 'application', page: `editor${editorName ? `:${editorName}` : ''}`, From f0948030cb73105d620603dc9caef001068f13bd Mon Sep 17 00:00:00 2001 From: lizozom Date: Thu, 24 Feb 2022 14:04:14 +0200 Subject: [PATCH 51/57] fix maps context --- .../execution_context_service.ts | 19 ++++++++++--------- .../plugins/maps/common/execution_context.ts | 18 ++++++++++-------- x-pack/plugins/maps/public/util.ts | 15 +++++++++------ .../plugins/maps/server/mvt/get_grid_tile.ts | 5 ++++- x-pack/plugins/maps/server/mvt/get_tile.ts | 5 ++++- 5 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/core/public/execution_context/execution_context_service.ts b/src/core/public/execution_context/execution_context_service.ts index 14ae69a53e5e88..d080c09a6de5b3 100644 --- a/src/core/public/execution_context/execution_context_service.ts +++ b/src/core/public/execution_context/execution_context_service.ts @@ -68,17 +68,14 @@ export class ExecutionContextService } }, get: () => { - return this.context$.value; + return this.mergeContext(); }, getAsLabels: () => { - return omitBy( - { - name: this.appId, - id: this.context$.value?.id, - page: this.context$.value?.page, - }, - isUndefined - ) as Labels; + return this.removeUndefined({ + name: this.appId, + id: this.context$.value?.id, + page: this.context$.value?.page, + }) as Labels; }, withGlobalContext: (context: KibanaExecutionContext) => { return this.mergeContext(context); @@ -106,6 +103,10 @@ export class ExecutionContextService this.subscription.unsubscribe(); } + private removeUndefined(context: KibanaExecutionContext = {}) { + return omitBy(context, isUndefined); + } + private mergeContext(context: KibanaExecutionContext = {}): KibanaExecutionContext { return { name: this.appId, diff --git a/x-pack/plugins/maps/common/execution_context.ts b/x-pack/plugins/maps/common/execution_context.ts index 23de29cfa8cd7d..4a11eb5d890295 100644 --- a/x-pack/plugins/maps/common/execution_context.ts +++ b/x-pack/plugins/maps/common/execution_context.ts @@ -5,14 +5,16 @@ * 2.0. */ +import { isUndefined, omitBy } from 'lodash'; import { APP_ID } from './constants'; -export function makeExecutionContext(id: string, url: string, description?: string) { - return { - name: APP_ID, - type: 'application', - id, - description: description || '', - url, - }; +export function makeExecutionContext(context: { id?: string; url?: string; description?: string }) { + return omitBy( + { + name: APP_ID, + type: 'application', + ...context, + }, + isUndefined + ); } diff --git a/x-pack/plugins/maps/public/util.ts b/x-pack/plugins/maps/public/util.ts index ac0136b48a8b49..f0fc30270add7e 100644 --- a/x-pack/plugins/maps/public/util.ts +++ b/x-pack/plugins/maps/public/util.ts @@ -73,12 +73,12 @@ export function isRetina(): boolean { return window.devicePixelRatio === 2; } -export function makePublicExecutionContext( - id: string, - description?: string -): KibanaExecutionContext { +export function makePublicExecutionContext(description: string): KibanaExecutionContext { const topLevelContext = getExecutionContext().get(); - const context = makeExecutionContext(id, window.location.pathname, description); + const context = makeExecutionContext({ + url: window.location.pathname, + description, + }); // Distinguish between running in maps app vs. embedded return topLevelContext.name !== context.name @@ -86,5 +86,8 @@ export function makePublicExecutionContext( ...topLevelContext, child: context, } - : context; + : { + ...topLevelContext, + ...context, + }; } diff --git a/x-pack/plugins/maps/server/mvt/get_grid_tile.ts b/x-pack/plugins/maps/server/mvt/get_grid_tile.ts index 193a3d74e2dca2..28effa5eabfba8 100644 --- a/x-pack/plugins/maps/server/mvt/get_grid_tile.ts +++ b/x-pack/plugins/maps/server/mvt/get_grid_tile.ts @@ -56,7 +56,10 @@ export async function getEsGridTile({ }; const tile = await core.executionContext.withContext( - makeExecutionContext('mvt:get_grid_tile', url), + makeExecutionContext({ + description: 'mvt:get_grid_tile', + url, + }), async () => { return await context.core.elasticsearch.client.asCurrentUser.transport.request( { diff --git a/x-pack/plugins/maps/server/mvt/get_tile.ts b/x-pack/plugins/maps/server/mvt/get_tile.ts index 2c8b6dd4b113d6..7e9bc01c5c317c 100644 --- a/x-pack/plugins/maps/server/mvt/get_tile.ts +++ b/x-pack/plugins/maps/server/mvt/get_tile.ts @@ -57,7 +57,10 @@ export async function getEsTile({ }; const tile = await core.executionContext.withContext( - makeExecutionContext('mvt:get_tile', url), + makeExecutionContext({ + description: 'mvt:get_tile', + url, + }), async () => { return await context.core.elasticsearch.client.asCurrentUser.transport.request( { From b0e216d2d64d5d5ba01c28f6e7630e9bee5961dc Mon Sep 17 00:00:00 2001 From: lizozom Date: Thu, 24 Feb 2022 15:41:36 +0200 Subject: [PATCH 52/57] jest tests for maps --- .../maps/common/execution_context.test.ts | 36 +++++++++++++ x-pack/plugins/maps/public/util.test.js | 54 ++++++++++++++++++- x-pack/plugins/maps/public/util.ts | 2 +- 3 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 x-pack/plugins/maps/common/execution_context.test.ts diff --git a/x-pack/plugins/maps/common/execution_context.test.ts b/x-pack/plugins/maps/common/execution_context.test.ts new file mode 100644 index 00000000000000..d50e572ca1e11e --- /dev/null +++ b/x-pack/plugins/maps/common/execution_context.test.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { makeExecutionContext } from './execution_context'; + +describe('makeExecutionContext', () => { + test('returns basic fields if nothing is provided', () => { + const context = makeExecutionContext({}); + expect(context).toStrictEqual({ + name: 'maps', + type: 'application', + }); + }); + + test('merges in context', () => { + const context = makeExecutionContext({ id: '123' }); + expect(context).toStrictEqual({ + name: 'maps', + type: 'application', + id: '123', + }); + }); + + test('ommits undefined values', () => { + const context = makeExecutionContext({ id: '123', description: undefined }); + expect(context).toStrictEqual({ + name: 'maps', + type: 'application', + id: '123', + }); + }); +}); diff --git a/x-pack/plugins/maps/public/util.test.js b/x-pack/plugins/maps/public/util.test.js index d8861063fc637c..7fc88578b378ae 100644 --- a/x-pack/plugins/maps/public/util.test.js +++ b/x-pack/plugins/maps/public/util.test.js @@ -5,7 +5,7 @@ * 2.0. */ -import { getGlyphUrl } from './util'; +import { getGlyphUrl, makePublicExecutionContext } from './util'; const MOCK_EMS_SETTINGS = { isEMSEnabled: () => true, @@ -62,3 +62,55 @@ describe('getGlyphUrl', () => { }); }); }); + +describe('makePublicExecutionContext', () => { + let injectedContext = {}; + beforeAll(() => { + require('./kibana_services').getExecutionContext = () => ({ + get: () => injectedContext, + }); + }); + + test('creates basic context when no top level context is provided', () => { + const context = makePublicExecutionContext('test'); + expect(context).toStrictEqual({ + description: 'test', + name: 'maps', + type: 'application', + url: '/', + }); + }); + + test('merges with top level context if its from the same app', () => { + injectedContext = { + name: 'maps', + id: '1234', + }; + const context = makePublicExecutionContext('test'); + expect(context).toStrictEqual({ + description: 'test', + name: 'maps', + type: 'application', + url: '/', + id: '1234', + }); + }); + + test('nests inside top level context if its from a different app', () => { + injectedContext = { + name: 'other-app', + id: '1234', + }; + const context = makePublicExecutionContext('test'); + expect(context).toStrictEqual({ + name: 'other-app', + id: '1234', + child: { + description: 'test', + type: 'application', + name: 'maps', + url: '/', + }, + }); + }); +}); diff --git a/x-pack/plugins/maps/public/util.ts b/x-pack/plugins/maps/public/util.ts index f0fc30270add7e..66244ea5f67685 100644 --- a/x-pack/plugins/maps/public/util.ts +++ b/x-pack/plugins/maps/public/util.ts @@ -81,7 +81,7 @@ export function makePublicExecutionContext(description: string): KibanaExecution }); // Distinguish between running in maps app vs. embedded - return topLevelContext.name !== context.name + return topLevelContext.name !== undefined && topLevelContext.name !== context.name ? { ...topLevelContext, child: context, From c10afe864860f98023acd937e01170ffc2ab98e0 Mon Sep 17 00:00:00 2001 From: lizozom Date: Thu, 24 Feb 2022 15:56:18 +0200 Subject: [PATCH 53/57] cr --- src/core/public/apm_system.ts | 5 ++++- .../execution_context/execution_context_service.ts | 14 +++++++++++++- src/plugins/dev_tools/public/application.tsx | 4 ++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/core/public/apm_system.ts b/src/core/public/apm_system.ts index a2fcdb45119e93..4e116c0a0182dd 100644 --- a/src/core/public/apm_system.ts +++ b/src/core/public/apm_system.ts @@ -83,7 +83,10 @@ export class ApmSystem { start.application.currentAppId$.subscribe((appId) => { if (appId && this.apm) { this.closePageLoadTransaction(); - this.apm.startTransaction(appId, 'app-change'); + this.apm.startTransaction(appId, 'app-change', { + managed: true, + canReuse: true, + }); } }); } diff --git a/src/core/public/execution_context/execution_context_service.ts b/src/core/public/execution_context/execution_context_service.ts index d080c09a6de5b3..2dea03e2374cab 100644 --- a/src/core/public/execution_context/execution_context_service.ts +++ b/src/core/public/execution_context/execution_context_service.ts @@ -19,16 +19,28 @@ export interface Labels { /** @public */ export interface ExecutionContextSetup { + /** + * The current context observable + **/ context$: Observable; + /** + * Set the current top level context + **/ set(c$: KibanaExecutionContext): void; + /** + * Get the current top level context + **/ get(): KibanaExecutionContext; + /** + * clears the context + **/ clear(): void; /** * returns apm labels **/ getAsLabels(): Labels; /** - * merges the current global context with the specific event context + * merges the current top level context with the specific event context **/ withGlobalContext(context?: KibanaExecutionContext): KibanaExecutionContext; } diff --git a/src/plugins/dev_tools/public/application.tsx b/src/plugins/dev_tools/public/application.tsx index 49aeb03de5c578..bcfde68abd99c1 100644 --- a/src/plugins/dev_tools/public/application.tsx +++ b/src/plugins/dev_tools/public/application.tsx @@ -20,7 +20,7 @@ import type { ChromeStart, ScopedHistory, CoreTheme, - CoreStart, + ExecutionContextStart, } from 'src/core/public'; import { KibanaThemeProvider, useExecutionContext } from '../../kibana_react/public'; import type { DocTitleService, BreadcrumbService } from './services'; @@ -30,7 +30,7 @@ import { DevToolApp } from './dev_tool'; export interface AppServices { docTitleService: DocTitleService; breadcrumbService: BreadcrumbService; - executionContext: CoreStart['executionContext']; + executionContext: ExecutionContextStart; } interface DevToolsWrapperProps { From 4a96dac79def2e0a307afec4832075b2928e0504 Mon Sep 17 00:00:00 2001 From: lizozom Date: Thu, 24 Feb 2022 16:24:05 +0200 Subject: [PATCH 54/57] docs --- ...a-plugin-core-public.executioncontextsetup.clear.md | 2 ++ ...lugin-core-public.executioncontextsetup.context_.md | 2 ++ ...ana-plugin-core-public.executioncontextsetup.get.md | 2 ++ .../kibana-plugin-core-public.executioncontextsetup.md | 10 +++++----- ...ana-plugin-core-public.executioncontextsetup.set.md | 2 ++ ...e-public.executioncontextsetup.withglobalcontext.md | 2 +- src/core/public/public.api.md | 4 ---- 7 files changed, 14 insertions(+), 10 deletions(-) diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.clear.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.clear.md index 9e9958dd2bd75f..94936b94d0710b 100644 --- a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.clear.md +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.clear.md @@ -4,6 +4,8 @@ ## ExecutionContextSetup.clear() method +clears the context + Signature: ```typescript diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.context_.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.context_.md index 1ec926f28ea508..d6c74db6d603e9 100644 --- a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.context_.md +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.context_.md @@ -4,6 +4,8 @@ ## ExecutionContextSetup.context$ property +The current context observable + Signature: ```typescript diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.get.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.get.md index 6c778142c8500e..65e9b1218649d2 100644 --- a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.get.md +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.get.md @@ -4,6 +4,8 @@ ## ExecutionContextSetup.get() method +Get the current top level context + Signature: ```typescript diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.md index d67ce2b7091ccd..de800496605a90 100644 --- a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.md +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.md @@ -15,15 +15,15 @@ export interface ExecutionContextSetup | Property | Type | Description | | --- | --- | --- | -| [context$](./kibana-plugin-core-public.executioncontextsetup.context_.md) | Observable<KibanaExecutionContext> | | +| [context$](./kibana-plugin-core-public.executioncontextsetup.context_.md) | Observable<KibanaExecutionContext> | The current context observable | ## Methods | Method | Description | | --- | --- | -| [clear()](./kibana-plugin-core-public.executioncontextsetup.clear.md) | | -| [get()](./kibana-plugin-core-public.executioncontextsetup.get.md) | | +| [clear()](./kibana-plugin-core-public.executioncontextsetup.clear.md) | clears the context | +| [get()](./kibana-plugin-core-public.executioncontextsetup.get.md) | Get the current top level context | | [getAsLabels()](./kibana-plugin-core-public.executioncontextsetup.getaslabels.md) | returns apm labels | -| [set(c$)](./kibana-plugin-core-public.executioncontextsetup.set.md) | | -| [withGlobalContext(context)](./kibana-plugin-core-public.executioncontextsetup.withglobalcontext.md) | merges the current global context with the specific event context | +| [set(c$)](./kibana-plugin-core-public.executioncontextsetup.set.md) | Set the current top level context | +| [withGlobalContext(context)](./kibana-plugin-core-public.executioncontextsetup.withglobalcontext.md) | merges the current top level context with the specific event context | diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.set.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.set.md index c0fb2cdd60258b..e3dcea78c827ab 100644 --- a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.set.md +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.set.md @@ -4,6 +4,8 @@ ## ExecutionContextSetup.set() method +Set the current top level context + Signature: ```typescript diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.withglobalcontext.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.withglobalcontext.md index a4e412a5133b85..574d0fd989750f 100644 --- a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.withglobalcontext.md +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.withglobalcontext.md @@ -4,7 +4,7 @@ ## ExecutionContextSetup.withGlobalContext() method -merges the current global context with the specific event context +merges the current top level context with the specific event context Signature: diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 2a96baf5123cbe..4d1fc00dd179d1 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -518,15 +518,11 @@ export interface ErrorToastOptions extends ToastOptions { // @public (undocumented) export interface ExecutionContextSetup { - // (undocumented) clear(): void; - // (undocumented) context$: Observable; - // (undocumented) get(): KibanaExecutionContext; // Warning: (ae-forgotten-export) The symbol "Labels" needs to be exported by the entry point index.d.ts getAsLabels(): Labels_2; - // (undocumented) set(c$: KibanaExecutionContext): void; withGlobalContext(context?: KibanaExecutionContext): KibanaExecutionContext; } From a78a4b8d6b193f64847e08a4e1ee19208da2cce8 Mon Sep 17 00:00:00 2001 From: Liza Katz Date: Thu, 24 Feb 2022 16:28:18 +0200 Subject: [PATCH 55/57] Update execution_context.test.ts --- x-pack/plugins/maps/common/execution_context.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/maps/common/execution_context.test.ts b/x-pack/plugins/maps/common/execution_context.test.ts index d50e572ca1e11e..25e3813a7e8f01 100644 --- a/x-pack/plugins/maps/common/execution_context.test.ts +++ b/x-pack/plugins/maps/common/execution_context.test.ts @@ -25,7 +25,7 @@ describe('makeExecutionContext', () => { }); }); - test('ommits undefined values', () => { + test('omits undefined values', () => { const context = makeExecutionContext({ id: '123', description: undefined }); expect(context).toStrictEqual({ name: 'maps', From 4dbc83e083622efc06adbef9ca18f763d85a0088 Mon Sep 17 00:00:00 2001 From: lizozom Date: Thu, 24 Feb 2022 16:37:55 +0200 Subject: [PATCH 56/57] docs --- .../kibana-plugin-core-public.executioncontextsetup.md | 1 + docs/development/core/public/kibana-plugin-core-public.md | 2 +- .../public/execution_context/execution_context_service.ts | 6 +++++- src/core/public/public.api.md | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.md b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.md index de800496605a90..01581d2e80a5c9 100644 --- a/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.md +++ b/docs/development/core/public/kibana-plugin-core-public.executioncontextsetup.md @@ -4,6 +4,7 @@ ## ExecutionContextSetup interface +Kibana execution context. Used to provide execution context to Elasticsearch, reporting, performance monitoring, etc. Signature: diff --git a/docs/development/core/public/kibana-plugin-core-public.md b/docs/development/core/public/kibana-plugin-core-public.md index 407f80c5502040..fca697144a8723 100644 --- a/docs/development/core/public/kibana-plugin-core-public.md +++ b/docs/development/core/public/kibana-plugin-core-public.md @@ -62,7 +62,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [DeprecationsServiceStart](./kibana-plugin-core-public.deprecationsservicestart.md) | DeprecationsService provides methods to fetch domain deprecation details from the Kibana server. | | [DocLinksStart](./kibana-plugin-core-public.doclinksstart.md) | | | [ErrorToastOptions](./kibana-plugin-core-public.errortoastoptions.md) | Options available for [IToasts](./kibana-plugin-core-public.itoasts.md) error APIs. | -| [ExecutionContextSetup](./kibana-plugin-core-public.executioncontextsetup.md) | | +| [ExecutionContextSetup](./kibana-plugin-core-public.executioncontextsetup.md) | Kibana execution context. Used to provide execution context to Elasticsearch, reporting, performance monitoring, etc. | | [FatalErrorInfo](./kibana-plugin-core-public.fatalerrorinfo.md) | Represents the message and stack of a fatal Error | | [FatalErrorsSetup](./kibana-plugin-core-public.fatalerrorssetup.md) | FatalErrors stop the Kibana Public Core and displays a fatal error screen with details about the Kibana build and the error. | | [HttpFetchOptions](./kibana-plugin-core-public.httpfetchoptions.md) | All options that may be used with a [HttpHandler](./kibana-plugin-core-public.httphandler.md). | diff --git a/src/core/public/execution_context/execution_context_service.ts b/src/core/public/execution_context/execution_context_service.ts index 2dea03e2374cab..6cad249eaf7d44 100644 --- a/src/core/public/execution_context/execution_context_service.ts +++ b/src/core/public/execution_context/execution_context_service.ts @@ -17,7 +17,11 @@ export interface Labels { [key: string]: LabelValue; } -/** @public */ +/** + * Kibana execution context. + * Used to provide execution context to Elasticsearch, reporting, performance monitoring, etc. + * @public + **/ export interface ExecutionContextSetup { /** * The current context observable diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 4d1fc00dd179d1..e3f2822b5a7c8d 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -516,7 +516,7 @@ export interface ErrorToastOptions extends ToastOptions { toastMessage?: string; } -// @public (undocumented) +// @public export interface ExecutionContextSetup { clear(): void; context$: Observable; From a57bed7bc6f4fe13500c2c38905e2c13b990950e Mon Sep 17 00:00:00 2001 From: lizozom Date: Sun, 27 Feb 2022 09:54:38 +0200 Subject: [PATCH 57/57] lint --- .../public/execution_context/execution_context_service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/public/execution_context/execution_context_service.ts b/src/core/public/execution_context/execution_context_service.ts index 6cad249eaf7d44..bf13a7351f9b5f 100644 --- a/src/core/public/execution_context/execution_context_service.ts +++ b/src/core/public/execution_context/execution_context_service.ts @@ -17,10 +17,10 @@ export interface Labels { [key: string]: LabelValue; } -/** +/** * Kibana execution context. * Used to provide execution context to Elasticsearch, reporting, performance monitoring, etc. - * @public + * @public **/ export interface ExecutionContextSetup { /**