There are no user-facing breaking changes in 7.7.

    Add addInfo toast to core notifications service

    This Info toast will be used for the async search notifications.

    via #60574

    Goodbye, legacy data plugin

    The legacy data plugin located in src/legacy/core_plugins/data has been removed. This change only affects legacy platform plugins which are either: 1. Importing the public/setup or public/legacy “shim” files from the legacy data plugin to access runtime contracts; or 2. importing static code from inside src/legacy/core_plugins/data; or 3. explicitly using require: ['data'] in the plugin definition.

    For scenario 1 above, you should migrate your plugin to access the services you need from the new platform data plugin. These are accessible in the legacy world by using ui/new_platform:

    For scenario 2, the equivalent static code you’ve been importing should now be available from src/plugins/data, in the server or public directories:

    1. - import { someStaticUtilOrType } from 'src/legacy/core_plugins/data/public';
    2. + import { someStaticUtilOrType } from 'src/plugins/data/public';

    For scenario 3, you should be able to safely drop the reference to the plugin, and add data to your list of dependencies in kibana.json whenever your plugin migrates to the new Kibana platform:

    1. // index.ts
    2. const myPluginInitializer: LegacyPluginInitializer = ({ Plugin }: LegacyPluginApi) =>
    3. new Plugin({
    4. id: 'my_plugin',
    5. - require: ['kibana', 'elasticsearch', 'visualizations', 'data'],
    6. + require: ['kibana', 'elasticsearch', 'visualizations'],
    7. ...,
    8. })
    9. );

    For more information on where to locate new platform data services, please refer to the table of plugins for shared application services in src/core/MIGRATION.md.

    via

    Delete FilterStateManager and QueryFilter

    Delete unused legacy exports FilterStateManager, QueryFilter, and SavedQuery.

    via

    Add UiSettings validation & Kibana default route redirection

    UiSettings definition allows to specify validation functions:

    1. import { schema } from '@kbn/config-schema';
    2. uiSettings.register({
    3. myUiSetting: {
    4. name: ...
    5. value: 'value',
    6. schema: schema.string()
    7. }
    8. })

    via

    Allow disabling xsrf protection per an endpoint

    Route configuration allows to disable xsrf protection for destructive HTTP methods:

    1. routet.get({ path: ..., validate: ..., options: { xsrfRequired: false } })

    via

    Add core metrics service

    A new metrics API is available from core, which allows retrieving various metrics regarding the HTTP server, process, and OS load/usages.

    1. core.metrics.getOpsMetrics$().subscribe(metrics => {
    2. // do something with the metrics
    3. })

    via

    Add an optional authentication mode for HTTP resources

    A route config accepts authRequired: 'optional'. A user can access a resource if has valid credentials or no credentials at all. Can be useful when we grant access to a resource but want to identify a user if possible.

    1. router.get( { path: '/', options: { authRequired: 'optional' } }, handler);

    via

    Migrate doc view part of discover

    The extension point for registering custom doc views was migrateed and can be used directly within the new platform.

    A working example of the new integration can be seen in test/plugin_functional/plugins/doc_views_plugin/public/plugin.tsx.

    To register doc views, list discover as a required dependency of your plugin and use the docViews.addDocView method exposed in the setup contract:

    1. export class MyPlugin implements Plugin<void, void> {
    2. public setup(core: CoreSetup, { discover }: { discover: DiscoverSetup }) {
    3. discover.docViews.addDocView({
    4. component: props => {
    5. return /* ... */;
    6. },
    7. order: 2,
    8. title: 'My custom doc view',
    9. });
    10. }
    11. /* ... */
    12. }

    via

    [Telemetry] Server backpressure mechanism

    Add a backpressure mechanism for sending telemetry on the server. Usage data will always be sent from the browser even if we are also sending it from the server. Server side Telemetry usage data sender will send an OPTIONS request before `POST`ing the data to our cluster to ensure the endpoint is reachable.

    Fallback mechanism

    1. Always send usage from browser regardless of the telemetry.sendUsageFrom kibana config.

    Server usage backpressure

    1. Send usage from server in addition to browser if telemetry.sendUsageFrom is set to server.
    2. Initial server usage attempt is after 5 minutes from starting kibana. Attempt to send every 12 hours afterwards.
    3. Restart attempt count after each kibana version upgrade (patch/minor/major).
    4. Restart attempt count if it succeeds in any of the 3 tries.

    Sending usage mechanism from server:

    Send OPTIONS request before attempting to send telemetry from server. OPTIONS is less intrusive as it does not contain any payload and is used to check if the endpoint is reachable. We can also use it in the future to check for allowed headers to use etc.

    • If OPTIONS request succeed; send usage via POST.
    • If OPTIONS request fails; dont send usage and follow the retry logic above.

    via

    Expressions server-side

    It is now possible to register expression functions and types on the Kibana server and execute expressions on the server. The API is the same as in the browser-side plugin, e.g:

    1. plugins.expressions.registerFunction(/* ... */);
    2. const result = await plugins.expressions.run('var_set name="foo" value="bar" | var name="foo"', null);

    via

    Local actions

    actionIds property has been removed from`Trigger` interface in ui_actions plugin. Use attachAction() method instead, for example:

    1. plugins.uiActions.attachAction(triggerId, actionId);

    Instead of previously:

    1. const trigger = {
    2. id: triggerId,
    3. actionIds: [actionId],
    4. };

    via

    Use log4j pattern syntax

    Logging output of the New platform plugins can use adjusted via .

    via #57433

    Allow savedObjects types registration from NP

    A new registerType API has been added to the core savedObjects setup API, allowing to register savedObject types from new platform plugins

    Please check the migration guide for more complete examples and migration procedure.

    via #57430

    Expose Vis on the contract as it requires visTypes

    In most of the places Vis used as a type, but in couple places it is used as a class. At the moment Vis as a class is not stateless, as it depends on visTypes. As it is not stateless, Vis class was removed from public exports and exposed on visualisations contract instead:

    1. new visualizationsStart.Vis(....);

    Vis as interface still can be imported as:

    1. import { Vis } from '../../../../../core_plugins/visualizations/public';

    via #56968

    Add ScopedHistory to AppMountParams

    Kibana Platform applications should use the provided history instance to integrate routing rather than setting up their own using appBasePath (which is now deprecated).

    Before

    1. core.application.register({
    2. id: 'myApp',
    3. mount({ appBasePath, element }) {
    4. ReactDOM.render(
    5. <BrowserRouter basename={appBasePath}>
    6. <App />
    7. </BrowserRouter>,
    8. element
    9. );
    10. return () => ReactDOM.unmountComponentAtNode(element);
    11. }
    12. });

    After

    1. core.application.register({
    2. id: 'myApp',
    3. mount({ element, history }) {
    4. ReactDOM.render(
    5. <BrowserRouter history={history}>
    6. <App />
    7. </BrowserRouter>,
    8. element
    9. );
    10. return () => ReactDOM.unmountComponentAtNode(element);
    11. }
    12. });

    via #56705

    Move new_vis_modal to visualizations plugin

    NewVisModal component and showNewVisModal function were statically exported and received all the dependencies as props/parameters.

    After

    showNewVisModal() is part of the plugin contract and plugin dependencies are provided implicitly.

    1. npStart.plugins.visualizations.showNewVisModal();

    via #56654

    UiComponent

    UiComponent interface was added to plugin. UiComponent represents a user interface building block, like a React component, but UiComponent does not have to be implemented in React—it can be implemented in plain JS or React, or Angular, etc.

    In many places in Kibana we want to be agnostic to frontend view library, i.e. instead of exposing React-specific APIs we want to expose APIs that are orthogonal to any rendering library. UiComponent interface represents such UI components. UI component receives a DOM element and props through render() method, the render() method can be called many times.

    1. export type UiComponent<Props extends object = object> = () => {
    2. render(el: HTMLElement, props: Props): void;
    3. unmount?(): void;
    4. };

    Although Kibana aims to be library agnostic, Kibana itself is written in React, therefore UiComponent is designed such that it maps directly to a functional React component: UiCompnent interface corresponds to React.ComponentType type and UiCompnent props map to React component props.

    To help use UiComponent interface in the codebase uiToReactComponent and reactToUiComponent helper functions were added to kibana_react plugin, they transform a UiComponent into a React component and vice versa, respectively.

    1. const uiToReactComponent: (comp: UiComponent) => React.ComponentType;
    2. const reactToUiComponent: (comp: React.ComponentType) => UiComponent;

    via #56555

    Start consuming np logging config

    Provides experimental support of new logging format for new platform plugins. More about the logging format.

    via

    [State Management] State syncing utils docs

    Refer to on state syncing utils.

    via #56479

    [NP] Move saved object modal into new platform

    SavedObjectSaveModal, showSaveModal and SaveResult from `ui/saved_objects`, and SavedObjectFinderUi, SavedObjectMetaData and OnSaveProps from `src/plugins/kibana_react/public` were moved to a new plugin src/plugins/saved_objects.

    Also now showSaveModal requires the second argument - I18nContext:

    1. import { showSaveModal } from 'src/plugins/saved_objects/public';
    2. ...
    3. showSaveModal(saveModal, npStart.core.i18n.Context);

    via #56383

    [State Management] State syncing helpers for query service

    Query service of data plugin now has state$ observable which allows to watch for query service data changes:

    1. interface QueryState {
    2. time?: TimeRange;
    3. refreshInterval?: RefreshInterval;
    4. filters?: Filter[];
    5. }
    6. interface QueryStateChange {
    7. time?: boolean; // time range has changed
    8. refreshInterval?: boolean; // refresh interval has changed
    9. filters?: boolean; // any filter has changed
    10. appFilters?: boolean; // specifies if app filters change
    11. globalFilters?: boolean; // specifies if global filters change
    12. }
    13. state$: Observable<{ changes: QueryStateChange; state: QueryState }>;

    via #56128

    Migrate saved_object_save_as_checkbox directive to Timelion

    Use our React component SavedObjectSaveModal with showCopyOnSave={true} instead of the react directive. Note that SavedObjectSaveModal soon will be part of a new plugin, so the path will change.

    1. import { SavedObjectSaveModal } from 'ui/saved_objects/components/saved_object_save_modal';
    2. <SavedObjectSaveModal
    3. onSave={onSave}
    4. onClose={() => {}}
    5. title={'A title'}
    6. showCopyOnSave={true}
    7. objectType={'The type of you saved object'}
    8. />

    via #56114

    ui/public cleanup

    Removed / moved modules

    In preparation for Kibana’s upcoming new platform, we are in the process of from the ui/public directory. Over time, the contents of this directory will be either deprecated or housed inside a parent plugin. If your plugin imports the listed items from the following ui/public modules, you will need to either update your import statements as indicated below, so that you are pulling these modules from their new locations, or copy the relevant code directly into your plugin.

    ui/agg_types #59605

    The ui/agg_types module has been removed in favor of the service provided by the data plugin in the new Kibana platform.

    Additionally, aggTypes and AggConfigs have been removed in favor of a types registry and a createAggConfigs function:

    The above examples are not comprehensive, but represent some of the more common uses of agg_types. For more details, please refer to the interfaces in , as well as the data plugin’s public/index file.

    ui/time_buckets

    The ui/time_buckets module has been removed and is now internal to the data plugin’s search & aggregations infrastructure. We are working on an improved set of helper utilities to eventually replace the need for the TimeBuckets class.

    In the meantime, if you currently rely on TimeBuckets, please copy the relevant pieces into your plugin code.

    ui/filter_manager #59872

    The ui/filter_manager module has been removed and now services and UI components are available on the data plugin’s query infrastructure.

    via

    Add savedObjects mappings API to core

    Added API to register savedObjects mapping from the new platform.

    1. // my-plugin/server/mappings.ts
    2. import { SavedObjectsTypeMappingDefinitions } from 'src/core/server';
    3. export const mappings: SavedObjectsTypeMappingDefinitions = {
    4. 'my-type': {
    5. properties: {
    6. afield: {
    7. type: "text"
    8. }
    9. }
    10. }
    11. }
    1. // my-plugin/server/plugin.ts
    2. import { mappings } from './mappings';
    3. export class MyPlugin implements Plugin {
    4. setup({ savedObjects }) {
    5. savedObjects.registerMappings(mappings);
    6. }
    7. }

    via

    Remove the VisEditorTypesRegistryProvider

    The VisEditorTypesRegistryProvider is removed. By default, visualizations will use the default editor.

    To specify a custom editor use editor parameter as a key and a class with your own controller as a value in a vis type definition:

    1. {
    2. name: 'my_new_vis',
    3. icon: 'my_icon',
    4. description: 'Cool new chart',
    5. editor: MyEditorController
    6. }

    via

    Explicitly test custom appRoutes

    Tests for custom `appRoute`s are now more clear and explicitly separate from those that test other rendering service interactions.

    via

    [NP] Platform exposes API to get authenticated user data

    HttpService exposes:

    • auth.get() — returns auth status and associated user data. User data are opaque to the http service. Possible auth status values:

      • authenticatedauth interceptor successfully authenticated a user.
      • unauthenticatedauth interceptor failed user authentication.
      • unknownauth interceptor has not been registered.
    • auth.isAuthenticated() - returns true, if auth interceptor successfully authenticated a user.

    via

    Implements getStartServices on server-side

    Adds a new API to be able to access start dependencies when registering handlers in setup phase.

    1. setup(core: CoreSetup, plugins: PluginDeps) {
    2. plugins.usageCollection.registerCollector({
    3. type: 'MY_TYPE',
    4. fetch: async () => {
    5. const [coreStart] = await core.getStartServices();
    6. const internalRepo = coreStart.savedObjects.createInternalRepository();
    7. // ...
    8. },
    9. });
    10. }
    11. start() {}
    12. }

    via

    Expressions refactor

    • context.types > inputTypes
    • Objects should be registered instead of function wrappers around those objects.

    via

    Refactor saved object management registry usage

    • savedSearches
    • savedVisualizations
    • savedDashboard

    The plugins now provide the functions to create a SavedObjectLoader service, here’s an example how the services are created now:

    1. import { createSavedSearchesService } from '../discover';
    2. import { TypesService, createSavedVisLoader } from '../../../visualizations/public';
    3. import { createSavedDashboardLoader } from '../dashboard';
    4. const services = {
    5. savedObjectsClient: npStart.core.savedObjects.client,
    6. indexPatterns: npStart.plugins.data.indexPatterns,
    7. chrome: npStart.core.chrome,
    8. overlays: npStart.core.overlays,
    9. };
    10. const servicesForVisualizations = {
    11. ...services,
    12. ...{ visualizationTypes: new TypesService().start() },
    13. }
    14. const savedSearches = createSavedSearchesService(services);
    15. const savedVisualizations = createSavedVisLoader(servicesForVisualizations);
    16. const savedDashboards = createSavedDashboardLoader(services);

    via

    Enforce camelCase format for a plugin id

    When creating a new platform plugin, you need to make sure that pluginId declared in camelCase within kibana.json manifest file. It might not match pluginPath, which is recommended to be in snake_case format.

    1. // ok
    2. "pluginPath": ["foo"],
    3. "id": "foo"
    4. // ok
    5. "pluginPath": "foo_bar",
    6. "id": "fooBar"

    via

    bfetch (2)

    Request batching and response streaming functionality of legacy Interpreter plugin has been moved out into a separate bfetch Kibana platform plugin. Now every plugin can create server endpoints and browser wrappers that can batch HTTP requests and stream responses back.

    As an example, we will create a batch processing endpoint that receives a number then doubles it and streams it back. We will also consider the number to be time in milliseconds and before streaming the number back the server will wait for the specified number of milliseconds.

    To do that, first create server-side batch processing route using addBatchProcessingRoute.

    1. plugins.bfetch.addBatchProcessingRoute<{ num: number }, { num: number }>(
    2. '/my-plugin/double',
    3. () => ({
    4. onBatchItem: async ({ num }) => {
    5. // Validate inputs.
    6. if (num < 0) throw new Error('Invalid number');
    7. // Wait number of specified milliseconds.
    8. await new Promise(r => setTimeout(r, num));
    9. // Double the number and send it back.
    10. return { num: 2 * num };
    11. },
    12. })
    13. );

    Now on client-side create double function using batchedFunction. The newly created double function can be called many times and it will package individual calls into batches and send them to the server.

    1. const double = plugins.bfetch.batchedFunction<{ num: number }, { num: number }>({
    2. url: '/my-plugin/double',
    3. });

    Note: the created double must accept a single object argument ({ num: number } in this case) and it will return a promise that resolves into an object, too (also { num: number } in this case).

    Use the double function.

    1. double({ num: 1 }).then(console.log, console.error); // { num: 2 }
    2. double({ num: 2 }).then(console.log, console.error); // { num: 4 }
    3. double({ num: 3 }).then(console.log, console.error); // { num: 6 }

    via

    Grouped Kibana nav

    Plugins should now define a category if they have a navigation item:

    • If you want to fit into our default categories, you can use our DEFAULT_APP_CATEGORIES defined in src/core/utils/default_app_categories.ts.
    • If you want to create their own category, you can also provide any object matching the AppCategory interface defined in src/core/types/app_category.ts.

    via

    Expose Elasticsearch from start and deprecate from setup

    Remove any API that could allow access/query to savedObjects from core setup contract, and move them to the start contract instead. Deprecate the CoreSetup.elasticsearch API and expose CoreStart.elasticsearch instead.

    via

    Embeddable triggers

    Embeddables can now report ui_actions triggers that they execute through the .supportedTriggers() method. For example:

    1. class MyEmbeddable extends Embeddable {
    2. supportedTriggers() {
    3. return ['VALUE_CLICK_TRIGGER'];
    4. }
    5. }

    The returned list of triggers will be used in the drilldowns feature on Dashboard, where users will be able to add drilldowns to embeddable triggers.

    via

    Force savedObject API consumers to define SO type explicitly

    The new interface enforces API consumers to specify SO type explicitly. Plugins can use SavedObjectAttributes to ensure their type are serializable, but it shouldn’t be used as their domain-specific type.

    via

    Trigger context

    Improved types for trigger contexts, which are consumed by actions.

    via

    Expressions debug mode

    Add ability to execute expression in “debug” mode, which would collect execution information about each function. This is used in the Expression Explorer (developed by Canvas) and in Canvas when the expression editor is open.

    via

    Move ui/agg_types in to shim data plugin

    • Moves the contents of ui/agg_types into the legacy shim data plugin
    • Re-exports contracts ui/agg_types for BWC
    • Creates dedicated interfaces for classes commonly being used as types: IAggConfig, IAggConfigs, IAggType, IFieldParamType, IMetricAggType

      • Right now these are just re-exporting the class as a type; eventually we should put more detailed typings in place.

    via

    Stateful search bar default behaviors

    The goal of the stateful version of SearchBar / TopNavMenu is to be an easy way to consume the services offered by plugins.data.query where developers should be able to provide minimal configuration and get a fully working SearchBar.

    via

    Guide for creating alert / action types in the UI

    Documentation to help developers integrate their alert / action type within our Management UIs

    via

    Move search service code to NP

    Move all of the search service code to Kibana new platform. Also deletes courier folder and moves getFlattenedObject to src/core/utils.

    via

    Expose NP FieldFormats service to server side

    The fieldFormats service is used on the server side as well. At the moment, it resides in src/legacy/ui/field_formats/mixin/field_formats_service.ts and only the FE plugin exposes it.

    via

    Update plugin generator to generate NP plugins

    Add more options for Kibana new platform plugin generator.

    • Generate FE components
    • Generate server side endpoint
    • Generate SCSS
    • Generate an optional .eslintrc.js file (for 3rd party plugins mostly)
    • Init git repo (for 3rd party plugins)

    via

    Run SO migration after plugins setup phase

    • Moves createScopedRepository and createInternalRepository from setup contract to start contract, and removes getScopedClient from the setup contract. There is no longer a possibility to be performing any call to SO before core’s start is done.
    • Creates the migrator, the repository accessors and runs the SO migration at the start of SavedObjectsService.start(), meaning that any SO call performed is assured to be done after the migration.
    • Changes the setClientFactory API to setClientFactoryProvider to provide a SO repository provider when registering the client factory.
    • Adapts the existing plugin calls to the removed APIs from setup to be now using getStartServices to access them on the core start contract.

    via

    Build immutable bundles for new platform plugins

    Plugins that have been migrated to the “new platform” are built with a new system into their own target/public directory. To build third-party plugin’s with this new system either pass --plugin-path to node scripts/build_new_platform_plugins or use the @kbn/optimizer package in the Kibana repo to build your plugin as described in the readme for that package.

    via

    [Search service] Asynchronous ES search strategy

    Adds an async Elasticsearch search strategy, which utilizes the async search strategy to call the _async_search APIs in Elasticsearch, returning an observable over the responses.

    via

    [Vis: Default editor] EUIficate and Reactify the sidebar

    If you are using the default editor in your VisType visualization definition, remove the editor: 'default' param from it. The default editor controller will be used by default.

    The default editor controller receives an optionsTemplate or optionTabs parameter. These tabs should be React components:

    via

    [test] Consolidate top-level yarn scripts

    Over time Kibana has added a number of testing frameworks, but our top-level scripts have remained the same to avoid workflow changes. The current naming convention with the number of test options can leave room for ambiguity.

    You’ll see two general changes: * docs will refer to the yarn script, giving us an abstraction to migrate frameworks out and avoid workflow interruptions (grunt/gulp -> node scripts/*) * test scripts now refer to the test runner, as opposed to the test type (yarn test:server -> yarn test:mocha)