Skip to content

Commit

Permalink
[SIEM] Move public to new platform (elastic#48840)
Browse files Browse the repository at this point in the history
* shim public new platform

* fix import

* fix ml api with kbn version

* review I

* fix bad coding with the hooks
  • Loading branch information
XavierM committed Oct 22, 2019
1 parent 851f9a1 commit 874f985
Show file tree
Hide file tree
Showing 50 changed files with 679 additions and 490 deletions.
4 changes: 2 additions & 2 deletions x-pack/legacy/plugins/siem/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { defaultIndexPattern } from './default_index_pattern';
import { isAlertExecutor } from './server/lib/detection_engine/alerts/types';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function siem(kibana: any) {
export const siem = (kibana: any) => {
return new kibana.Plugin({
id: APP_ID,
configPrefix: 'xpack.siem',
Expand Down Expand Up @@ -138,4 +138,4 @@ export function siem(kibana: any) {
initServerWithKibana(server);
},
});
}
};
2 changes: 1 addition & 1 deletion x-pack/legacy/plugins/siem/public/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
* you may not use this file except in compliance with the Elastic License.
*/

import './apps/kibana_app';
import './apps/index';
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import chrome from 'ui/chrome';
import { SiemRootController } from './start_app';

import 'uiExports/embeddableFactories';
import chrome from 'ui/chrome';
import { npStart } from 'ui/new_platform';
import { Plugin } from './plugin';

// load the application
chrome.setRootController('siem', SiemRootController);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
new Plugin({ opaqueId: Symbol('siem'), env: {} as any }, chrome).start(npStart);
54 changes: 54 additions & 0 deletions x-pack/legacy/plugins/siem/public/apps/plugin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import React from 'react';
import { render } from 'react-dom';
import { LegacyCoreStart, PluginInitializerContext } from 'src/core/public';
import { PluginsStart } from 'ui/new_platform/new_platform';
import { Chrome } from 'ui/chrome';

import { SiemApp } from './start_app';
import template from './template.html';

export const ROOT_ELEMENT_ID = 'react-siem-root';

export interface StartObject {
core: LegacyCoreStart;
plugins: PluginsStart;
}

export class Plugin {
constructor(
// @ts-ignore this is added to satisfy the New Platform typing constraint,
// but we're not leveraging any of its functionality yet.
private readonly initializerContext: PluginInitializerContext,
private readonly chrome: Chrome
) {
this.chrome = chrome;
}

public start(start: StartObject): void {
const { core, plugins } = start;
// @ts-ignore improper type description
this.chrome.setRootTemplate(template);
const checkForRoot = () => {
return new Promise(resolve => {
const ready = !!document.getElementById(ROOT_ELEMENT_ID);
if (ready) {
resolve();
} else {
setTimeout(() => resolve(checkForRoot()), 10);
}
});
};
checkForRoot().then(() => {
const node = document.getElementById(ROOT_ELEMENT_ID);
if (node) {
render(<SiemApp core={core} plugins={plugins} />, node);
}
});
}
}
31 changes: 13 additions & 18 deletions x-pack/legacy/plugins/siem/public/apps/start_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import { createHashHistory } from 'history';
import React, { memo, FC } from 'react';
import { ApolloProvider } from 'react-apollo';
import { render, unmountComponentAtNode } from 'react-dom';
import { Provider as ReduxStoreProvider } from 'react-redux';
import { ThemeProvider } from 'styled-components';

Expand All @@ -22,13 +21,18 @@ import { DEFAULT_DARK_MODE } from '../../common/constants';
import { ErrorToastDispatcher } from '../components/error_toast_dispatcher';
import { compose } from '../lib/compose/kibana_compose';
import { AppFrontendLibs } from '../lib/lib';
import { KibanaCoreContextProvider } from '../lib/compose/kibana_core';
import { KibanaPluginsContextProvider } from '../lib/compose/kibana_plugins';
import { useKibanaUiSetting } from '../lib/settings/use_kibana_ui_setting';
import { PageRouter } from '../routes';
import { createStore } from '../store/store';
import { GlobalToaster, ManageGlobalToaster } from '../components/toasters';
import { MlCapabilitiesProvider } from '../components/ml/permissions/ml_capabilities_provider';
import { useKibanaUiSetting } from '../lib/settings/use_kibana_ui_setting';

import { ApolloClientContext } from '../utils/apollo_context';

import { StartObject } from './plugin';

const StartApp: FC<AppFrontendLibs> = memo(libs => {
const history = createHashHistory();

Expand Down Expand Up @@ -68,21 +72,12 @@ const StartApp: FC<AppFrontendLibs> = memo(libs => {
return <AppPluginRoot />;
});

const ROOT_ELEMENT_ID = 'react-siem-root';
export const ROOT_ELEMENT_ID = 'react-siem-root';

const App = memo(() => (
<div id={ROOT_ELEMENT_ID}>
<StartApp {...compose()} />
</div>
export const SiemApp = memo<StartObject>(({ core, plugins }) => (
<KibanaCoreContextProvider core={core}>
<KibanaPluginsContextProvider plugins={plugins}>
<StartApp {...compose()} />
</KibanaPluginsContextProvider>
</KibanaCoreContextProvider>
));

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const SiemRootController = ($scope: any, $element: any) => {
const domNode: Element = $element[0];

render(<App />, domNode);

$scope.$on('$destroy', () => {
unmountComponentAtNode(domNode);
});
};
1 change: 1 addition & 0 deletions x-pack/legacy/plugins/siem/public/apps/template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div id="react-siem-root"></div>
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,27 @@ import toJson from 'enzyme-to-json';
import * as React from 'react';
import { EmbeddedMap } from './embedded_map';
import { SetQuery } from './types';
import { useKibanaCore } from '../../lib/compose/kibana_core';

jest.mock('../search_bar', () => ({
siemFilterManager: {
addFilters: jest.fn(),
},
}));

jest.mock('ui/new_platform', () => ({
npStart: {
core: {
injectedMetadata: {
getKibanaVersion: () => '8.0.0',
},
},
plugins: {
uiActions: require('../../../../../../../src/plugins/ui_actions/public/mocks').uiActionsPluginMock.createSetupContract(),
},
const mockUseKibanaCore = useKibanaCore as jest.Mock;
jest.mock('../../lib/compose/kibana_core');
mockUseKibanaCore.mockImplementation(() => ({
uiSettings: {
get$: () => 'world',
},
npSetup: {
core: {
uiSettings: {
get$: () => 'world',
},
},
plugins: {
uiActions: require('../../../../../../../src/plugins/ui_actions/public/mocks').uiActionsPluginMock.createStartContract(),
},
injectedMetadata: {
getKibanaVersion: () => '8.0.0',
},
}));

jest.mock('../../lib/compose/kibana_plugins');

describe('EmbeddedMap', () => {
let setQuery: SetQuery;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import { EuiFlexGroup, EuiSpacer } from '@elastic/eui';
import { Filter } from '@kbn/es-query';
import React, { useEffect, useState } from 'react';
import { npStart } from 'ui/new_platform';
import { SavedObjectFinder } from 'ui/saved_objects/components/saved_object_finder';
import { createPortalNode, InPortal } from 'react-reverse-portal';
import { Query } from 'src/plugins/data/common';
Expand All @@ -16,17 +15,20 @@ import styled from 'styled-components';
import { start } from '../../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public/legacy';
import { EmbeddablePanel } from '../../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public';

import { Loader } from '../loader';
import { getIndexPatternTitleIdMapping } from '../../hooks/api/helpers';
import { useIndexPatterns } from '../../hooks/use_index_patterns';
import { useKibanaUiSetting } from '../../lib/settings/use_kibana_ui_setting';
import { DEFAULT_INDEX_KEY } from '../../../common/constants';
import { useKibanaPlugins } from '../../lib/compose/kibana_plugins';
import { useKibanaCore } from '../../lib/compose/kibana_core';
import { useStateToaster } from '../toasters';
import { Loader } from '../loader';
import { IndexPatternsMissingPrompt } from './index_patterns_missing_prompt';
import { MapEmbeddable, SetQuery } from './types';
import * as i18n from './translations';
import { useStateToaster } from '../toasters';

import { createEmbeddable, displayErrorToast, setupEmbeddablesAPI } from './embedded_map_helpers';
import { MapToolTip } from './map_tool_tip/map_tool_tip';
import { getIndexPatternTitleIdMapping } from '../../hooks/api/helpers';

const EmbeddableWrapper = styled(EuiFlexGroup)`
position: relative;
Expand Down Expand Up @@ -63,13 +65,16 @@ export const EmbeddedMap = React.memo<EmbeddedMapProps>(
// Search InPortal/OutPortal for implementation touch points
const portalNode = React.useMemo(() => createPortalNode(), []);

const plugins = useKibanaPlugins();
const core = useKibanaCore();

// Initial Load useEffect
useEffect(() => {
let isSubscribed = true;
async function setupEmbeddable() {
// Configure Embeddables API
try {
setupEmbeddablesAPI();
setupEmbeddablesAPI(plugins);
} catch (e) {
displayErrorToast(i18n.ERROR_CONFIGURING_EMBEDDABLES_API, e.message, dispatchToaster);
setIsLoading(false);
Expand All @@ -96,7 +101,8 @@ export const EmbeddedMap = React.memo<EmbeddedMapProps>(
startDate,
endDate,
setQuery,
portalNode
portalNode,
plugins.embeddable
);
if (isSubscribed) {
setEmbeddable(embeddableObject);
Expand Down Expand Up @@ -154,12 +160,12 @@ export const EmbeddedMap = React.memo<EmbeddedMapProps>(
<EmbeddablePanel
data-test-subj="embeddable-panel"
embeddable={embeddable}
getActions={npStart.plugins.uiActions.getTriggerCompatibleActions}
getActions={plugins.uiActions.getTriggerCompatibleActions}
getEmbeddableFactory={start.getEmbeddableFactory}
getAllEmbeddableFactories={start.getEmbeddableFactories}
notifications={npStart.core.notifications}
overlays={npStart.core.overlays}
inspector={npStart.plugins.inspector}
notifications={core.notifications}
overlays={core.overlays}
inspector={plugins.inspector}
SavedObjectFinder={SavedObjectFinder}
/>
) : !isLoading && isIndexError ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,26 @@
*/

import { createEmbeddable, displayErrorToast, setupEmbeddablesAPI } from './embedded_map_helpers';
import { npStart } from 'ui/new_platform';
import { createUiNewPlatformMock } from 'ui/new_platform/__mocks__/helpers';
import { createPortalNode } from 'react-reverse-portal';
import { PluginsStart } from 'ui/new_platform/new_platform';

jest.mock('ui/new_platform');
jest.mock('../../lib/settings/use_kibana_ui_setting');

jest.mock(
'../../../../../../../src/legacy/core_plugins/embeddable_api/public/np_ready/public/legacy',
() => ({
start: {
getEmbeddableFactory: () => ({
createFromState: () => ({
reload: jest.fn(),
}),
}),
},
})
);

jest.mock('uuid', () => {
return {
v4: jest.fn(() => '9e1f72a9-7c73-4b7f-a562-09940f7daf4a'),
};
});

const { npStart } = createUiNewPlatformMock();
npStart.plugins.embeddable.getEmbeddableFactory = jest.fn().mockImplementation(() => ({
createFromState: () => ({
reload: jest.fn(),
}),
}));

describe('embedded_map_helpers', () => {
describe('displayErrorToast', () => {
test('dispatches toast with correct title and message', () => {
Expand All @@ -51,7 +46,7 @@ describe('embedded_map_helpers', () => {

describe('setupEmbeddablesAPI', () => {
test('attaches SIEM_FILTER_ACTION, and detaches extra UI actions', () => {
setupEmbeddablesAPI();
setupEmbeddablesAPI((npStart.plugins as unknown) as PluginsStart);
expect(npStart.plugins.uiActions.registerAction).toHaveBeenCalledTimes(1);
expect(npStart.plugins.uiActions.detachAction).toHaveBeenCalledTimes(3);
});
Expand All @@ -67,7 +62,8 @@ describe('embedded_map_helpers', () => {
0,
0,
setQueryMock,
createPortalNode()
createPortalNode(),
npStart.plugins.embeddable
);
expect(setQueryMock).toHaveBeenCalledTimes(1);
});
Expand All @@ -81,7 +77,8 @@ describe('embedded_map_helpers', () => {
0,
0,
setQueryMock,
createPortalNode()
createPortalNode(),
npStart.plugins.embeddable
);
expect(setQueryMock.mock.calls[0][0].refetch).not.toBe(embeddable.reload);
setQueryMock.mock.results[0].value();
Expand Down
Loading

0 comments on commit 874f985

Please sign in to comment.