diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_add.test.js b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_add.test.js index 06a7c2f1ec45e3..2be00e70f6f848 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_add.test.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_add.test.js @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - +import '../../public/np_ready/app/services/breadcrumbs.mock'; import { setupEnvironment, pageHelpers, nextTick, getRandomString } from './helpers'; import { indexPatterns } from '../../../../../../src/plugins/data/public'; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_edit.test.js b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_edit.test.js index 04e80deaf82766..abc3e5dc9def26 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_edit.test.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_edit.test.js @@ -4,7 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { AutoFollowPatternForm } from '../../public/app/components/auto_follow_pattern_form'; +import '../../public/np_ready/app/services/breadcrumbs.mock'; +import { AutoFollowPatternForm } from '../../public/np_ready/app/components/auto_follow_pattern_form'; import { setupEnvironment, pageHelpers, nextTick } from './helpers'; import { AUTO_FOLLOW_PATTERN_EDIT } from './helpers/constants'; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_list.test.js b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_list.test.js index 88d8f98b973bd4..20e982856dc19b 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_list.test.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_list.test.js @@ -4,21 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ +import '../../public/np_ready/app/services/breadcrumbs.mock'; import { setupEnvironment, pageHelpers, nextTick, getRandomString } from './helpers'; import { getAutoFollowPatternClientMock } from '../../fixtures/auto_follow_pattern'; jest.mock('ui/new_platform'); -jest.mock('ui/chrome', () => ({ - addBasePath: () => 'api/cross_cluster_replication', - breadcrumbs: { set: () => {} }, - getUiSettingsClient: () => ({ - get: x => x, - getUpdate$: () => ({ subscribe: jest.fn() }), - }), -})); - const { setup } = pageHelpers.autoFollowPatternList; describe('', () => { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_index_add.test.js b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_index_add.test.js index 8d4523ca26de20..7680be9d858a46 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_index_add.test.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_index_add.test.js @@ -4,8 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ +import '../../public/np_ready/app/services/breadcrumbs.mock'; import { setupEnvironment, pageHelpers, nextTick } from './helpers'; -import { RemoteClustersFormField } from '../../public/app/components'; +import { RemoteClustersFormField } from '../../public/np_ready/app/components'; import { indexPatterns } from '../../../../../../src/plugins/data/public'; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_index_edit.test.js b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_index_edit.test.js index 5e2810ae882fbe..cfa37ff2e0358d 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_index_edit.test.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_index_edit.test.js @@ -4,8 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ +import '../../public/np_ready/app/services/breadcrumbs.mock'; import { setupEnvironment, pageHelpers, nextTick } from './helpers'; -import { FollowerIndexForm } from '../../public/app/components/follower_index_form/follower_index_form'; +import { FollowerIndexForm } from '../../public/np_ready/app/components/follower_index_form/follower_index_form'; import { FOLLOWER_INDEX_EDIT } from './helpers/constants'; jest.mock('ui/new_platform'); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_indices_list.test.js b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_indices_list.test.js index 9fd5756a7febfe..dde31d1d166f99 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_indices_list.test.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_indices_list.test.js @@ -10,15 +10,6 @@ import { getFollowerIndexMock } from '../../fixtures/follower_index'; jest.mock('ui/new_platform'); -jest.mock('ui/chrome', () => ({ - addBasePath: () => 'api/cross_cluster_replication', - breadcrumbs: { set: () => {} }, - getUiSettingsClient: () => ({ - get: x => x, - getUpdate$: () => ({ subscribe: jest.fn() }), - }), -})); - const { setup } = pageHelpers.followerIndexList; describe('', () => { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_add.helpers.js b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_add.helpers.js index 3eb195bac7ed15..1f64e589bc4c10 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_add.helpers.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_add.helpers.js @@ -5,9 +5,9 @@ */ import { registerTestBed } from '../../../../../../test_utils'; -import { AutoFollowPatternAdd } from '../../../public/app/sections/auto_follow_pattern_add'; -import { ccrStore } from '../../../public/app/store'; -import routing from '../../../public/app/services/routing'; +import { AutoFollowPatternAdd } from '../../../public/np_ready/app/sections/auto_follow_pattern_add'; +import { ccrStore } from '../../../public/np_ready/app/store'; +import routing from '../../../public/np_ready/app/services/routing'; const testBedConfig = { store: ccrStore, diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_edit.helpers.js b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_edit.helpers.js index 94a94554b9105e..2b110c6552072e 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_edit.helpers.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_edit.helpers.js @@ -5,9 +5,9 @@ */ import { registerTestBed } from '../../../../../../test_utils'; -import { AutoFollowPatternEdit } from '../../../public/app/sections/auto_follow_pattern_edit'; -import { ccrStore } from '../../../public/app/store'; -import routing from '../../../public/app/services/routing'; +import { AutoFollowPatternEdit } from '../../../public/np_ready/app/sections/auto_follow_pattern_edit'; +import { ccrStore } from '../../../public/np_ready/app/store'; +import routing from '../../../public/np_ready/app/services/routing'; import { AUTO_FOLLOW_PATTERN_EDIT_NAME } from './constants'; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_list.helpers.js b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_list.helpers.js index c0d29e8af25497..1d3e8ad6dff83b 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_list.helpers.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_list.helpers.js @@ -5,9 +5,9 @@ */ import { registerTestBed, findTestSubject } from '../../../../../../test_utils'; -import { AutoFollowPatternList } from '../../../public/app/sections/home/auto_follow_pattern_list'; -import { ccrStore } from '../../../public/app/store'; -import routing from '../../../public/app/services/routing'; +import { AutoFollowPatternList } from '../../../public/np_ready/app/sections/home/auto_follow_pattern_list'; +import { ccrStore } from '../../../public/np_ready/app/store'; +import routing from '../../../public/np_ready/app/services/routing'; const testBedConfig = { store: ccrStore, diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_add.helpers.js b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_add.helpers.js index 785330049cb0ce..f74baa1b2ad0a4 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_add.helpers.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_add.helpers.js @@ -5,9 +5,9 @@ */ import { registerTestBed } from '../../../../../../test_utils'; -import { FollowerIndexAdd } from '../../../public/app/sections/follower_index_add'; -import { ccrStore } from '../../../public/app/store'; -import routing from '../../../public/app/services/routing'; +import { FollowerIndexAdd } from '../../../public/np_ready/app/sections/follower_index_add'; +import { ccrStore } from '../../../public/np_ready/app/store'; +import routing from '../../../public/np_ready/app/services/routing'; const testBedConfig = { store: ccrStore, diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_edit.helpers.js b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_edit.helpers.js index 56cbe5b47229c6..47f8539bb593b6 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_edit.helpers.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_edit.helpers.js @@ -5,9 +5,9 @@ */ import { registerTestBed } from '../../../../../../test_utils'; -import { FollowerIndexEdit } from '../../../public/app/sections/follower_index_edit'; -import { ccrStore } from '../../../public/app/store'; -import routing from '../../../public/app/services/routing'; +import { FollowerIndexEdit } from '../../../public/np_ready/app/sections/follower_index_edit'; +import { ccrStore } from '../../../public/np_ready/app/store'; +import routing from '../../../public/np_ready/app/services/routing'; import { FOLLOWER_INDEX_EDIT_NAME } from './constants'; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_list.helpers.js b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_list.helpers.js index 02b64cd7f306ca..2154e11e17b1f7 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_list.helpers.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_list.helpers.js @@ -5,9 +5,9 @@ */ import { registerTestBed, findTestSubject } from '../../../../../../test_utils'; -import { FollowerIndicesList } from '../../../public/app/sections/home/follower_indices_list'; -import { ccrStore } from '../../../public/app/store'; -import routing from '../../../public/app/services/routing'; +import { FollowerIndicesList } from '../../../public/np_ready/app/sections/home/follower_indices_list'; +import { ccrStore } from '../../../public/np_ready/app/store'; +import routing from '../../../public/np_ready/app/services/routing'; const testBedConfig = { store: ccrStore, diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/home.helpers.js b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/home.helpers.js index db30e4fe1dbe7c..664ad909ba8e76 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/home.helpers.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/home.helpers.js @@ -5,9 +5,9 @@ */ import { registerTestBed } from '../../../../../../test_utils'; -import { CrossClusterReplicationHome } from '../../../public/app/sections/home/home'; -import { ccrStore } from '../../../public/app/store'; -import routing from '../../../public/app/services/routing'; +import { CrossClusterReplicationHome } from '../../../public/np_ready/app/sections/home/home'; +import { ccrStore } from '../../../public/np_ready/app/store'; +import routing from '../../../public/np_ready/app/services/routing'; import { BASE_PATH } from '../../../common/constants'; const testBedConfig = { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/http_requests.js b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/http_requests.js index 9bd88a08a5a617..e2bd54a92a1f13 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/http_requests.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/http_requests.js @@ -19,7 +19,7 @@ const registerHttpRequestMockHelpers = server => { server.respondWith( 'GET', - 'api/cross_cluster_replication/follower_indices', + '/api/cross_cluster_replication/follower_indices', mockResponse(defaultResponse, response) ); }; @@ -29,7 +29,7 @@ const registerHttpRequestMockHelpers = server => { server.respondWith( 'GET', - 'api/cross_cluster_replication/auto_follow_patterns', + '/api/cross_cluster_replication/auto_follow_patterns', mockResponse(defaultResponse, response) ); }; @@ -39,7 +39,7 @@ const registerHttpRequestMockHelpers = server => { server.respondWith( 'DELETE', - /api\/cross_cluster_replication\/auto_follow_patterns/, + /\/api\/cross_cluster_replication\/auto_follow_patterns/, mockResponse(defaultResponse, response) ); }; @@ -61,7 +61,7 @@ const registerHttpRequestMockHelpers = server => { server.respondWith( 'GET', - 'api/cross_cluster_replication/stats/auto_follow', + '/api/cross_cluster_replication/stats/auto_follow', mockResponse(defaultResponse, response) ); }; @@ -87,7 +87,7 @@ const registerHttpRequestMockHelpers = server => { server.respondWith( 'GET', - /api\/cross_cluster_replication\/auto_follow_patterns\/.+/, + /\/api\/cross_cluster_replication\/auto_follow_patterns\/.+/, mockResponse(defaultResponse, response) ); }; @@ -105,7 +105,7 @@ const registerHttpRequestMockHelpers = server => { server.respondWith( 'GET', - /api\/cross_cluster_replication\/follower_indices\/.+/, + /\/api\/cross_cluster_replication\/follower_indices\/.+/, mockResponse(defaultResponse, response) ); }; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/setup_environment.js b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/setup_environment.js index 8bd86067d85135..3562ad0df5b514 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/setup_environment.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/setup_environment.js @@ -7,14 +7,15 @@ import axios from 'axios'; import axiosXhrAdapter from 'axios/lib/adapters/xhr'; -import { setHttpClient } from '../../../public/app/services/api'; +import { setHttpClient } from '../../../public/np_ready/app/services/api'; import { init as initHttpRequests } from './http_requests'; export const setupEnvironment = () => { - // Mock Angular $q - const $q = { defer: () => ({ resolve() {} }) }; - // axios has a $http like interface so using it to simulate $http - setHttpClient(axios.create({ adapter: axiosXhrAdapter }), $q); + // axios has a similar interface to HttpSetup, but we + // flatten out the response. + const client = axios.create({ adapter: axiosXhrAdapter }); + client.interceptors.response.use(({ data }) => data); + setHttpClient(client); const { server, httpRequestsMockHelpers } = initHttpRequests(); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/home.test.js b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/home.test.js index 2afa9c44a7b1c4..2c536d069ef532 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/home.test.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/home.test.js @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import '../../public/np_ready/app/services/breadcrumbs.mock'; import { setupEnvironment, pageHelpers, nextTick } from './helpers'; jest.mock('ui/new_platform'); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/common/constants/app.js b/x-pack/legacy/plugins/cross_cluster_replication/common/constants/app.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/common/constants/app.js rename to x-pack/legacy/plugins/cross_cluster_replication/common/constants/app.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/common/constants/base_path.js b/x-pack/legacy/plugins/cross_cluster_replication/common/constants/base_path.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/common/constants/base_path.js rename to x-pack/legacy/plugins/cross_cluster_replication/common/constants/base_path.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/common/constants/index.js b/x-pack/legacy/plugins/cross_cluster_replication/common/constants/index.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/common/constants/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/common/constants/index.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/common/constants/plugin.js b/x-pack/legacy/plugins/cross_cluster_replication/common/constants/plugin.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/common/constants/plugin.js rename to x-pack/legacy/plugins/cross_cluster_replication/common/constants/plugin.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/common/constants/settings.js b/x-pack/legacy/plugins/cross_cluster_replication/common/constants/settings.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/common/constants/settings.js rename to x-pack/legacy/plugins/cross_cluster_replication/common/constants/settings.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/index.js b/x-pack/legacy/plugins/cross_cluster_replication/index.js index cdb867972fcf5c..aff4cc5b56738e 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/index.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/index.js @@ -6,9 +6,7 @@ import { resolve } from 'path'; import { PLUGIN } from './common/constants'; -import { registerLicenseChecker } from './server/lib/register_license_checker'; -import { registerRoutes } from './server/routes/register_routes'; -import { ccrDataEnricher } from './cross_cluster_replication_data'; +import { plugin } from './server/np_ready'; export function crossClusterReplication(kibana) { return new kibana.Plugin({ @@ -47,15 +45,13 @@ export function crossClusterReplication(kibana) { ); }, init: function initCcrPlugin(server) { - registerLicenseChecker(server); - registerRoutes(server); - if ( - server.config().get('xpack.ccr.ui.enabled') && - server.newPlatform.setup.plugins.indexManagement && - server.newPlatform.setup.plugins.indexManagement.indexDataEnricher - ) { - server.newPlatform.setup.plugins.indexManagement.indexDataEnricher.add(ccrDataEnricher); - } + plugin({}).setup(server.newPlatform.setup.core, { + indexManagement: server.newPlatform.setup.plugins.indexManagement, + __LEGACY: { + server, + ccrUIEnabled: server.config().get('xpack.ccr.ui.enabled'), + }, + }); }, }); } diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/documentation_links.js b/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/documentation_links.js deleted file mode 100644 index 585ca7e0f5cf17..00000000000000 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/documentation_links.js +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } from 'ui/documentation_links'; - -const esBase = `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}`; - -export const autoFollowPatternUrl = `${esBase}/ccr-put-auto-follow-pattern.html`; -export const followerIndexUrl = `${esBase}/ccr-put-follow.html`; -export const byteUnitsUrl = `${esBase}/common-options.html#byte-units`; -export const timeUnitsUrl = `${esBase}/common-options.html#time-units`; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/index.js index 4ec268f0de7f29..e92c44da34474c 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/index.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/index.js @@ -5,4 +5,3 @@ */ import './register_routes'; -import './extend_index_management'; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/index.scss b/x-pack/legacy/plugins/cross_cluster_replication/public/index.scss index 6f65dc04d4427a..31317e16e3e9f9 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/index.scss +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/index.scss @@ -10,4 +10,4 @@ // ccrChart__legend--small // ccrChart__legend-isLoading -@import 'app/app'; +@import 'np_ready/app/app'; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/_app.scss b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/_app.scss similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/_app.scss rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/_app.scss diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/app.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/app.js similarity index 97% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/app.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/app.js index 31626750a7f37d..968646a4bd1b0d 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/app.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/app.js @@ -7,7 +7,6 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { Route, Switch, Redirect, withRouter } from 'react-router-dom'; -import { fatalError } from 'ui/notify'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -21,7 +20,8 @@ import { EuiTitle, } from '@elastic/eui'; -import { BASE_PATH } from '../../common/constants'; +import { BASE_PATH } from '../../../common/constants'; +import { getFatalErrors } from './services/notifications'; import { SectionError } from './components'; import routing from './services/routing'; import { loadPermissions } from './services/api'; @@ -81,7 +81,7 @@ class AppComponent extends Component { }); } catch (error) { // Expect an error in the shape provided by Angular's $http service. - if (error && error.data) { + if (error && error.body) { return this.setState({ isFetchingPermissions: false, fetchPermissionError: error, @@ -90,7 +90,7 @@ class AppComponent extends Component { // This error isn't an HTTP error, so let the fatal error screen tell the user something // unexpected happened. - fatalError( + getFatalErrors().add( error, i18n.translate('xpack.crossClusterReplication.app.checkPermissionsFatalErrorTitle', { defaultMessage: 'Cross-Cluster Replication app', diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/__snapshots__/auto_follow_pattern_form.test.js.snap b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/__snapshots__/auto_follow_pattern_form.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/components/__snapshots__/auto_follow_pattern_form.test.js.snap rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/__snapshots__/auto_follow_pattern_form.test.js.snap diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_action_menu/auto_follow_pattern_action_menu.container.ts b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_action_menu/auto_follow_pattern_action_menu.container.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_action_menu/auto_follow_pattern_action_menu.container.ts rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_action_menu/auto_follow_pattern_action_menu.container.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_action_menu/auto_follow_pattern_action_menu.tsx b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_action_menu/auto_follow_pattern_action_menu.tsx similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_action_menu/auto_follow_pattern_action_menu.tsx rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_action_menu/auto_follow_pattern_action_menu.tsx diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_action_menu/index.ts b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_action_menu/index.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_action_menu/index.ts rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_action_menu/index.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_delete_provider.d.ts b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_delete_provider.d.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_delete_provider.d.ts rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_delete_provider.d.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_delete_provider.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_delete_provider.js similarity index 98% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_delete_provider.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_delete_provider.js index f9c03165dcf971..7803b329e62581 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_delete_provider.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_delete_provider.js @@ -11,7 +11,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EuiConfirmModal, EuiOverlayMask } from '@elastic/eui'; import { deleteAutoFollowPattern } from '../store/actions'; -import { arrify } from '../../../common/services/utils'; +import { arrify } from '../../../../common/services/utils'; class AutoFollowPatternDeleteProviderUi extends PureComponent { state = { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_form.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_form.js similarity index 99% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_form.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_form.js index d4e418a964c8ff..5bc5d8ba6e4027 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_form.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_form.js @@ -29,8 +29,8 @@ import { EuiTitle, } from '@elastic/eui'; -import { indices } from '../../../../../../../src/plugins/es_ui_shared/public'; -import { indexPatterns } from '../../../../../../../src/plugins/data/public'; +import { indices } from '../../../../../../../../src/plugins/es_ui_shared/public'; +import { indexPatterns } from '../../../../../../../../src/plugins/data/public'; import routing from '../services/routing'; import { extractQueryParams } from '../services/query_params'; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_form.test.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_form.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_form.test.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_form.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_indices_preview.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_indices_preview.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_indices_preview.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_indices_preview.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_page_title.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_page_title.js similarity index 92% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_page_title.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_page_title.js index 43cc0a39e6e57c..9880e8c983a8e1 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_page_title.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_page_title.js @@ -17,7 +17,7 @@ import { EuiTitle, } from '@elastic/eui'; -import { autoFollowPatternUrl } from '../services/documentation_links'; +import { getAutoFollowPatternUrl } from '../services/documentation_links'; export const AutoFollowPatternPageTitle = ({ title }) => ( @@ -35,7 +35,7 @@ export const AutoFollowPatternPageTitle = ({ title }) => ( + + { @@ -223,18 +223,24 @@ export class FollowerIndexForm extends PureComponent { isValidatingIndexName: false, }); } catch (error) { - // Expect an error in the shape provided by Angular's $http service. - if (error && error.data) { - // All validation does is check for a name collision, so we can just let the user attempt - // to save the follower index and get an error back from the API. - return this.setState({ - isValidatingIndexName: false, - }); + if (error) { + if (error.name === 'AbortError') { + // Ignore aborted requests + return; + } + // This could be an HTTP error + if (error.body) { + // All validation does is check for a name collision, so we can just let the user attempt + // to save the follower index and get an error back from the API. + return this.setState({ + isValidatingIndexName: false, + }); + } } // This error isn't an HTTP error, so let the fatal error screen tell the user something // unexpected happened. - fatalError( + getFatalErrors().add( error, i18n.translate( 'xpack.crossClusterReplication.followerIndexForm.indexNameValidationFatalErrorTitle', diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/follower_index_form/follower_index_form.test.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_form.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/components/follower_index_form/follower_index_form.test.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_form.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/follower_index_form/follower_index_request_flyout.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_request_flyout.js similarity index 96% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/components/follower_index_form/follower_index_request_flyout.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_request_flyout.js index cba1c104e45d98..cb02a929b16f84 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/follower_index_form/follower_index_request_flyout.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_request_flyout.js @@ -26,7 +26,7 @@ import { EuiTitle, } from '@elastic/eui'; -import { serializeFollowerIndex } from '../../../../common/services/follower_index_serialization'; +import { serializeFollowerIndex } from '../../../../../common/services/follower_index_serialization'; export class FollowerIndexRequestFlyout extends PureComponent { static propTypes = { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/follower_index_form/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/components/follower_index_form/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/follower_index_page_title.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_page_title.js similarity index 92% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/components/follower_index_page_title.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_page_title.js index a77059b5fe084a..d72038096b72a2 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/follower_index_page_title.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_page_title.js @@ -17,7 +17,7 @@ import { EuiTitle, } from '@elastic/eui'; -import { followerIndexUrl } from '../services/documentation_links'; +import { getFollowerIndexUrl } from '../services/documentation_links'; export const FollowerIndexPageTitle = ({ title }) => ( @@ -35,7 +35,7 @@ export const FollowerIndexPageTitle = ({ title }) => ( ( diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/remote_clusters_provider.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/remote_clusters_provider.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/components/remote_clusters_provider.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/remote_clusters_provider.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/section_error.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/section_error.js similarity index 79% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/components/section_error.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/section_error.js index 8aaf89b30f0e78..a2c782a0e8e58a 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/section_error.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/section_error.js @@ -9,21 +9,21 @@ import { EuiCallOut, EuiSpacer } from '@elastic/eui'; export function SectionError(props) { const { title, error, ...rest } = props; - const data = error.data ? error.data : error; + const data = error.body ? error.body : error; const { error: errorString, - cause, // wrapEsError() on the server add a "cause" array + attributes, // wrapEsError() on the server add a "cause" array message, } = data; return (
{message || errorString}
- {cause && ( + {attributes && attributes.cause && (
    - {cause.map((message, i) => ( + {attributes.cause.map((message, i) => (
  • {message}
  • ))}
diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/section_loading.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/section_loading.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/components/section_loading.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/section_loading.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/components/section_unauthorized.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/section_unauthorized.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/components/section_unauthorized.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/section_unauthorized.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/constants/api.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/api.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/constants/api.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/api.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/constants/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/constants/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/constants/sections.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/sections.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/constants/sections.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/sections.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/constants/ui_metric.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/ui_metric.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/constants/ui_metric.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/ui_metric.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/index.js similarity index 88% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/index.js index 928d37558adb7b..cc81fce4eebe71 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/index.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/index.js @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { I18nContext } from 'ui/i18n'; import React from 'react'; import { render } from 'react-dom'; import { Provider } from 'react-redux'; @@ -12,7 +11,7 @@ import { HashRouter } from 'react-router-dom'; import { App } from './app'; import { ccrStore } from './store'; -export const renderReact = async elem => { +export const renderReact = async (elem, I18nContext) => { render( diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.container.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.container.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.container.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.js similarity index 91% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.js index f55b9e4bceb0b3..60a6cc79376e5c 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.js @@ -7,12 +7,10 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from '@kbn/i18n/react'; -import chrome from 'ui/chrome'; -import { MANAGEMENT_BREADCRUMB } from 'ui/management'; import { EuiPageContent } from '@elastic/eui'; -import { listBreadcrumb, addBreadcrumb } from '../../services/breadcrumbs'; +import { listBreadcrumb, addBreadcrumb, setBreadcrumbs } from '../../services/breadcrumbs'; import { AutoFollowPatternForm, AutoFollowPatternPageTitle, @@ -29,7 +27,7 @@ export class AutoFollowPatternAdd extends PureComponent { }; componentDidMount() { - chrome.breadcrumbs.set([MANAGEMENT_BREADCRUMB, listBreadcrumb, addBreadcrumb]); + setBreadcrumbs([listBreadcrumb, addBreadcrumb]); } componentWillUnmount() { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_add/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_add/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_add/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_add/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.container.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.container.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.container.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js similarity index 96% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js index a64c9566502f15..4cd3617abd9899 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js @@ -8,12 +8,10 @@ import React, { PureComponent, Fragment } from 'react'; import PropTypes from 'prop-types'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import chrome from 'ui/chrome'; -import { MANAGEMENT_BREADCRUMB } from 'ui/management'; import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiPageContent, EuiSpacer } from '@elastic/eui'; -import { listBreadcrumb, editBreadcrumb } from '../../services/breadcrumbs'; +import { listBreadcrumb, editBreadcrumb, setBreadcrumbs } from '../../services/breadcrumbs'; import routing from '../../services/routing'; import { AutoFollowPatternForm, @@ -56,7 +54,7 @@ export class AutoFollowPatternEdit extends PureComponent { selectAutoFollowPattern(decodedId); - chrome.breadcrumbs.set([MANAGEMENT_BREADCRUMB, listBreadcrumb, editBreadcrumb]); + setBreadcrumbs([listBreadcrumb, editBreadcrumb]); } componentDidUpdate(prevProps, prevState) { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_edit/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_edit/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/follower_index_add/follower_index_add.container.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_add/follower_index_add.container.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/follower_index_add/follower_index_add.container.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_add/follower_index_add.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/follower_index_add/follower_index_add.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_add/follower_index_add.js similarity index 91% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/follower_index_add/follower_index_add.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_add/follower_index_add.js index 26b5d8d6bb880a..003e27777652b2 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/follower_index_add/follower_index_add.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_add/follower_index_add.js @@ -7,12 +7,10 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from '@kbn/i18n/react'; -import chrome from 'ui/chrome'; -import { MANAGEMENT_BREADCRUMB } from 'ui/management'; import { EuiPageContent } from '@elastic/eui'; -import { listBreadcrumb, addBreadcrumb } from '../../services/breadcrumbs'; +import { setBreadcrumbs, listBreadcrumb, addBreadcrumb } from '../../services/breadcrumbs'; import { FollowerIndexForm, FollowerIndexPageTitle, @@ -29,7 +27,7 @@ export class FollowerIndexAdd extends PureComponent { }; componentDidMount() { - chrome.breadcrumbs.set([MANAGEMENT_BREADCRUMB, listBreadcrumb, addBreadcrumb]); + setBreadcrumbs([listBreadcrumb, addBreadcrumb]); } componentWillUnmount() { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/follower_index_add/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_add/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/follower_index_add/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_add/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/follower_index_edit/follower_index_edit.container.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_edit/follower_index_edit.container.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/follower_index_edit/follower_index_edit.container.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_edit/follower_index_edit.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/follower_index_edit/follower_index_edit.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_edit/follower_index_edit.js similarity index 97% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/follower_index_edit/follower_index_edit.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_edit/follower_index_edit.js index 7dc45e88f41063..21493602c12a7c 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/follower_index_edit/follower_index_edit.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_edit/follower_index_edit.js @@ -8,8 +8,6 @@ import React, { PureComponent, Fragment } from 'react'; import PropTypes from 'prop-types'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import chrome from 'ui/chrome'; -import { MANAGEMENT_BREADCRUMB } from 'ui/management'; import { EuiButtonEmpty, @@ -21,7 +19,7 @@ import { EuiSpacer, } from '@elastic/eui'; -import { listBreadcrumb, editBreadcrumb } from '../../services/breadcrumbs'; +import { setBreadcrumbs, listBreadcrumb, editBreadcrumb } from '../../services/breadcrumbs'; import routing from '../../services/routing'; import { FollowerIndexForm, @@ -76,7 +74,7 @@ export class FollowerIndexEdit extends PureComponent { selectFollowerIndex(decodedId); - chrome.breadcrumbs.set([MANAGEMENT_BREADCRUMB, listBreadcrumb, editBreadcrumb]); + setBreadcrumbs([listBreadcrumb, editBreadcrumb]); } componentDidUpdate(prevProps, prevState) { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/follower_index_edit/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_edit/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/follower_index_edit/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_edit/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.container.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.container.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.container.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.container.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.container.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.container.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.container.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.container.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.container.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js similarity index 99% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js index 7b31ffa5024b76..1a6d5e6efe35a0 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js @@ -7,7 +7,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from '@kbn/i18n/react'; -import { getIndexListUri } from '../../../../../../../../../../plugins/index_management/public'; +import { getIndexListUri } from '../../../../../../../../../../../plugins/index_management/public'; import { EuiButtonEmpty, diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/components/detail_panel/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/components/detail_panel/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/components/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/components/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/context_menu/context_menu.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/context_menu/context_menu.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/context_menu/context_menu.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/context_menu/context_menu.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/context_menu/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/context_menu/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/context_menu/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/context_menu/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.container.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.container.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.container.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.js similarity index 99% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.js index 2ad118d28f38d7..3e8cf6d3e2f78e 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.js @@ -31,7 +31,7 @@ import { } from '@elastic/eui'; import 'brace/theme/textmate'; -import { getIndexListUri } from '../../../../../../../../../../plugins/index_management/public'; +import { getIndexListUri } from '../../../../../../../../../../../plugins/index_management/public'; import { API_STATUS } from '../../../../../constants'; import { ContextMenu } from '../context_menu'; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/detail_panel/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/detail_panel/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/detail_panel/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/detail_panel/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/follower_indices_table/follower_indices_table.container.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/follower_indices_table/follower_indices_table.container.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/follower_indices_table/follower_indices_table.container.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/follower_indices_table/follower_indices_table.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/follower_indices_table/follower_indices_table.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/follower_indices_table/follower_indices_table.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/follower_indices_table/follower_indices_table.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/follower_indices_table/follower_indices_table.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/follower_indices_table/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/follower_indices_table/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/follower_indices_table/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/follower_indices_table/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/follower_indices_list.container.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/follower_indices_list.container.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/follower_indices_list.container.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/follower_indices_list.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/follower_indices_list.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/follower_indices_list.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/follower_indices_list.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/follower_indices_list.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/home.container.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/home.container.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/home.container.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/home.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/home.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/home.js similarity index 91% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/home.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/home.js index f89d287540ebdf..88db9096122453 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/home.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/home.js @@ -7,13 +7,11 @@ import React, { PureComponent } from 'react'; import { Route, Switch } from 'react-router-dom'; import { FormattedMessage } from '@kbn/i18n/react'; -import chrome from 'ui/chrome'; -import { MANAGEMENT_BREADCRUMB } from 'ui/management'; import { EuiPageBody, EuiPageContent, EuiSpacer, EuiTab, EuiTabs, EuiTitle } from '@elastic/eui'; -import { BASE_PATH } from '../../../../common/constants'; -import { listBreadcrumb } from '../../services/breadcrumbs'; +import { BASE_PATH } from '../../../../../common/constants'; +import { setBreadcrumbs, listBreadcrumb } from '../../services/breadcrumbs'; import routing from '../../services/routing'; import { AutoFollowPatternList } from './auto_follow_pattern_list'; import { FollowerIndicesList } from './follower_indices_list'; @@ -47,7 +45,7 @@ export class CrossClusterReplicationHome extends PureComponent { ]; componentDidMount() { - chrome.breadcrumbs.set([MANAGEMENT_BREADCRUMB, listBreadcrumb]); + setBreadcrumbs([listBreadcrumb]); } static getDerivedStateFromProps(props) { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/home/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/sections/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/__snapshots__/auto_follow_pattern_validators.test.js.snap b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/__snapshots__/auto_follow_pattern_validators.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/services/__snapshots__/auto_follow_pattern_validators.test.js.snap rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/__snapshots__/auto_follow_pattern_validators.test.js.snap diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/api.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/api.js similarity index 52% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/services/api.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/api.js index 52576387444fd4..b50c36aa8df9f5 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/api.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/api.js @@ -3,14 +3,12 @@ * 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 { API_BASE_PATH, API_REMOTE_CLUSTERS_BASE_PATH, API_INDEX_MANAGEMENT_BASE_PATH, -} from '../../../common/constants'; -import { arrify } from '../../../common/services/utils'; +} from '../../../../common/constants'; +import { arrify } from '../../../../common/services/utils'; import { UIM_FOLLOWER_INDEX_CREATE, UIM_FOLLOWER_INDEX_UPDATE, @@ -33,22 +31,10 @@ import { import { trackUserRequest } from './track_ui_metric'; import { areAllSettingsDefault } from './follower_index_default_settings'; -const apiPrefix = chrome.addBasePath(API_BASE_PATH); -const apiPrefixRemoteClusters = chrome.addBasePath(API_REMOTE_CLUSTERS_BASE_PATH); -const apiPrefixIndexManagement = chrome.addBasePath(API_INDEX_MANAGEMENT_BASE_PATH); - -// This is an Angular service, which is why we use this provider pattern -// to access it within our React app. let httpClient; -// The deferred AngularJS api allows us to create a deferred promise -// to be resolved later. This allows us to cancel in-flight http Requests. -// https://docs.angularjs.org/api/ng/service/$q#the-deferred-api -let $q; - -export function setHttpClient(client, $deffered) { +export function setHttpClient(client) { httpClient = client; - $q = $deffered; } export const getHttpClient = () => { @@ -57,67 +43,65 @@ export const getHttpClient = () => { // --- -const extractData = response => response.data; - const createIdString = ids => ids.map(id => encodeURIComponent(id)).join(','); /* Auto Follow Pattern */ -export const loadAutoFollowPatterns = () => - httpClient.get(`${apiPrefix}/auto_follow_patterns`).then(extractData); +export const loadAutoFollowPatterns = () => httpClient.get(`${API_BASE_PATH}/auto_follow_patterns`); export const getAutoFollowPattern = id => - httpClient.get(`${apiPrefix}/auto_follow_patterns/${encodeURIComponent(id)}`).then(extractData); + httpClient.get(`${API_BASE_PATH}/auto_follow_patterns/${encodeURIComponent(id)}`); -export const loadRemoteClusters = () => httpClient.get(apiPrefixRemoteClusters).then(extractData); +export const loadRemoteClusters = () => httpClient.get(API_REMOTE_CLUSTERS_BASE_PATH); export const createAutoFollowPattern = autoFollowPattern => { - const request = httpClient.post(`${apiPrefix}/auto_follow_patterns`, autoFollowPattern); - return trackUserRequest(request, UIM_AUTO_FOLLOW_PATTERN_CREATE).then(extractData); + const request = httpClient.post(`${API_BASE_PATH}/auto_follow_patterns`, { + body: JSON.stringify(autoFollowPattern), + }); + return trackUserRequest(request, UIM_AUTO_FOLLOW_PATTERN_CREATE); }; export const updateAutoFollowPattern = (id, autoFollowPattern) => { const request = httpClient.put( - `${apiPrefix}/auto_follow_patterns/${encodeURIComponent(id)}`, - autoFollowPattern + `${API_BASE_PATH}/auto_follow_patterns/${encodeURIComponent(id)}`, + { body: JSON.stringify(autoFollowPattern) } ); - return trackUserRequest(request, UIM_AUTO_FOLLOW_PATTERN_UPDATE).then(extractData); + return trackUserRequest(request, UIM_AUTO_FOLLOW_PATTERN_UPDATE); }; export const deleteAutoFollowPattern = id => { const ids = arrify(id); const idString = ids.map(_id => encodeURIComponent(_id)).join(','); - const request = httpClient.delete(`${apiPrefix}/auto_follow_patterns/${idString}`); + const request = httpClient.delete(`${API_BASE_PATH}/auto_follow_patterns/${idString}`); const uiMetric = ids.length > 1 ? UIM_AUTO_FOLLOW_PATTERN_DELETE_MANY : UIM_AUTO_FOLLOW_PATTERN_DELETE; - return trackUserRequest(request, uiMetric).then(extractData); + return trackUserRequest(request, uiMetric); }; export const pauseAutoFollowPattern = id => { const ids = arrify(id); const idString = ids.map(encodeURIComponent).join(','); - const request = httpClient.post(`${apiPrefix}/auto_follow_patterns/${idString}/pause`); + const request = httpClient.post(`${API_BASE_PATH}/auto_follow_patterns/${idString}/pause`); const uiMetric = ids.length > 1 ? UIM_AUTO_FOLLOW_PATTERN_PAUSE_MANY : UIM_AUTO_FOLLOW_PATTERN_PAUSE; - return trackUserRequest(request, uiMetric).then(extractData); + return trackUserRequest(request, uiMetric); }; export const resumeAutoFollowPattern = id => { const ids = arrify(id); const idString = ids.map(encodeURIComponent).join(','); - const request = httpClient.post(`${apiPrefix}/auto_follow_patterns/${idString}/resume`); + const request = httpClient.post(`${API_BASE_PATH}/auto_follow_patterns/${idString}/resume`); const uiMetric = ids.length > 1 ? UIM_AUTO_FOLLOW_PATTERN_RESUME_MANY : UIM_AUTO_FOLLOW_PATTERN_RESUME; - return trackUserRequest(request, uiMetric).then(extractData); + return trackUserRequest(request, uiMetric); }; /* Follower Index */ -export const loadFollowerIndices = () => - httpClient.get(`${apiPrefix}/follower_indices`).then(extractData); +export const loadFollowerIndices = () => httpClient.get(`${API_BASE_PATH}/follower_indices`); export const getFollowerIndex = id => - httpClient.get(`${apiPrefix}/follower_indices/${encodeURIComponent(id)}`).then(extractData); + httpClient.get(`${API_BASE_PATH}/follower_indices/${encodeURIComponent(id)}`); export const createFollowerIndex = followerIndex => { const uiMetrics = [UIM_FOLLOWER_INDEX_CREATE]; @@ -125,32 +109,34 @@ export const createFollowerIndex = followerIndex => { if (isUsingAdvancedSettings) { uiMetrics.push(UIM_FOLLOWER_INDEX_USE_ADVANCED_OPTIONS); } - const request = httpClient.post(`${apiPrefix}/follower_indices`, followerIndex); - return trackUserRequest(request, uiMetrics).then(extractData); + const request = httpClient.post(`${API_BASE_PATH}/follower_indices`, { + body: JSON.stringify(followerIndex), + }); + return trackUserRequest(request, uiMetrics); }; export const pauseFollowerIndex = id => { const ids = arrify(id); const idString = createIdString(ids); - const request = httpClient.put(`${apiPrefix}/follower_indices/${idString}/pause`); + const request = httpClient.put(`${API_BASE_PATH}/follower_indices/${idString}/pause`); const uiMetric = ids.length > 1 ? UIM_FOLLOWER_INDEX_PAUSE_MANY : UIM_FOLLOWER_INDEX_PAUSE; - return trackUserRequest(request, uiMetric).then(extractData); + return trackUserRequest(request, uiMetric); }; export const resumeFollowerIndex = id => { const ids = arrify(id); const idString = createIdString(ids); - const request = httpClient.put(`${apiPrefix}/follower_indices/${idString}/resume`); + const request = httpClient.put(`${API_BASE_PATH}/follower_indices/${idString}/resume`); const uiMetric = ids.length > 1 ? UIM_FOLLOWER_INDEX_RESUME_MANY : UIM_FOLLOWER_INDEX_RESUME; - return trackUserRequest(request, uiMetric).then(extractData); + return trackUserRequest(request, uiMetric); }; export const unfollowLeaderIndex = id => { const ids = arrify(id); const idString = createIdString(ids); - const request = httpClient.put(`${apiPrefix}/follower_indices/${idString}/unfollow`); + const request = httpClient.put(`${API_BASE_PATH}/follower_indices/${idString}/unfollow`); const uiMetric = ids.length > 1 ? UIM_FOLLOWER_INDEX_UNFOLLOW_MANY : UIM_FOLLOWER_INDEX_UNFOLLOW; - return trackUserRequest(request, uiMetric).then(extractData); + return trackUserRequest(request, uiMetric); }; export const updateFollowerIndex = (id, followerIndex) => { @@ -159,31 +145,28 @@ export const updateFollowerIndex = (id, followerIndex) => { if (isUsingAdvancedSettings) { uiMetrics.push(UIM_FOLLOWER_INDEX_USE_ADVANCED_OPTIONS); } - const request = httpClient.put( - `${apiPrefix}/follower_indices/${encodeURIComponent(id)}`, - followerIndex - ); - return trackUserRequest(request, uiMetrics).then(extractData); + const request = httpClient.put(`${API_BASE_PATH}/follower_indices/${encodeURIComponent(id)}`, { + body: JSON.stringify(followerIndex), + }); + return trackUserRequest(request, uiMetrics); }; /* Stats */ -export const loadAutoFollowStats = () => - httpClient.get(`${apiPrefix}/stats/auto_follow`).then(extractData); +export const loadAutoFollowStats = () => httpClient.get(`${API_BASE_PATH}/stats/auto_follow`); /* Indices */ -let canceler = null; +let abortController = null; export const loadIndices = () => { - if (canceler) { - // If there is a previous request in flight we cancel it by resolving the canceler - canceler.resolve(); + if (abortController) { + abortController.abort(); + abortController = null; } - canceler = $q.defer(); - return httpClient - .get(`${apiPrefixIndexManagement}/indices`, { timeout: canceler.promise }) - .then(response => { - canceler = null; - return extractData(response); - }); + abortController = new AbortController(); + const { signal } = abortController; + return httpClient.get(`${API_INDEX_MANAGEMENT_BASE_PATH}/indices`, { signal }).then(response => { + abortController = null; + return response; + }); }; -export const loadPermissions = () => httpClient.get(`${apiPrefix}/permissions`).then(extractData); +export const loadPermissions = () => httpClient.get(`${API_BASE_PATH}/permissions`); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/auto_follow_errors.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_errors.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/services/auto_follow_errors.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_errors.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/auto_follow_errors.test.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_errors.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/services/auto_follow_errors.test.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_errors.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/auto_follow_pattern.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/services/auto_follow_pattern.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/auto_follow_pattern.test.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/services/auto_follow_pattern.test.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/auto_follow_pattern_validators.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern_validators.js similarity index 97% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/services/auto_follow_pattern_validators.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern_validators.js index 5186a02383d33c..1b5a39658ee463 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/auto_follow_pattern_validators.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern_validators.js @@ -8,8 +8,8 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { indices } from '../../../../../../../src/plugins/es_ui_shared/public'; -import { indexPatterns } from '../../../../../../../src/plugins/data/public'; +import { indices } from '../../../../../../../../src/plugins/es_ui_shared/public'; +import { indexPatterns } from '../../../../../../../../src/plugins/data/public'; const { indexNameBeginsWithPeriod, diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/auto_follow_pattern_validators.test.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern_validators.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/services/auto_follow_pattern_validators.test.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern_validators.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/breadcrumbs.mock.ts b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/breadcrumbs.mock.ts new file mode 100644 index 00000000000000..b7c75108d4ef08 --- /dev/null +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/breadcrumbs.mock.ts @@ -0,0 +1,10 @@ +/* + * 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. + */ + +jest.mock('./breadcrumbs', () => ({ + ...jest.requireActual('./breadcrumbs'), + setBreadcrumbs: jest.fn(), +})); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/breadcrumbs.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/breadcrumbs.ts similarity index 56% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/services/breadcrumbs.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/breadcrumbs.ts index f8c8cc710964a1..dc64cdee07f7db 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/breadcrumbs.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/breadcrumbs.ts @@ -3,9 +3,27 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - import { i18n } from '@kbn/i18n'; -import { BASE_PATH } from '../../../common/constants'; +import { ChromeBreadcrumb } from 'src/core/public'; + +import { ManagementAppMountParams } from '../../../../../../../../src/plugins/management/public'; + +import { BASE_PATH } from '../../../../common/constants'; + +let setBreadcrumbs: ManagementAppMountParams['setBreadcrumbs']; + +export const setBreadcrumbSetter = ({ + __LEGACY, +}: { + __LEGACY: { + chrome: any; + MANAGEMENT_BREADCRUMB: ChromeBreadcrumb; + }; +}): void => { + setBreadcrumbs = (crumbs: ChromeBreadcrumb[]) => { + __LEGACY.chrome.breadcrumbs.set([__LEGACY.MANAGEMENT_BREADCRUMB, ...crumbs]); + }; +}; export const listBreadcrumb = { text: i18n.translate('xpack.crossClusterReplication.homeBreadcrumbTitle', { @@ -25,3 +43,5 @@ export const editBreadcrumb = { defaultMessage: 'Edit', }), }; + +export { setBreadcrumbs }; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/documentation_links.ts b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/documentation_links.ts new file mode 100644 index 00000000000000..f17926d2bee103 --- /dev/null +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/documentation_links.ts @@ -0,0 +1,22 @@ +/* + * 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. + */ + +let esBase: string; + +export const setDocLinks = ({ + DOC_LINK_VERSION, + ELASTIC_WEBSITE_URL, +}: { + ELASTIC_WEBSITE_URL: string; + DOC_LINK_VERSION: string; +}) => { + esBase = `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}`; +}; + +export const getAutoFollowPatternUrl = () => `${esBase}/ccr-put-auto-follow-pattern.html`; +export const getFollowerIndexUrl = () => `${esBase}/ccr-put-follow.html`; +export const getByteUnitsUrl = () => `${esBase}/common-options.html#byte-units`; +export const getTimeUnitsUrl = () => `${esBase}/common-options.html#time-units`; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/follower_index_default_settings.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/follower_index_default_settings.js similarity index 89% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/services/follower_index_default_settings.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/follower_index_default_settings.js index 118a54887d4049..d20fa76ef54518 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/follower_index_default_settings.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/follower_index_default_settings.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { FOLLOWER_INDEX_ADVANCED_SETTINGS } from '../../../common/constants'; +import { FOLLOWER_INDEX_ADVANCED_SETTINGS } from '../../../../common/constants'; export const getSettingDefault = name => { if (!FOLLOWER_INDEX_ADVANCED_SETTINGS[name]) { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/get_remote_cluster_name.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/get_remote_cluster_name.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/services/get_remote_cluster_name.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/get_remote_cluster_name.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/input_validation.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/input_validation.js similarity index 97% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/services/input_validation.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/input_validation.js index 981b3f59297513..64c3e8412437e4 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/input_validation.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/input_validation.js @@ -6,7 +6,7 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { indices } from '../../../../../../../src/plugins/es_ui_shared/public'; +import { indices } from '../../../../../../../../src/plugins/es_ui_shared/public'; const isEmpty = value => { return !value || !value.trim().length; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/notifications.ts b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/notifications.ts new file mode 100644 index 00000000000000..5e1c3e9e99437a --- /dev/null +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/notifications.ts @@ -0,0 +1,20 @@ +/* + * 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 { NotificationsSetup, IToasts, FatalErrorsSetup } from 'src/core/public'; + +let _notifications: IToasts; +let _fatalErrors: FatalErrorsSetup; + +export const setNotifications = ( + notifications: NotificationsSetup, + fatalErrorsSetup: FatalErrorsSetup +) => { + _notifications = notifications.toasts; + _fatalErrors = fatalErrorsSetup; +}; + +export const getNotifications = () => _notifications; +export const getFatalErrors = () => _fatalErrors; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/query_params.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/query_params.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/services/query_params.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/query_params.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/routing.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/routing.js similarity index 99% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/services/routing.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/routing.js index 487b1068794f97..965aeaaad22ad9 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/routing.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/routing.js @@ -10,7 +10,7 @@ import { createLocation } from 'history'; import { stringify } from 'query-string'; -import { APPS, BASE_PATH, BASE_PATH_REMOTE_CLUSTERS } from '../../../common/constants'; +import { APPS, BASE_PATH, BASE_PATH_REMOTE_CLUSTERS } from '../../../../common/constants'; const isModifiedEvent = event => !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/track_ui_metric.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/track_ui_metric.js similarity index 92% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/services/track_ui_metric.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/track_ui_metric.js index bd618f6a59e5cf..36b9c185b487d8 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/track_ui_metric.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/track_ui_metric.js @@ -7,7 +7,7 @@ import { createUiStatsReporter, METRIC_TYPE, -} from '../../../../../../../src/legacy/core_plugins/ui_metric/public'; +} from '../../../../../../../../src/legacy/core_plugins/ui_metric/public'; import { UIM_APP_NAME } from '../constants'; export const trackUiMetric = createUiStatsReporter(UIM_APP_NAME); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/utils.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/utils.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/services/utils.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/utils.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/services/utils.test.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/utils.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/services/utils.test.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/utils.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/store/action_types.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/action_types.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/store/action_types.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/action_types.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/store/actions/api.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/api.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/store/actions/api.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/api.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/store/actions/auto_follow_pattern.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/auto_follow_pattern.js similarity index 95% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/store/actions/auto_follow_pattern.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/auto_follow_pattern.js index 439858ad98ba34..b81cd30f3977a7 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/store/actions/auto_follow_pattern.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/auto_follow_pattern.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { i18n } from '@kbn/i18n'; -import { toastNotifications } from 'ui/notify'; +import { getNotifications } from '../../services/notifications'; import { SECTIONS, API_STATUS } from '../../constants'; import { loadAutoFollowPatterns as loadAutoFollowPatternsRequest, @@ -75,7 +75,7 @@ export const saveAutoFollowPattern = (id, autoFollowPattern, isUpdating = false) } ); - toastNotifications.addSuccess(successMessage); + getNotifications().addSuccess(successMessage); routing.navigate(`/auto_follow_patterns`, undefined, { pattern: encodeURIComponent(id), }); @@ -111,7 +111,7 @@ export const deleteAutoFollowPattern = id => } ); - toastNotifications.addDanger(errorMessage); + getNotifications().addDanger(errorMessage); } if (response.itemsDeleted.length) { @@ -133,7 +133,7 @@ export const deleteAutoFollowPattern = id => } ); - toastNotifications.addSuccess(successMessage); + getNotifications().addSuccess(successMessage); // If we've just deleted a pattern we were looking at, we need to close the panel. const autoFollowPatternId = getSelectedAutoFollowPatternId('detail')(getState()); @@ -173,7 +173,7 @@ export const pauseAutoFollowPattern = id => } ); - toastNotifications.addDanger(errorMessage); + getNotifications().addDanger(errorMessage); } if (response.itemsPaused.length) { @@ -195,7 +195,7 @@ export const pauseAutoFollowPattern = id => } ); - toastNotifications.addSuccess(successMessage); + getNotifications().addSuccess(successMessage); } }, }); @@ -229,7 +229,7 @@ export const resumeAutoFollowPattern = id => } ); - toastNotifications.addDanger(errorMessage); + getNotifications().addDanger(errorMessage); } if (response.itemsResumed.length) { @@ -251,7 +251,7 @@ export const resumeAutoFollowPattern = id => } ); - toastNotifications.addSuccess(successMessage); + getNotifications().addSuccess(successMessage); } }, }); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/store/actions/ccr.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/ccr.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/store/actions/ccr.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/ccr.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/store/actions/follower_index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/follower_index.js similarity index 95% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/store/actions/follower_index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/follower_index.js index da1c2599744988..ebdee067ced75f 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/app/store/actions/follower_index.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/follower_index.js @@ -4,8 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ import { i18n } from '@kbn/i18n'; -import { toastNotifications } from 'ui/notify'; + import routing from '../../services/routing'; +import { getNotifications } from '../../services/notifications'; import { SECTIONS, API_STATUS } from '../../constants'; import { loadFollowerIndices as loadFollowerIndicesRequest, @@ -75,7 +76,7 @@ export const saveFollowerIndex = (name, followerIndex, isUpdating = false) => } ); - toastNotifications.addSuccess(successMessage); + getNotifications().addSuccess(successMessage); routing.navigate(`/follower_indices`, undefined, { name: encodeURIComponent(name), }); @@ -111,7 +112,7 @@ export const pauseFollowerIndex = id => } ); - toastNotifications.addDanger(errorMessage); + getNotifications().addDanger(errorMessage); } if (response.itemsPaused.length) { @@ -133,7 +134,7 @@ export const pauseFollowerIndex = id => } ); - toastNotifications.addSuccess(successMessage); + getNotifications().addSuccess(successMessage); // Refresh list dispatch(loadFollowerIndices(true)); @@ -170,7 +171,7 @@ export const resumeFollowerIndex = id => } ); - toastNotifications.addDanger(errorMessage); + getNotifications().addDanger(errorMessage); } if (response.itemsResumed.length) { @@ -192,7 +193,7 @@ export const resumeFollowerIndex = id => } ); - toastNotifications.addSuccess(successMessage); + getNotifications().addSuccess(successMessage); } // Refresh list @@ -229,7 +230,7 @@ export const unfollowLeaderIndex = id => } ); - toastNotifications.addDanger(errorMessage); + getNotifications().addDanger(errorMessage); } if (response.itemsUnfollowed.length) { @@ -251,7 +252,7 @@ export const unfollowLeaderIndex = id => } ); - toastNotifications.addSuccess(successMessage); + getNotifications().addSuccess(successMessage); } if (response.itemsNotOpen.length) { @@ -273,7 +274,7 @@ export const unfollowLeaderIndex = id => } ); - toastNotifications.addWarning(warningMessage); + getNotifications().addWarning(warningMessage); } // If we've just unfollowed a follower index we were looking at, we need to close the panel. diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/store/actions/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/store/actions/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/store/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/store/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/store/reducers/api.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/api.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/store/reducers/api.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/api.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/store/reducers/api.test.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/api.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/store/reducers/api.test.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/api.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/store/reducers/auto_follow_pattern.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/auto_follow_pattern.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/store/reducers/auto_follow_pattern.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/auto_follow_pattern.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/store/reducers/follower_index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/follower_index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/store/reducers/follower_index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/follower_index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/store/reducers/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/store/reducers/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/store/reducers/stats.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/stats.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/store/reducers/stats.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/stats.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/store/selectors/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/selectors/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/store/selectors/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/selectors/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/app/store/store.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/store.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/app/store/store.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/store.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/extend_index_management/index.js b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/extend_index_management.ts similarity index 67% rename from x-pack/legacy/plugins/cross_cluster_replication/public/extend_index_management/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/extend_index_management.ts index c44918c500849b..01c6250383fb8f 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/extend_index_management/index.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/extend_index_management.ts @@ -3,14 +3,15 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + import { i18n } from '@kbn/i18n'; -import { npSetup } from 'ui/new_platform'; import { get } from 'lodash'; +import { IndexMgmtSetup } from '../../../../../plugins/index_management/public'; const propertyPath = 'isFollowerIndex'; const followerBadgeExtension = { - matchIndex: index => { + matchIndex: (index: any) => { return get(index, propertyPath); }, label: i18n.translate('xpack.crossClusterReplication.indexMgmtBadge.followerLabel', { @@ -20,6 +21,8 @@ const followerBadgeExtension = { filterExpression: 'isFollowerIndex:true', }; -if (npSetup.plugins.indexManagement) { - npSetup.plugins.indexManagement.extensionsService.addBadge(followerBadgeExtension); -} +export const extendIndexManagement = (indexManagement?: IndexMgmtSetup) => { + if (indexManagement) { + indexManagement.extensionsService.addBadge(followerBadgeExtension); + } +}; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/index.ts b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/index.ts new file mode 100644 index 00000000000000..11aea6b7b5de43 --- /dev/null +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/index.ts @@ -0,0 +1,11 @@ +/* + * 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 { PluginInitializerContext } from 'src/core/public'; + +import { CrossClusterReplicationUIPlugin } from './plugin'; + +export const plugin = (ctx: PluginInitializerContext) => new CrossClusterReplicationUIPlugin(ctx); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/plugin.ts b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/plugin.ts new file mode 100644 index 00000000000000..f7651cbb210a74 --- /dev/null +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/plugin.ts @@ -0,0 +1,44 @@ +/* + * 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 { + ChromeBreadcrumb, + CoreSetup, + Plugin, + PluginInitializerContext, + DocLinksStart, +} from 'src/core/public'; + +import { IndexMgmtSetup } from '../../../../../plugins/index_management/public'; + +// @ts-ignore; +import { setHttpClient } from './app/services/api'; +import { setBreadcrumbSetter } from './app/services/breadcrumbs'; +import { setDocLinks } from './app/services/documentation_links'; +import { setNotifications } from './app/services/notifications'; +import { extendIndexManagement } from './extend_index_management'; + +interface PluginDependencies { + indexManagement: IndexMgmtSetup; + __LEGACY: { + chrome: any; + MANAGEMENT_BREADCRUMB: ChromeBreadcrumb; + docLinks: DocLinksStart; + }; +} + +export class CrossClusterReplicationUIPlugin implements Plugin { + // @ts-ignore + constructor(private readonly ctx: PluginInitializerContext) {} + setup({ http, notifications, fatalErrors }: CoreSetup, deps: PluginDependencies) { + setHttpClient(http); + setBreadcrumbSetter(deps); + setDocLinks(deps.__LEGACY.docLinks); + setNotifications(notifications, fatalErrors); + extendIndexManagement(deps.indexManagement); + } + + start() {} +} diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/register_routes.js b/x-pack/legacy/plugins/cross_cluster_replication/public/register_routes.js index 7b9ba07f46c188..838939f46e5233 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/register_routes.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/public/register_routes.js @@ -6,15 +6,21 @@ import { unmountComponentAtNode } from 'react-dom'; import chrome from 'ui/chrome'; -import { management } from 'ui/management'; +import { management, MANAGEMENT_BREADCRUMB } from 'ui/management'; +import { npSetup, npStart } from 'ui/new_platform'; import routes from 'ui/routes'; import { xpackInfo } from 'plugins/xpack_main/services/xpack_info'; import { i18n } from '@kbn/i18n'; import template from './main.html'; import { BASE_PATH } from '../common/constants'; -import { renderReact } from './app'; -import { setHttpClient } from './app/services/api'; + +import { plugin } from './np_ready'; + +/** + * TODO: When this file is deleted, use the management section for rendering + */ +import { renderReact } from './np_ready/app'; const isAvailable = xpackInfo.get('features.crossClusterReplication.isAvailable'); const isActive = xpackInfo.get('features.crossClusterReplication.isActive'); @@ -37,26 +43,31 @@ if (isLicenseOK && isCcrUiEnabled) { const CCR_REACT_ROOT = 'ccrReactRoot'; + plugin({}).setup(npSetup.core, { + ...npSetup.plugins, + __LEGACY: { + chrome, + docLinks: npStart.core.docLinks, + MANAGEMENT_BREADCRUMB, + }, + }); + const unmountReactApp = () => elem && unmountComponentAtNode(elem); routes.when(`${BASE_PATH}/:section?/:subsection?/:view?/:id?`, { template, controllerAs: 'ccr', controller: class CrossClusterReplicationController { - constructor($scope, $route, $http, $q) { + constructor($scope, $route) { // React-router's does not play well with the angular router. It will cause this controller // to re-execute without the $destroy handler being called. This means that the app will be mounted twice // creating a memory leak when leaving (only 1 app will be unmounted). // To avoid this, we unmount the React app each time we enter the controller. unmountReactApp(); - // NOTE: We depend upon Angular's $http service because it's decorated with interceptors, - // e.g. to check license status per request. - setHttpClient($http, $q); - $scope.$$postDigest(() => { elem = document.getElementById(CCR_REACT_ROOT); - renderReact(elem); + renderReact(elem, npStart.core.i18n.Context); // Angular Lifecycle const appRoute = $route.current; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/__tests__/wrap_custom_error.js b/x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/__tests__/wrap_custom_error.js deleted file mode 100644 index f9c102be7a1ff3..00000000000000 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/__tests__/wrap_custom_error.js +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import expect from '@kbn/expect'; -import { wrapCustomError } from '../wrap_custom_error'; - -describe('wrap_custom_error', () => { - describe('#wrapCustomError', () => { - it('should return a Boom object', () => { - const originalError = new Error('I am an error'); - const statusCode = 404; - const wrappedError = wrapCustomError(originalError, statusCode); - - expect(wrappedError.isBoom).to.be(true); - expect(wrappedError.output.statusCode).to.equal(statusCode); - }); - }); -}); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/__tests__/wrap_unknown_error.js b/x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/__tests__/wrap_unknown_error.js deleted file mode 100644 index 85e0b2b3033ad4..00000000000000 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/__tests__/wrap_unknown_error.js +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import expect from '@kbn/expect'; -import { wrapUnknownError } from '../wrap_unknown_error'; - -describe('wrap_unknown_error', () => { - describe('#wrapUnknownError', () => { - it('should return a Boom object', () => { - const originalError = new Error('I am an error'); - const wrappedError = wrapUnknownError(originalError); - - expect(wrappedError.isBoom).to.be(true); - }); - }); -}); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/wrap_custom_error.js b/x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/wrap_custom_error.js deleted file mode 100644 index 3295113d38ee5a..00000000000000 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/wrap_custom_error.js +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Boom from 'boom'; - -/** - * Wraps a custom error into a Boom error response and returns it - * - * @param err Object error - * @param statusCode Error status code - * @return Object Boom error response - */ -export function wrapCustomError(err, statusCode) { - return Boom.boomify(err, { statusCode }); -} diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/__tests__/license_pre_routing_factory.js b/x-pack/legacy/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/__tests__/license_pre_routing_factory.js deleted file mode 100644 index a73aa96209c262..00000000000000 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/__tests__/license_pre_routing_factory.js +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import expect from '@kbn/expect'; -import { licensePreRoutingFactory } from '../license_pre_routing_factory'; - -describe('license_pre_routing_factory', () => { - describe('#reportingFeaturePreRoutingFactory', () => { - let mockServer; - let mockLicenseCheckResults; - - beforeEach(() => { - mockServer = { - plugins: { - xpack_main: { - info: { - feature: () => ({ - getLicenseCheckResults: () => mockLicenseCheckResults, - }), - }, - }, - }, - }; - }); - - it('only instantiates one instance per server', () => { - const firstInstance = licensePreRoutingFactory(mockServer); - const secondInstance = licensePreRoutingFactory(mockServer); - - expect(firstInstance).to.be(secondInstance); - }); - - describe('isAvailable is false', () => { - beforeEach(() => { - mockLicenseCheckResults = { - isAvailable: false, - }; - }); - - it('replies with 403', () => { - const licensePreRouting = licensePreRoutingFactory(mockServer); - const response = licensePreRouting(); - expect(response).to.be.an(Error); - expect(response.isBoom).to.be(true); - expect(response.output.statusCode).to.be(403); - }); - }); - - describe('isAvailable is true', () => { - beforeEach(() => { - mockLicenseCheckResults = { - isAvailable: true, - }; - }); - - it('replies with nothing', () => { - const licensePreRouting = licensePreRoutingFactory(mockServer); - const response = licensePreRouting(); - expect(response).to.be(null); - }); - }); - }); -}); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/license_pre_routing_factory.js b/x-pack/legacy/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/license_pre_routing_factory.js deleted file mode 100644 index 548ad7ca02104a..00000000000000 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/license_pre_routing_factory.js +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { once } from 'lodash'; -import { wrapCustomError } from '../error_wrappers'; -import { PLUGIN } from '../../../common/constants'; - -export const licensePreRoutingFactory = once(server => { - const xpackMainPlugin = server.plugins.xpack_main; - - // License checking and enable/disable logic - function licensePreRouting() { - const licenseCheckResults = xpackMainPlugin.info.feature(PLUGIN.ID).getLicenseCheckResults(); - if (!licenseCheckResults.isAvailable) { - const error = new Error(licenseCheckResults.message); - const statusCode = 403; - const wrappedError = wrapCustomError(error, statusCode); - return wrappedError; - } else { - return null; - } - } - - return licensePreRouting; -}); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/client/elasticsearch_ccr.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/client/elasticsearch_ccr.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/client/elasticsearch_ccr.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/client/elasticsearch_ccr.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/cross_cluster_replication_data.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/cross_cluster_replication_data.ts similarity index 59% rename from x-pack/legacy/plugins/cross_cluster_replication/cross_cluster_replication_data.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/cross_cluster_replication_data.ts index 2944c3e6bc2ecd..ae15073b979e1e 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/cross_cluster_replication_data.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/cross_cluster_replication_data.ts @@ -3,9 +3,11 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +import { APICaller } from 'src/core/server'; +import { Index } from '../../../../../plugins/index_management/server'; -export const ccrDataEnricher = async (indicesList, callWithRequest) => { - if (!indicesList || !indicesList.length) { +export const ccrDataEnricher = async (indicesList: Index[], callWithRequest: APICaller) => { + if (!indicesList?.length) { return indicesList; } const params = { @@ -18,9 +20,11 @@ export const ccrDataEnricher = async (indicesList, callWithRequest) => { params ); return indicesList.map(index => { - const isFollowerIndex = !!followerIndices.find(followerIndex => { - return followerIndex.follower_index === index.name; - }); + const isFollowerIndex = !!followerIndices.find( + (followerIndex: { follower_index: string }) => { + return followerIndex.follower_index === index.name; + } + ); return { ...index, isFollowerIndex, diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/index.ts b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/index.ts new file mode 100644 index 00000000000000..7a38d024d99a2a --- /dev/null +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/index.ts @@ -0,0 +1,11 @@ +/* + * 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 { PluginInitializerContext } from 'src/core/server'; +import { CrossClusterReplicationServerPlugin } from './plugin'; + +export const plugin = (ctx: PluginInitializerContext) => + new CrossClusterReplicationServerPlugin(ctx); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/__snapshots__/ccr_stats_serialization.test.js.snap b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/__snapshots__/ccr_stats_serialization.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/lib/__snapshots__/ccr_stats_serialization.test.js.snap rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/__snapshots__/ccr_stats_serialization.test.js.snap diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/call_with_request_factory/call_with_request_factory.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/call_with_request_factory/call_with_request_factory.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/lib/call_with_request_factory/call_with_request_factory.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/call_with_request_factory/call_with_request_factory.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/call_with_request_factory/index.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/call_with_request_factory/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/lib/call_with_request_factory/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/call_with_request_factory/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/ccr_stats_serialization.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/ccr_stats_serialization.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.test.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/ccr_stats_serialization.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.test.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/ccr_stats_serialization.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/check_license/check_license.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/check_license/check_license.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/lib/check_license/check_license.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/check_license/check_license.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/check_license/index.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/check_license/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/lib/check_license/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/check_license/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/__tests__/wrap_es_error.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/error_wrappers/__tests__/wrap_es_error.test.js similarity index 55% rename from x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/__tests__/wrap_es_error.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/error_wrappers/__tests__/wrap_es_error.test.js index 8241dc43291371..11a6fd4e1d816a 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/__tests__/wrap_es_error.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/error_wrappers/__tests__/wrap_es_error.test.js @@ -16,24 +16,18 @@ describe('wrap_es_error', () => { originalError.response = '{}'; }); - it('should return a Boom object', () => { + it('should return the correct object', () => { const wrappedError = wrapEsError(originalError); - expect(wrappedError.isBoom).to.be(true); + expect(wrappedError.statusCode).to.be(originalError.statusCode); + expect(wrappedError.message).to.be(originalError.message); }); - it('should return the correct Boom object', () => { - const wrappedError = wrapEsError(originalError); - - expect(wrappedError.output.statusCode).to.be(originalError.statusCode); - expect(wrappedError.output.payload.message).to.be(originalError.message); - }); - - it('should return the correct Boom object with custom message', () => { + it('should return the correct object with custom message', () => { const wrappedError = wrapEsError(originalError, { 404: 'No encontrado!' }); - expect(wrappedError.output.statusCode).to.be(originalError.statusCode); - expect(wrappedError.output.payload.message).to.be('No encontrado!'); + expect(wrappedError.statusCode).to.be(originalError.statusCode); + expect(wrappedError.message).to.be('No encontrado!'); }); }); }); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/index.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/error_wrappers/index.ts similarity index 72% rename from x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/error_wrappers/index.ts index f275f156370912..3756b0c74fb102 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/index.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/error_wrappers/index.ts @@ -4,6 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { wrapCustomError } from './wrap_custom_error'; export { wrapEsError } from './wrap_es_error'; -export { wrapUnknownError } from './wrap_unknown_error'; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/wrap_es_error.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/error_wrappers/wrap_es_error.ts similarity index 66% rename from x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/wrap_es_error.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/error_wrappers/wrap_es_error.ts index 5f4884a3f2d266..8afd5f1a018ebd 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/wrap_es_error.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/error_wrappers/wrap_es_error.ts @@ -4,16 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ -import Boom from 'boom'; - -function extractCausedByChain(causedBy = {}, accumulator = []) { - const { reason, caused_by } = causedBy; // eslint-disable-line camelcase +function extractCausedByChain( + causedBy: Record = {}, + accumulator: string[] = [] +): string[] { + const { reason, caused_by } = causedBy; // eslint-disable-line @typescript-eslint/camelcase if (reason) { accumulator.push(reason); } - // eslint-disable-next-line camelcase + // eslint-disable-next-line @typescript-eslint/camelcase if (caused_by) { return extractCausedByChain(caused_by, accumulator); } @@ -26,34 +27,39 @@ function extractCausedByChain(causedBy = {}, accumulator = []) { * * @param err Object Error thrown by ES JS client * @param statusCodeToMessageMap Object Optional map of HTTP status codes => error messages - * @return Object Boom error response */ -export function wrapEsError(err, statusCodeToMessageMap = {}) { +export function wrapEsError( + err: any, + statusCodeToMessageMap: Record = {} +): { message: string; body?: { cause?: string[] }; statusCode: number } { const { statusCode, response } = err; const { error: { - root_cause = [], // eslint-disable-line camelcase - caused_by, // eslint-disable-line camelcase + root_cause = [], // eslint-disable-line @typescript-eslint/camelcase + caused_by = undefined, // eslint-disable-line @typescript-eslint/camelcase } = {}, } = JSON.parse(response); // If no custom message if specified for the error's status code, just // wrap the error as a Boom error response and return it if (!statusCodeToMessageMap[statusCode]) { - const boomError = Boom.boomify(err, { statusCode }); - // The caused_by chain has the most information so use that if it's available. If not then // settle for the root_cause. const causedByChain = extractCausedByChain(caused_by); const defaultCause = root_cause.length ? extractCausedByChain(root_cause[0]) : undefined; - boomError.output.payload.cause = causedByChain.length ? causedByChain : defaultCause; - return boomError; + return { + message: err.message, + statusCode, + body: { + cause: causedByChain.length ? causedByChain : defaultCause, + }, + }; } // Otherwise, use the custom message to create a Boom error response and // return it const message = statusCodeToMessageMap[statusCode]; - return new Boom(message, { statusCode }); + return { message, statusCode }; } diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/wrap_unknown_error.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/is_es_error.ts similarity index 50% rename from x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/wrap_unknown_error.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/is_es_error.ts index ffd915c5133626..4137293cf39c06 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/error_wrappers/wrap_unknown_error.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/is_es_error.ts @@ -4,14 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import Boom from 'boom'; +import * as legacyElasticsearch from 'elasticsearch'; -/** - * Wraps an unknown error into a Boom error response and returns it - * - * @param err Object Unknown error - * @return Object Boom error response - */ -export function wrapUnknownError(err) { - return Boom.boomify(err); +const esErrorsParent = legacyElasticsearch.errors._Abstract; + +export function isEsError(err: Error) { + return err instanceof esErrorsParent; } diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/is_es_error_factory/__tests__/is_es_error_factory.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/is_es_error_factory/__tests__/is_es_error_factory.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/lib/is_es_error_factory/__tests__/is_es_error_factory.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/is_es_error_factory/__tests__/is_es_error_factory.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/is_es_error_factory/index.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/is_es_error_factory/index.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/lib/is_es_error_factory/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/is_es_error_factory/index.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/is_es_error_factory/is_es_error_factory.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/is_es_error_factory/is_es_error_factory.ts similarity index 76% rename from x-pack/legacy/plugins/cross_cluster_replication/server/lib/is_es_error_factory/is_es_error_factory.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/is_es_error_factory/is_es_error_factory.ts index 6c17554385ef85..fc6405b8e75133 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/is_es_error_factory/is_es_error_factory.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/is_es_error_factory/is_es_error_factory.ts @@ -6,13 +6,13 @@ import { memoize } from 'lodash'; -const esErrorsFactory = memoize(server => { +const esErrorsFactory = memoize((server: any) => { return server.plugins.elasticsearch.getCluster('admin').errors; }); -export function isEsErrorFactory(server) { +export function isEsErrorFactory(server: any) { const esErrors = esErrorsFactory(server); - return function isEsError(err) { + return function isEsError(err: any) { return err instanceof esErrors._Abstract; }; } diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/license_pre_routing_factory/__jest__/license_pre_routing_factory.test.ts b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/license_pre_routing_factory/__jest__/license_pre_routing_factory.test.ts new file mode 100644 index 00000000000000..d22505f0e315ad --- /dev/null +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/license_pre_routing_factory/__jest__/license_pre_routing_factory.test.ts @@ -0,0 +1,64 @@ +/* + * 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 { kibanaResponseFactory } from '../../../../../../../../../src/core/server'; +import { licensePreRoutingFactory } from '../license_pre_routing_factory'; + +describe('license_pre_routing_factory', () => { + describe('#reportingFeaturePreRoutingFactory', () => { + let mockDeps: any; + let mockLicenseCheckResults: any; + + const anyContext: any = {}; + const anyRequest: any = {}; + + beforeEach(() => { + mockDeps = { + __LEGACY: { + server: { + plugins: { + xpack_main: { + info: { + feature: () => ({ + getLicenseCheckResults: () => mockLicenseCheckResults, + }), + }, + }, + }, + }, + }, + requestHandler: jest.fn(), + }; + }); + + describe('isAvailable is false', () => { + beforeEach(() => { + mockLicenseCheckResults = { + isAvailable: false, + }; + }); + + it('replies with 403', async () => { + const licensePreRouting = licensePreRoutingFactory(mockDeps); + const response = await licensePreRouting(anyContext, anyRequest, kibanaResponseFactory); + expect(response.status).toBe(403); + }); + }); + + describe('isAvailable is true', () => { + beforeEach(() => { + mockLicenseCheckResults = { + isAvailable: true, + }; + }); + + it('it calls the wrapped handler', async () => { + const licensePreRouting = licensePreRoutingFactory(mockDeps); + await licensePreRouting(anyContext, anyRequest, kibanaResponseFactory); + expect(mockDeps.requestHandler).toHaveBeenCalledTimes(1); + }); + }); + }); +}); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/index.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/license_pre_routing_factory/index.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/license_pre_routing_factory/index.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/license_pre_routing_factory/license_pre_routing_factory.ts b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/license_pre_routing_factory/license_pre_routing_factory.ts new file mode 100644 index 00000000000000..c47faa940a6503 --- /dev/null +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/license_pre_routing_factory/license_pre_routing_factory.ts @@ -0,0 +1,32 @@ +/* + * 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 { RequestHandler } from 'src/core/server'; +import { PLUGIN } from '../../../../common/constants'; + +export const licensePreRoutingFactory = ({ + __LEGACY, + requestHandler, +}: { + __LEGACY: { server: any }; + requestHandler: RequestHandler; +}) => { + const xpackMainPlugin = __LEGACY.server.plugins.xpack_main; + + // License checking and enable/disable logic + const licensePreRouting: RequestHandler = (ctx, request, response) => { + const licenseCheckResults = xpackMainPlugin.info.feature(PLUGIN.ID).getLicenseCheckResults(); + if (!licenseCheckResults.isAvailable) { + return response.forbidden({ + body: licenseCheckResults.message, + }); + } else { + return requestHandler(ctx, request, response); + } + }; + + return licensePreRouting; +}; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/register_license_checker/index.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/register_license_checker/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/lib/register_license_checker/index.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/register_license_checker/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/register_license_checker/register_license_checker.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/register_license_checker/register_license_checker.js similarity index 66% rename from x-pack/legacy/plugins/cross_cluster_replication/server/lib/register_license_checker/register_license_checker.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/register_license_checker/register_license_checker.js index dbd99efd955734..b9bb34a80ce796 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/lib/register_license_checker/register_license_checker.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/register_license_checker/register_license_checker.js @@ -4,13 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { mirrorPluginStatus } from '../../../../../server/lib/mirror_plugin_status'; -import { PLUGIN } from '../../../common/constants'; +import { mirrorPluginStatus } from '../../../../../../server/lib/mirror_plugin_status'; +import { PLUGIN } from '../../../../common/constants'; import { checkLicense } from '../check_license'; -export function registerLicenseChecker(server) { - const xpackMainPlugin = server.plugins.xpack_main; - const ccrPluggin = server.plugins[PLUGIN.ID]; +export function registerLicenseChecker(__LEGACY) { + const xpackMainPlugin = __LEGACY.server.plugins.xpack_main; + const ccrPluggin = __LEGACY.server.plugins[PLUGIN.ID]; mirrorPluginStatus(xpackMainPlugin, ccrPluggin); xpackMainPlugin.status.once('green', () => { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/plugin.ts b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/plugin.ts new file mode 100644 index 00000000000000..1012c07af3d2ae --- /dev/null +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/plugin.ts @@ -0,0 +1,38 @@ +/* + * 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 { Plugin, PluginInitializerContext, CoreSetup } from 'src/core/server'; + +import { IndexMgmtSetup } from '../../../../../plugins/index_management/server'; + +// @ts-ignore +import { registerLicenseChecker } from './lib/register_license_checker'; +// @ts-ignore +import { registerRoutes } from './routes/register_routes'; +import { ccrDataEnricher } from './cross_cluster_replication_data'; + +interface PluginDependencies { + indexManagement: IndexMgmtSetup; + __LEGACY: { + server: any; + ccrUIEnabled: boolean; + }; +} + +export class CrossClusterReplicationServerPlugin implements Plugin { + // @ts-ignore + constructor(private readonly ctx: PluginInitializerContext) {} + setup({ http }: CoreSetup, { indexManagement, __LEGACY }: PluginDependencies) { + registerLicenseChecker(__LEGACY); + + const router = http.createRouter(); + registerRoutes({ router, __LEGACY }); + if (__LEGACY.ccrUIEnabled && indexManagement && indexManagement.indexDataEnricher) { + indexManagement.indexDataEnricher.add(ccrDataEnricher); + } + } + start() {} +} diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern.test.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/__jest__/auto_follow_pattern.test.js similarity index 68% rename from x-pack/legacy/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern.test.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/__jest__/auto_follow_pattern.test.js index c610039cfd2aca..f3024515c7213d 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern.test.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/__jest__/auto_follow_pattern.test.js @@ -3,23 +3,23 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +import { deserializeAutoFollowPattern } from '../../../../../common/services/auto_follow_pattern_serialization'; +import { callWithRequestFactory } from '../../../lib/call_with_request_factory'; +import { isEsErrorFactory } from '../../../lib/is_es_error_factory'; +import { getAutoFollowPatternMock, getAutoFollowPatternListMock } from '../../../../../fixtures'; +import { registerAutoFollowPatternRoutes } from '../auto_follow_pattern'; -import { deserializeAutoFollowPattern } from '../../../common/services/auto_follow_pattern_serialization'; -import { callWithRequestFactory } from '../../lib/call_with_request_factory'; -import { isEsErrorFactory } from '../../lib/is_es_error_factory'; -import { getAutoFollowPatternMock, getAutoFollowPatternListMock } from '../../../fixtures'; -import { registerAutoFollowPatternRoutes } from './auto_follow_pattern'; +import { createRouter, callRoute } from './helpers'; -jest.mock('../../lib/call_with_request_factory'); -jest.mock('../../lib/is_es_error_factory'); -jest.mock('../../lib/license_pre_routing_factory'); +jest.mock('../../../lib/call_with_request_factory'); +jest.mock('../../../lib/is_es_error_factory'); +jest.mock('../../../lib/license_pre_routing_factory', () => ({ + licensePreRoutingFactory: ({ requestHandler }) => requestHandler, +})); const DESERIALIZED_KEYS = Object.keys(deserializeAutoFollowPattern(getAutoFollowPatternMock())); -/** - * Hashtable to save the route handlers - */ -const routeHandlers = {}; +let routeRegistry; /** * Helper to extract all the different server route handler so we can easily call them in our tests. @@ -28,8 +28,6 @@ const routeHandlers = {}; * if a "server.route()" call is moved or deleted, then the HANDLER_INDEX_TO_ACTION must be updated here. */ const registerHandlers = () => { - let index = 0; - const HANDLER_INDEX_TO_ACTION = { 0: 'list', 1: 'create', @@ -40,15 +38,12 @@ const registerHandlers = () => { 6: 'resume', }; - const server = { - route({ handler }) { - // Save handler and increment index - routeHandlers[HANDLER_INDEX_TO_ACTION[index]] = handler; - index++; - }, - }; + routeRegistry = createRouter(HANDLER_INDEX_TO_ACTION); - registerAutoFollowPatternRoutes(server); + registerAutoFollowPatternRoutes({ + __LEGACY: {}, + router: routeRegistry.router, + }); }; /** @@ -94,14 +89,16 @@ describe('[CCR API Routes] Auto Follow Pattern', () => { describe('list()', () => { beforeEach(() => { - routeHandler = routeHandlers.list; + routeHandler = routeRegistry.getRoutes().list; }); it('should deserialize the response from Elasticsearch', async () => { const totalResult = 2; setHttpRequestResponse(null, getAutoFollowPatternListMock(totalResult)); - const response = await routeHandler(); + const { + options: { body: response }, + } = await callRoute(routeHandler); const autoFollowPattern = response.patterns[0]; expect(response.patterns.length).toEqual(totalResult); @@ -112,21 +109,25 @@ describe('[CCR API Routes] Auto Follow Pattern', () => { describe('create()', () => { beforeEach(() => { resetHttpRequestResponses(); - routeHandler = routeHandlers.create; + routeHandler = routeRegistry.getRoutes().create; }); it('should throw a 409 conflict error if id already exists', async () => { setHttpRequestResponse(null, { acknowledge: true }); setHttpRequestResponse(null, { acknowledge: true }); - const response = await routeHandler({ - payload: { - id: 'some-id', - foo: 'bar', - }, - }).catch(err => err); // return the error - - expect(response.output.statusCode).toEqual(409); + const response = await callRoute( + routeHandler, + {}, + { + body: { + id: 'some-id', + foo: 'bar', + }, + } + ); + + expect(response.status).toEqual(409); }); it('should return 200 status when the id does not exist', async () => { @@ -135,12 +136,18 @@ describe('[CCR API Routes] Auto Follow Pattern', () => { setHttpRequestResponse(error); setHttpRequestResponse(null, { acknowledge: true }); - const response = await routeHandler({ - payload: { - id: 'some-id', - foo: 'bar', - }, - }); + const { + options: { body: response }, + } = await callRoute( + routeHandler, + {}, + { + body: { + id: 'some-id', + foo: 'bar', + }, + } + ); expect(response).toEqual({ acknowledge: true }); }); @@ -148,7 +155,7 @@ describe('[CCR API Routes] Auto Follow Pattern', () => { describe('update()', () => { beforeEach(() => { - routeHandler = routeHandlers.update; + routeHandler = routeRegistry.getRoutes().update; }); it('should serialize the payload before sending it to Elasticsearch', async () => { @@ -156,16 +163,16 @@ describe('[CCR API Routes] Auto Follow Pattern', () => { const request = { params: { id: 'foo' }, - payload: { + body: { remoteCluster: 'bar1', leaderIndexPatterns: ['bar2'], followIndexPattern: 'bar3', }, }; - const response = await routeHandler(request); + const response = await callRoute(routeHandler, {}, request); - expect(response).toEqual({ + expect(response.options.body).toEqual({ id: 'foo', body: { remote_cluster: 'bar1', @@ -178,7 +185,7 @@ describe('[CCR API Routes] Auto Follow Pattern', () => { describe('get()', () => { beforeEach(() => { - routeHandler = routeHandlers.get; + routeHandler = routeRegistry.getRoutes().get; }); it('should return a single resource even though ES return an array with 1 item', async () => { @@ -187,21 +194,23 @@ describe('[CCR API Routes] Auto Follow Pattern', () => { setHttpRequestResponse(null, esResponse); - const response = await routeHandler({ params: { id: 1 } }); - expect(Object.keys(response)).toEqual(DESERIALIZED_KEYS); + const response = await callRoute(routeHandler, {}, { params: { id: 1 } }); + expect(Object.keys(response.options.body)).toEqual(DESERIALIZED_KEYS); }); }); describe('delete()', () => { beforeEach(() => { resetHttpRequestResponses(); - routeHandler = routeHandlers.delete; + routeHandler = routeRegistry.getRoutes().delete; }); it('should delete a single item', async () => { setHttpRequestResponse(null, { acknowledge: true }); - const response = await routeHandler({ params: { id: 'a' } }); + const { + options: { body: response }, + } = await callRoute(routeHandler, {}, { params: { id: 'a' } }); expect(response.itemsDeleted).toEqual(['a']); expect(response.errors).toEqual([]); @@ -212,9 +221,9 @@ describe('[CCR API Routes] Auto Follow Pattern', () => { setHttpRequestResponse(null, { acknowledge: true }); setHttpRequestResponse(null, { acknowledge: true }); - const response = await routeHandler({ params: { id: 'a,b,c' } }); + const response = await callRoute(routeHandler, {}, { params: { id: 'a,b,c' } }); - expect(response.itemsDeleted).toEqual(['a', 'b', 'c']); + expect(response.options.body.itemsDeleted).toEqual(['a', 'b', 'c']); }); it('should catch error and return them in array', async () => { @@ -224,7 +233,9 @@ describe('[CCR API Routes] Auto Follow Pattern', () => { setHttpRequestResponse(null, { acknowledge: true }); setHttpRequestResponse(error); - const response = await routeHandler({ params: { id: 'a,b' } }); + const { + options: { body: response }, + } = await callRoute(routeHandler, {}, { params: { id: 'a,b' } }); expect(response.itemsDeleted).toEqual(['a']); expect(response.errors[0].id).toEqual('b'); @@ -234,13 +245,15 @@ describe('[CCR API Routes] Auto Follow Pattern', () => { describe('pause()', () => { beforeEach(() => { resetHttpRequestResponses(); - routeHandler = routeHandlers.pause; + routeHandler = routeRegistry.getRoutes().pause; }); it('accept a single item', async () => { setHttpRequestResponse(null, { acknowledge: true }); - const response = await routeHandler({ params: { id: 'a' } }); + const { + options: { body: response }, + } = await callRoute(routeHandler, {}, { params: { id: 'a' } }); expect(response.itemsPaused).toEqual(['a']); expect(response.errors).toEqual([]); @@ -251,9 +264,9 @@ describe('[CCR API Routes] Auto Follow Pattern', () => { setHttpRequestResponse(null, { acknowledge: true }); setHttpRequestResponse(null, { acknowledge: true }); - const response = await routeHandler({ params: { id: 'a,b,c' } }); + const response = await callRoute(routeHandler, {}, { params: { id: 'a,b,c' } }); - expect(response.itemsPaused).toEqual(['a', 'b', 'c']); + expect(response.options.body.itemsPaused).toEqual(['a', 'b', 'c']); }); it('should catch error and return them in array', async () => { @@ -263,7 +276,9 @@ describe('[CCR API Routes] Auto Follow Pattern', () => { setHttpRequestResponse(null, { acknowledge: true }); setHttpRequestResponse(error); - const response = await routeHandler({ params: { id: 'a,b' } }); + const { + options: { body: response }, + } = await callRoute(routeHandler, {}, { params: { id: 'a,b' } }); expect(response.itemsPaused).toEqual(['a']); expect(response.errors[0].id).toEqual('b'); @@ -273,13 +288,15 @@ describe('[CCR API Routes] Auto Follow Pattern', () => { describe('resume()', () => { beforeEach(() => { resetHttpRequestResponses(); - routeHandler = routeHandlers.resume; + routeHandler = routeRegistry.getRoutes().resume; }); it('accept a single item', async () => { setHttpRequestResponse(null, { acknowledge: true }); - const response = await routeHandler({ params: { id: 'a' } }); + const { + options: { body: response }, + } = await callRoute(routeHandler, {}, { params: { id: 'a' } }); expect(response.itemsResumed).toEqual(['a']); expect(response.errors).toEqual([]); @@ -290,9 +307,9 @@ describe('[CCR API Routes] Auto Follow Pattern', () => { setHttpRequestResponse(null, { acknowledge: true }); setHttpRequestResponse(null, { acknowledge: true }); - const response = await routeHandler({ params: { id: 'a,b,c' } }); + const response = await callRoute(routeHandler, {}, { params: { id: 'a,b,c' } }); - expect(response.itemsResumed).toEqual(['a', 'b', 'c']); + expect(response.options.body.itemsResumed).toEqual(['a', 'b', 'c']); }); it('should catch error and return them in array', async () => { @@ -302,7 +319,9 @@ describe('[CCR API Routes] Auto Follow Pattern', () => { setHttpRequestResponse(null, { acknowledge: true }); setHttpRequestResponse(error); - const response = await routeHandler({ params: { id: 'a,b' } }); + const { + options: { body: response }, + } = await callRoute(routeHandler, {}, { params: { id: 'a,b' } }); expect(response.itemsResumed).toEqual(['a']); expect(response.errors[0].id).toEqual('b'); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/routes/api/follower_index.test.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/__jest__/follower_index.test.js similarity index 72% rename from x-pack/legacy/plugins/cross_cluster_replication/server/routes/api/follower_index.test.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/__jest__/follower_index.test.js index 7e363c2758a4c9..f0139e5bd70115 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/routes/api/follower_index.test.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/__jest__/follower_index.test.js @@ -3,21 +3,23 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - -import { deserializeFollowerIndex } from '../../../common/services/follower_index_serialization'; +import { deserializeFollowerIndex } from '../../../../../common/services/follower_index_serialization'; import { getFollowerIndexStatsMock, getFollowerIndexListStatsMock, getFollowerIndexInfoMock, getFollowerIndexListInfoMock, -} from '../../../fixtures'; -import { callWithRequestFactory } from '../../lib/call_with_request_factory'; -import { isEsErrorFactory } from '../../lib/is_es_error_factory'; -import { registerFollowerIndexRoutes } from './follower_index'; - -jest.mock('../../lib/call_with_request_factory'); -jest.mock('../../lib/is_es_error_factory'); -jest.mock('../../lib/license_pre_routing_factory'); +} from '../../../../../fixtures'; +import { callWithRequestFactory } from '../../../lib/call_with_request_factory'; +import { isEsErrorFactory } from '../../../lib/is_es_error_factory'; +import { registerFollowerIndexRoutes } from '../follower_index'; +import { createRouter, callRoute } from './helpers'; + +jest.mock('../../../lib/call_with_request_factory'); +jest.mock('../../../lib/is_es_error_factory'); +jest.mock('../../../lib/license_pre_routing_factory', () => ({ + licensePreRoutingFactory: ({ requestHandler }) => requestHandler, +})); const DESERIALIZED_KEYS = Object.keys( deserializeFollowerIndex({ @@ -26,10 +28,7 @@ const DESERIALIZED_KEYS = Object.keys( }) ); -/** - * Hashtable to save the route handlers - */ -const routeHandlers = {}; +let routeRegistry; /** * Helper to extract all the different server route handler so we can easily call them in our tests. @@ -38,8 +37,6 @@ const routeHandlers = {}; * if a 'server.route()' call is moved or deleted, then the HANDLER_INDEX_TO_ACTION must be updated here. */ const registerHandlers = () => { - let index = 0; - const HANDLER_INDEX_TO_ACTION = { 0: 'list', 1: 'get', @@ -50,15 +47,11 @@ const registerHandlers = () => { 6: 'unfollow', }; - const server = { - route({ handler }) { - // Save handler and increment index - routeHandlers[HANDLER_INDEX_TO_ACTION[index]] = handler; - index++; - }, - }; - - registerFollowerIndexRoutes(server); + routeRegistry = createRouter(HANDLER_INDEX_TO_ACTION); + registerFollowerIndexRoutes({ + __LEGACY: {}, + router: routeRegistry.router, + }); }; /** @@ -104,7 +97,7 @@ describe('[CCR API Routes] Follower Index', () => { describe('list()', () => { beforeEach(() => { - routeHandler = routeHandlers.list; + routeHandler = routeRegistry.getRoutes().list; }); it('deserializes the response from Elasticsearch', async () => { @@ -117,7 +110,9 @@ describe('[CCR API Routes] Follower Index', () => { setHttpRequestResponse(null, infoResult); setHttpRequestResponse(null, statsResult); - const response = await routeHandler(); + const { + options: { body: response }, + } = await callRoute(routeHandler); const followerIndex = response.indices[0]; expect(response.indices.length).toEqual(totalResult); @@ -127,7 +122,7 @@ describe('[CCR API Routes] Follower Index', () => { describe('get()', () => { beforeEach(() => { - routeHandler = routeHandlers.get; + routeHandler = routeRegistry.getRoutes().get; }); it('should return a single resource even though ES return an array with 1 item', async () => { @@ -138,7 +133,9 @@ describe('[CCR API Routes] Follower Index', () => { setHttpRequestResponse(null, { follower_indices: [followerIndexInfo] }); setHttpRequestResponse(null, { indices: [followerIndexStats] }); - const response = await routeHandler({ params: { id: mockId } }); + const { + options: { body: response }, + } = await callRoute(routeHandler, {}, { params: { id: mockId } }); expect(Object.keys(response)).toEqual(DESERIALIZED_KEYS); }); }); @@ -146,34 +143,40 @@ describe('[CCR API Routes] Follower Index', () => { describe('create()', () => { beforeEach(() => { resetHttpRequestResponses(); - routeHandler = routeHandlers.create; + routeHandler = routeRegistry.getRoutes().create; }); it('should return 200 status when follower index is created', async () => { setHttpRequestResponse(null, { acknowledge: true }); - const response = await routeHandler({ - payload: { - name: 'follower_index', - remoteCluster: 'remote_cluster', - leaderIndex: 'leader_index', - }, - }); + const response = await callRoute( + routeHandler, + {}, + { + body: { + name: 'follower_index', + remoteCluster: 'remote_cluster', + leaderIndex: 'leader_index', + }, + } + ); - expect(response).toEqual({ acknowledge: true }); + expect(response.options.body).toEqual({ acknowledge: true }); }); }); describe('pause()', () => { beforeEach(() => { resetHttpRequestResponses(); - routeHandler = routeHandlers.pause; + routeHandler = routeRegistry.getRoutes().pause; }); it('should pause a single item', async () => { setHttpRequestResponse(null, { acknowledge: true }); - const response = await routeHandler({ params: { id: '1' } }); + const { + options: { body: response }, + } = await callRoute(routeHandler, {}, { params: { id: '1' } }); expect(response.itemsPaused).toEqual(['1']); expect(response.errors).toEqual([]); @@ -184,9 +187,9 @@ describe('[CCR API Routes] Follower Index', () => { setHttpRequestResponse(null, { acknowledge: true }); setHttpRequestResponse(null, { acknowledge: true }); - const response = await routeHandler({ params: { id: '1,2,3' } }); + const response = await callRoute(routeHandler, {}, { params: { id: '1,2,3' } }); - expect(response.itemsPaused).toEqual(['1', '2', '3']); + expect(response.options.body.itemsPaused).toEqual(['1', '2', '3']); }); it('should catch error and return them in array', async () => { @@ -196,7 +199,9 @@ describe('[CCR API Routes] Follower Index', () => { setHttpRequestResponse(null, { acknowledge: true }); setHttpRequestResponse(error); - const response = await routeHandler({ params: { id: '1,2' } }); + const { + options: { body: response }, + } = await callRoute(routeHandler, {}, { params: { id: '1,2' } }); expect(response.itemsPaused).toEqual(['1']); expect(response.errors[0].id).toEqual('2'); @@ -206,13 +211,15 @@ describe('[CCR API Routes] Follower Index', () => { describe('resume()', () => { beforeEach(() => { resetHttpRequestResponses(); - routeHandler = routeHandlers.resume; + routeHandler = routeRegistry.getRoutes().resume; }); it('should resume a single item', async () => { setHttpRequestResponse(null, { acknowledge: true }); - const response = await routeHandler({ params: { id: '1' } }); + const { + options: { body: response }, + } = await callRoute(routeHandler, {}, { params: { id: '1' } }); expect(response.itemsResumed).toEqual(['1']); expect(response.errors).toEqual([]); @@ -223,9 +230,9 @@ describe('[CCR API Routes] Follower Index', () => { setHttpRequestResponse(null, { acknowledge: true }); setHttpRequestResponse(null, { acknowledge: true }); - const response = await routeHandler({ params: { id: '1,2,3' } }); + const response = await callRoute(routeHandler, {}, { params: { id: '1,2,3' } }); - expect(response.itemsResumed).toEqual(['1', '2', '3']); + expect(response.options.body.itemsResumed).toEqual(['1', '2', '3']); }); it('should catch error and return them in array', async () => { @@ -235,7 +242,9 @@ describe('[CCR API Routes] Follower Index', () => { setHttpRequestResponse(null, { acknowledge: true }); setHttpRequestResponse(error); - const response = await routeHandler({ params: { id: '1,2' } }); + const { + options: { body: response }, + } = await callRoute(routeHandler, {}, { params: { id: '1,2' } }); expect(response.itemsResumed).toEqual(['1']); expect(response.errors[0].id).toEqual('2'); @@ -245,7 +254,7 @@ describe('[CCR API Routes] Follower Index', () => { describe('unfollow()', () => { beforeEach(() => { resetHttpRequestResponses(); - routeHandler = routeHandlers.unfollow; + routeHandler = routeRegistry.getRoutes().unfollow; }); it('should unfollow await single item', async () => { @@ -254,7 +263,9 @@ describe('[CCR API Routes] Follower Index', () => { setHttpRequestResponse(null, { acknowledge: true }); setHttpRequestResponse(null, { acknowledge: true }); - const response = await routeHandler({ params: { id: '1' } }); + const { + options: { body: response }, + } = await callRoute(routeHandler, {}, { params: { id: '1' } }); expect(response.itemsUnfollowed).toEqual(['1']); expect(response.errors).toEqual([]); @@ -274,9 +285,9 @@ describe('[CCR API Routes] Follower Index', () => { setHttpRequestResponse(null, { acknowledge: true }); setHttpRequestResponse(null, { acknowledge: true }); - const response = await routeHandler({ params: { id: '1,2,3' } }); + const response = await callRoute(routeHandler, {}, { params: { id: '1,2,3' } }); - expect(response.itemsUnfollowed).toEqual(['1', '2', '3']); + expect(response.options.body.itemsUnfollowed).toEqual(['1', '2', '3']); }); it('should catch error and return them in array', async () => { @@ -290,7 +301,9 @@ describe('[CCR API Routes] Follower Index', () => { setHttpRequestResponse(null, { acknowledge: true }); setHttpRequestResponse(error); - const response = await routeHandler({ params: { id: '1,2' } }); + const { + options: { body: response }, + } = await callRoute(routeHandler, {}, { params: { id: '1,2' } }); expect(response.itemsUnfollowed).toEqual(['1']); expect(response.errors[0].id).toEqual('2'); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/__jest__/helpers.ts b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/__jest__/helpers.ts new file mode 100644 index 00000000000000..555fc0937c0ad6 --- /dev/null +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/__jest__/helpers.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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { RequestHandler } from 'src/core/server'; +import { kibanaResponseFactory } from '../../../../../../../../../src/core/server'; + +export const callRoute = ( + route: RequestHandler, + ctx = {}, + request = {}, + response = kibanaResponseFactory +) => { + return route(ctx as any, request as any, response); +}; + +export const createRouter = (indexToActionMap: Record) => { + let index = 0; + const routeHandlers: Record> = {}; + const addHandler = (ignoreCtxForNow: any, handler: RequestHandler) => { + // Save handler and increment index + routeHandlers[indexToActionMap[index]] = handler; + index++; + }; + + return { + getRoutes: () => routeHandlers, + router: { + get: addHandler, + post: addHandler, + put: addHandler, + delete: addHandler, + }, + }; +}; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/auto_follow_pattern.ts b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/auto_follow_pattern.ts new file mode 100644 index 00000000000000..d458f1ccb354b6 --- /dev/null +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/auto_follow_pattern.ts @@ -0,0 +1,301 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +// @ts-ignore +import { callWithRequestFactory } from '../../lib/call_with_request_factory'; +import { isEsError } from '../../lib/is_es_error'; +// @ts-ignore +import { + deserializeAutoFollowPattern, + deserializeListAutoFollowPatterns, + serializeAutoFollowPattern, + // @ts-ignore +} from '../../../../common/services/auto_follow_pattern_serialization'; + +import { licensePreRoutingFactory } from '../../lib/license_pre_routing_factory'; +import { API_BASE_PATH } from '../../../../common/constants'; + +import { RouteDependencies } from '../types'; +import { mapErrorToKibanaHttpResponse } from '../map_to_kibana_http_error'; + +export const registerAutoFollowPatternRoutes = ({ router, __LEGACY }: RouteDependencies) => { + /** + * Returns a list of all auto-follow patterns + */ + router.get( + { + path: `${API_BASE_PATH}/auto_follow_patterns`, + validate: false, + }, + licensePreRoutingFactory({ + __LEGACY, + requestHandler: async (ctx, request, response) => { + const callWithRequest = callWithRequestFactory(__LEGACY.server, request); + + try { + const result = await callWithRequest('ccr.autoFollowPatterns'); + return response.ok({ + body: { + patterns: deserializeListAutoFollowPatterns(result.patterns), + }, + }); + } catch (err) { + return mapErrorToKibanaHttpResponse(err); + } + }, + }) + ); + + /** + * Create an auto-follow pattern + */ + router.post( + { + path: `${API_BASE_PATH}/auto_follow_patterns`, + validate: { + body: schema.object( + { + id: schema.string(), + }, + { unknowns: 'allow' } + ), + }, + }, + licensePreRoutingFactory({ + __LEGACY, + requestHandler: async (ctx, request, response) => { + const callWithRequest = callWithRequestFactory(__LEGACY.server, request); + const { id, ...rest } = request.body; + const body = serializeAutoFollowPattern(rest); + + /** + * First let's make sur that an auto-follow pattern with + * the same id does not exist. + */ + try { + await callWithRequest('ccr.autoFollowPattern', { id }); + // If we get here it means that an auto-follow pattern with the same id exists + return response.conflict({ + body: `An auto-follow pattern with the name "${id}" already exists.`, + }); + } catch (err) { + if (err.statusCode !== 404) { + return mapErrorToKibanaHttpResponse(err); + } + } + + try { + return response.ok({ + body: await callWithRequest('ccr.saveAutoFollowPattern', { id, body }), + }); + } catch (err) { + return mapErrorToKibanaHttpResponse(err); + } + }, + }) + ); + + /** + * Update an auto-follow pattern + */ + router.put( + { + path: `${API_BASE_PATH}/auto_follow_patterns/{id}`, + validate: { + params: schema.object({ + id: schema.string(), + }), + body: schema.object({}, { unknowns: 'allow' }), + }, + }, + licensePreRoutingFactory({ + __LEGACY, + requestHandler: async (ctx, request, response) => { + const callWithRequest = callWithRequestFactory(__LEGACY.server, request); + const { id } = request.params; + const body = serializeAutoFollowPattern(request.body); + + try { + return response.ok({ + body: await callWithRequest('ccr.saveAutoFollowPattern', { id, body }), + }); + } catch (err) { + return mapErrorToKibanaHttpResponse(err); + } + }, + }) + ); + + /** + * Returns a single auto-follow pattern + */ + router.get( + { + path: `${API_BASE_PATH}/auto_follow_patterns/{id}`, + validate: { + params: schema.object({ + id: schema.string(), + }), + }, + }, + licensePreRoutingFactory({ + __LEGACY, + requestHandler: async (ctx, request, response) => { + const callWithRequest = callWithRequestFactory(__LEGACY.server, request); + const { id } = request.params; + + try { + const result = await callWithRequest('ccr.autoFollowPattern', { id }); + const autoFollowPattern = result.patterns[0]; + + return response.ok({ + body: deserializeAutoFollowPattern(autoFollowPattern), + }); + } catch (err) { + return mapErrorToKibanaHttpResponse(err); + } + }, + }) + ); + + /** + * Delete an auto-follow pattern + */ + router.delete( + { + path: `${API_BASE_PATH}/auto_follow_patterns/{id}`, + validate: { + params: schema.object({ + id: schema.string(), + }), + }, + }, + licensePreRoutingFactory({ + __LEGACY, + requestHandler: async (ctx, request, response) => { + const callWithRequest = callWithRequestFactory(__LEGACY.server, request); + const { id } = request.params; + const ids = id.split(','); + + const itemsDeleted: string[] = []; + const errors: Array<{ id: string; error: any }> = []; + + await Promise.all( + ids.map(_id => + callWithRequest('ccr.deleteAutoFollowPattern', { id: _id }) + .then(() => itemsDeleted.push(_id)) + .catch((err: Error) => { + if (isEsError(err)) { + errors.push({ id: _id, error: mapErrorToKibanaHttpResponse(err) }); + } else { + errors.push({ id: _id, error: mapErrorToKibanaHttpResponse(err) }); + } + }) + ) + ); + + return response.ok({ + body: { + itemsDeleted, + errors, + }, + }); + }, + }) + ); + + /** + * Pause auto-follow pattern(s) + */ + router.post( + { + path: `${API_BASE_PATH}/auto_follow_patterns/{id}/pause`, + validate: { + params: schema.object({ + id: schema.string(), + }), + }, + }, + licensePreRoutingFactory({ + __LEGACY, + requestHandler: async (ctx, request, response) => { + const callWithRequest = callWithRequestFactory(__LEGACY.server, request); + const { id } = request.params; + const ids = id.split(','); + + const itemsPaused: string[] = []; + const errors: Array<{ id: string; error: any }> = []; + + await Promise.all( + ids.map(_id => + callWithRequest('ccr.pauseAutoFollowPattern', { id: _id }) + .then(() => itemsPaused.push(_id)) + .catch((err: Error) => { + if (isEsError(err)) { + errors.push({ id: _id, error: mapErrorToKibanaHttpResponse(err) }); + } else { + errors.push({ id: _id, error: mapErrorToKibanaHttpResponse(err) }); + } + }) + ) + ); + + return response.ok({ + body: { + itemsPaused, + errors, + }, + }); + }, + }) + ); + + /** + * Resume auto-follow pattern(s) + */ + router.post( + { + path: `${API_BASE_PATH}/auto_follow_patterns/{id}/resume`, + validate: { + params: schema.object({ + id: schema.string(), + }), + }, + }, + licensePreRoutingFactory({ + __LEGACY, + requestHandler: async (ctx, request, response) => { + const callWithRequest = callWithRequestFactory(__LEGACY.server, request); + const { id } = request.params; + const ids = id.split(','); + + const itemsResumed: string[] = []; + const errors: Array<{ id: string; error: any }> = []; + + await Promise.all( + ids.map(_id => + callWithRequest('ccr.resumeAutoFollowPattern', { id: _id }) + .then(() => itemsResumed.push(_id)) + .catch((err: Error) => { + if (isEsError(err)) { + errors.push({ id: _id, error: mapErrorToKibanaHttpResponse(err) }); + } else { + errors.push({ id: _id, error: mapErrorToKibanaHttpResponse(err) }); + } + }) + ) + ); + + return response.ok({ + body: { + itemsResumed, + errors, + }, + }); + }, + }) + ); +}; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/ccr.ts b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/ccr.ts new file mode 100644 index 00000000000000..b08b056ad2c8ae --- /dev/null +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/ccr.ts @@ -0,0 +1,112 @@ +/* + * 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 { API_BASE_PATH } from '../../../../common/constants'; +// @ts-ignore +import { callWithRequestFactory } from '../../lib/call_with_request_factory'; +// @ts-ignore +import { deserializeAutoFollowStats } from '../../lib/ccr_stats_serialization'; +import { licensePreRoutingFactory } from '../../lib/license_pre_routing_factory'; + +import { mapErrorToKibanaHttpResponse } from '../map_to_kibana_http_error'; +import { RouteDependencies } from '../types'; + +export const registerCcrRoutes = ({ router, __LEGACY }: RouteDependencies) => { + /** + * Returns Auto-follow stats + */ + router.get( + { + path: `${API_BASE_PATH}/stats/auto_follow`, + validate: false, + }, + licensePreRoutingFactory({ + __LEGACY, + requestHandler: async (ctx, request, response) => { + const callWithRequest = callWithRequestFactory(__LEGACY.server, request); + + try { + const { auto_follow_stats: autoFollowStats } = await callWithRequest('ccr.stats'); + + return response.ok({ + body: deserializeAutoFollowStats(autoFollowStats), + }); + } catch (err) { + return mapErrorToKibanaHttpResponse(err); + } + }, + }) + ); + + /** + * Returns whether the user has CCR permissions + */ + router.get( + { + path: `${API_BASE_PATH}/permissions`, + validate: false, + }, + licensePreRoutingFactory({ + __LEGACY, + requestHandler: async (ctx, request, response) => { + const xpackMainPlugin = __LEGACY.server.plugins.xpack_main; + const xpackInfo = xpackMainPlugin && xpackMainPlugin.info; + + if (!xpackInfo) { + // xpackInfo is updated via poll, so it may not be available until polling has begun. + // In this rare situation, tell the client the service is temporarily unavailable. + return response.customError({ + statusCode: 503, + body: 'Security info unavailable', + }); + } + + const securityInfo = xpackInfo && xpackInfo.isAvailable() && xpackInfo.feature('security'); + if (!securityInfo || !securityInfo.isAvailable() || !securityInfo.isEnabled()) { + // If security isn't enabled or available (in the case where security is enabled but license reverted to Basic) let the user use CCR. + return response.ok({ + body: { + hasPermission: true, + missingClusterPrivileges: [], + }, + }); + } + + const callWithRequest = callWithRequestFactory(__LEGACY.server, request); + + try { + const { has_all_requested: hasPermission, cluster } = await callWithRequest( + 'ccr.permissions', + { + body: { + cluster: ['manage', 'manage_ccr'], + }, + } + ); + + const missingClusterPrivileges = Object.keys(cluster).reduce( + (permissions: any, permissionName: any) => { + if (!cluster[permissionName]) { + permissions.push(permissionName); + return permissions; + } + }, + [] as any[] + ); + + return response.ok({ + body: { + hasPermission, + missingClusterPrivileges, + }, + }); + } catch (err) { + return mapErrorToKibanaHttpResponse(err); + } + }, + }) + ); +}; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/follower_index.ts b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/follower_index.ts new file mode 100644 index 00000000000000..3896e1c02c9150 --- /dev/null +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/follower_index.ts @@ -0,0 +1,345 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { + deserializeFollowerIndex, + deserializeListFollowerIndices, + serializeFollowerIndex, + serializeAdvancedSettings, + // @ts-ignore +} from '../../../../common/services/follower_index_serialization'; +import { API_BASE_PATH } from '../../../../common/constants'; +// @ts-ignore +import { removeEmptyFields } from '../../../../common/services/utils'; +// @ts-ignore +import { callWithRequestFactory } from '../../lib/call_with_request_factory'; +import { licensePreRoutingFactory } from '../../lib/license_pre_routing_factory'; + +import { RouteDependencies } from '../types'; +import { mapErrorToKibanaHttpResponse } from '../map_to_kibana_http_error'; + +export const registerFollowerIndexRoutes = ({ router, __LEGACY }: RouteDependencies) => { + /** + * Returns a list of all follower indices + */ + router.get( + { + path: `${API_BASE_PATH}/follower_indices`, + validate: false, + }, + licensePreRoutingFactory({ + __LEGACY, + requestHandler: async (ctx, request, response) => { + const callWithRequest = callWithRequestFactory(__LEGACY.server, request); + + try { + const { follower_indices: followerIndices } = await callWithRequest('ccr.info', { + id: '_all', + }); + + const { + follow_stats: { indices: followerIndicesStats }, + } = await callWithRequest('ccr.stats'); + + const followerIndicesStatsMap = followerIndicesStats.reduce((map: any, stats: any) => { + map[stats.index] = stats; + return map; + }, {}); + + const collatedFollowerIndices = followerIndices.map((followerIndex: any) => { + return { + ...followerIndex, + ...followerIndicesStatsMap[followerIndex.follower_index], + }; + }); + + return response.ok({ + body: { + indices: deserializeListFollowerIndices(collatedFollowerIndices), + }, + }); + } catch (err) { + return mapErrorToKibanaHttpResponse(err); + } + }, + }) + ); + + /** + * Returns a single follower index pattern + */ + router.get( + { + path: `${API_BASE_PATH}/follower_indices/{id}`, + validate: { + params: schema.object({ + id: schema.string(), + }), + }, + }, + licensePreRoutingFactory({ + __LEGACY, + requestHandler: async (ctx, request, response) => { + const callWithRequest = callWithRequestFactory(__LEGACY.server, request); + const { id } = request.params; + + try { + const { follower_indices: followerIndices } = await callWithRequest('ccr.info', { id }); + + const followerIndexInfo = followerIndices && followerIndices[0]; + + if (!followerIndexInfo) { + return response.notFound({ + body: `The follower index "${id}" does not exist.`, + }); + } + + // If this follower is paused, skip call to ES stats api since it will return 404 + if (followerIndexInfo.status === 'paused') { + return response.ok({ + body: deserializeFollowerIndex({ + ...followerIndexInfo, + }), + }); + } else { + const { + indices: followerIndicesStats, + } = await callWithRequest('ccr.followerIndexStats', { id }); + + return response.ok({ + body: deserializeFollowerIndex({ + ...followerIndexInfo, + ...(followerIndicesStats ? followerIndicesStats[0] : {}), + }), + }); + } + } catch (err) { + return mapErrorToKibanaHttpResponse(err); + } + }, + }) + ); + + /** + * Create a follower index + */ + router.post( + { + path: `${API_BASE_PATH}/follower_indices`, + validate: { + body: schema.object( + { + name: schema.string(), + }, + { unknowns: 'allow' } + ), + }, + }, + licensePreRoutingFactory({ + __LEGACY, + requestHandler: async (ctx, request, response) => { + const callWithRequest = callWithRequestFactory(__LEGACY.server, request); + const { name, ...rest } = request.body; + const body = removeEmptyFields(serializeFollowerIndex(rest)); + + try { + return response.ok({ + body: await callWithRequest('ccr.saveFollowerIndex', { name, body }), + }); + } catch (err) { + return mapErrorToKibanaHttpResponse(err); + } + }, + }) + ); + + /** + * Edit a follower index + */ + router.put( + { + path: `${API_BASE_PATH}/follower_indices/{id}`, + validate: { + params: schema.object({ id: schema.string() }), + }, + }, + licensePreRoutingFactory({ + __LEGACY, + requestHandler: async (ctx, request, response) => { + const callWithRequest = callWithRequestFactory(__LEGACY.server, request); + const { id } = request.params; + + // We need to first pause the follower and then resume it passing the advanced settings + try { + const { follower_indices: followerIndices } = await callWithRequest('ccr.info', { id }); + const followerIndexInfo = followerIndices && followerIndices[0]; + if (!followerIndexInfo) { + return response.notFound({ body: `The follower index "${id}" does not exist.` }); + } + + // Retrieve paused state instead of pulling it from the payload to ensure it's not stale. + const isPaused = followerIndexInfo.status === 'paused'; + // Pause follower if not already paused + if (!isPaused) { + await callWithRequest('ccr.pauseFollowerIndex', { id }); + } + + // Resume follower + const body = removeEmptyFields(serializeAdvancedSettings(request.body)); + return response.ok({ + body: await callWithRequest('ccr.resumeFollowerIndex', { id, body }), + }); + } catch (err) { + return mapErrorToKibanaHttpResponse(err); + } + }, + }) + ); + + /** + * Pauses a follower index + */ + router.put( + { + path: `${API_BASE_PATH}/follower_indices/{id}/pause`, + validate: { + params: schema.object({ id: schema.string() }), + }, + }, + licensePreRoutingFactory({ + __LEGACY, + requestHandler: async (ctx, request, response) => { + const callWithRequest = callWithRequestFactory(__LEGACY.server, request); + const { id } = request.params; + const ids = id.split(','); + + const itemsPaused: string[] = []; + const errors: Array<{ id: string; error: any }> = []; + + await Promise.all( + ids.map(_id => + callWithRequest('ccr.pauseFollowerIndex', { id: _id }) + .then(() => itemsPaused.push(_id)) + .catch((err: Error) => { + errors.push({ id: _id, error: mapErrorToKibanaHttpResponse(err) }); + }) + ) + ); + + return response.ok({ + body: { + itemsPaused, + errors, + }, + }); + }, + }) + ); + + /** + * Resumes a follower index + */ + router.put( + { + path: `${API_BASE_PATH}/follower_indices/{id}/resume`, + validate: { + params: schema.object({ id: schema.string() }), + }, + }, + licensePreRoutingFactory({ + __LEGACY, + requestHandler: async (ctx, request, response) => { + const callWithRequest = callWithRequestFactory(__LEGACY.server, request); + const { id } = request.params; + const ids = id.split(','); + + const itemsResumed: string[] = []; + const errors: Array<{ id: string; error: any }> = []; + + await Promise.all( + ids.map(_id => + callWithRequest('ccr.resumeFollowerIndex', { id: _id }) + .then(() => itemsResumed.push(_id)) + .catch((err: Error) => { + errors.push({ id: _id, error: mapErrorToKibanaHttpResponse(err) }); + }) + ) + ); + + return response.ok({ + body: { + itemsResumed, + errors, + }, + }); + }, + }) + ); + + /** + * Unfollow follower index's leader index + */ + router.put( + { + path: `${API_BASE_PATH}/follower_indices/{id}/unfollow`, + validate: { + params: schema.object({ id: schema.string() }), + }, + }, + licensePreRoutingFactory({ + __LEGACY, + requestHandler: async (ctx, request, response) => { + const callWithRequest = callWithRequestFactory(__LEGACY.server, request); + const { id } = request.params; + const ids = id.split(','); + + const itemsUnfollowed: string[] = []; + const itemsNotOpen: string[] = []; + const errors: Array<{ id: string; error: any }> = []; + + await Promise.all( + ids.map(async _id => { + try { + // Try to pause follower, let it fail silently since it may already be paused + try { + await callWithRequest('ccr.pauseFollowerIndex', { id: _id }); + } catch (e) { + // Swallow errors + } + + // Close index + await callWithRequest('indices.close', { index: _id }); + + // Unfollow leader + await callWithRequest('ccr.unfollowLeaderIndex', { id: _id }); + + // Try to re-open the index, store failures in a separate array to surface warnings in the UI + // This will allow users to query their index normally after unfollowing + try { + await callWithRequest('indices.open', { index: _id }); + } catch (e) { + itemsNotOpen.push(_id); + } + + // Push success + itemsUnfollowed.push(_id); + } catch (err) { + errors.push({ id: _id, error: mapErrorToKibanaHttpResponse(err) }); + } + }) + ); + + return response.ok({ + body: { + itemsUnfollowed, + itemsNotOpen, + errors, + }, + }); + }, + }) + ); +}; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/map_to_kibana_http_error.ts b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/map_to_kibana_http_error.ts new file mode 100644 index 00000000000000..6a81bd26dc47df --- /dev/null +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/map_to_kibana_http_error.ts @@ -0,0 +1,26 @@ +/* + * 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 { kibanaResponseFactory } from '../../../../../../../src/core/server'; +// @ts-ignore +import { wrapEsError } from '../lib/error_wrappers'; +import { isEsError } from '../lib/is_es_error'; + +export const mapErrorToKibanaHttpResponse = (err: any) => { + if (isEsError(err)) { + const { statusCode, message, body } = wrapEsError(err); + return kibanaResponseFactory.customError({ + statusCode, + body: { + message, + attributes: { + cause: body?.cause, + }, + }, + }); + } + return kibanaResponseFactory.internalError(err); +}; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/routes/register_routes.js b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/register_routes.ts similarity index 67% rename from x-pack/legacy/plugins/cross_cluster_replication/server/routes/register_routes.js rename to x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/register_routes.ts index 6e4088ec8600f3..7e594175506918 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/routes/register_routes.js +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/register_routes.ts @@ -7,9 +7,10 @@ import { registerAutoFollowPatternRoutes } from './api/auto_follow_pattern'; import { registerFollowerIndexRoutes } from './api/follower_index'; import { registerCcrRoutes } from './api/ccr'; +import { RouteDependencies } from './types'; -export function registerRoutes(server) { - registerAutoFollowPatternRoutes(server); - registerFollowerIndexRoutes(server); - registerCcrRoutes(server); +export function registerRoutes(deps: RouteDependencies) { + registerAutoFollowPatternRoutes(deps); + registerFollowerIndexRoutes(deps); + registerCcrRoutes(deps); } diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/types.ts b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/types.ts new file mode 100644 index 00000000000000..7f57c20c536e03 --- /dev/null +++ b/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/types.ts @@ -0,0 +1,13 @@ +/* + * 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 { IRouter } from 'src/core/server'; + +export interface RouteDependencies { + router: IRouter; + __LEGACY: { + server: any; + }; +} diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern.js b/x-pack/legacy/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern.js deleted file mode 100644 index 4667f0a110c1fd..00000000000000 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern.js +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import Boom from 'boom'; -import { callWithRequestFactory } from '../../lib/call_with_request_factory'; -import { isEsErrorFactory } from '../../lib/is_es_error_factory'; -import { wrapEsError, wrapUnknownError } from '../../lib/error_wrappers'; -import { - deserializeAutoFollowPattern, - deserializeListAutoFollowPatterns, - serializeAutoFollowPattern, -} from '../../../common/services/auto_follow_pattern_serialization'; -import { licensePreRoutingFactory } from '../../lib/license_pre_routing_factory'; -import { API_BASE_PATH } from '../../../common/constants'; - -export const registerAutoFollowPatternRoutes = server => { - const isEsError = isEsErrorFactory(server); - const licensePreRouting = licensePreRoutingFactory(server); - - /** - * Returns a list of all auto-follow patterns - */ - server.route({ - path: `${API_BASE_PATH}/auto_follow_patterns`, - method: 'GET', - config: { - pre: [licensePreRouting], - }, - handler: async request => { - const callWithRequest = callWithRequestFactory(server, request); - - try { - const response = await callWithRequest('ccr.autoFollowPatterns'); - return { - patterns: deserializeListAutoFollowPatterns(response.patterns), - }; - } catch (err) { - if (isEsError(err)) { - throw wrapEsError(err); - } - throw wrapUnknownError(err); - } - }, - }); - - /** - * Create an auto-follow pattern - */ - server.route({ - path: `${API_BASE_PATH}/auto_follow_patterns`, - method: 'POST', - config: { - pre: [licensePreRouting], - }, - handler: async request => { - const callWithRequest = callWithRequestFactory(server, request); - const { id, ...rest } = request.payload; - const body = serializeAutoFollowPattern(rest); - - /** - * First let's make sur that an auto-follow pattern with - * the same id does not exist. - */ - try { - await callWithRequest('ccr.autoFollowPattern', { id }); - // If we get here it means that an auto-follow pattern with the same id exists - const error = Boom.conflict(`An auto-follow pattern with the name "${id}" already exists.`); - throw error; - } catch (err) { - if (err.statusCode !== 404) { - if (isEsError(err)) { - throw wrapEsError(err); - } - throw wrapUnknownError(err); - } - } - - try { - return await callWithRequest('ccr.saveAutoFollowPattern', { id, body }); - } catch (err) { - if (isEsError(err)) { - throw wrapEsError(err); - } - throw wrapUnknownError(err); - } - }, - }); - - /** - * Update an auto-follow pattern - */ - server.route({ - path: `${API_BASE_PATH}/auto_follow_patterns/{id}`, - method: 'PUT', - config: { - pre: [licensePreRouting], - }, - handler: async request => { - const callWithRequest = callWithRequestFactory(server, request); - const { id } = request.params; - const body = serializeAutoFollowPattern(request.payload); - - try { - return await callWithRequest('ccr.saveAutoFollowPattern', { id, body }); - } catch (err) { - if (isEsError(err)) { - throw wrapEsError(err); - } - throw wrapUnknownError(err); - } - }, - }); - - /** - * Returns a single auto-follow pattern - */ - server.route({ - path: `${API_BASE_PATH}/auto_follow_patterns/{id}`, - method: 'GET', - config: { - pre: [licensePreRouting], - }, - handler: async request => { - const callWithRequest = callWithRequestFactory(server, request); - const { id } = request.params; - - try { - const response = await callWithRequest('ccr.autoFollowPattern', { id }); - const autoFollowPattern = response.patterns[0]; - - return deserializeAutoFollowPattern(autoFollowPattern); - } catch (err) { - if (isEsError(err)) { - throw wrapEsError(err); - } - throw wrapUnknownError(err); - } - }, - }); - - /** - * Delete an auto-follow pattern - */ - server.route({ - path: `${API_BASE_PATH}/auto_follow_patterns/{id}`, - method: 'DELETE', - config: { - pre: [licensePreRouting], - }, - handler: async request => { - const callWithRequest = callWithRequestFactory(server, request); - const { id } = request.params; - const ids = id.split(','); - - const itemsDeleted = []; - const errors = []; - - await Promise.all( - ids.map(_id => - callWithRequest('ccr.deleteAutoFollowPattern', { id: _id }) - .then(() => itemsDeleted.push(_id)) - .catch(err => { - if (isEsError(err)) { - errors.push({ id: _id, error: wrapEsError(err) }); - } else { - errors.push({ id: _id, error: wrapUnknownError(err) }); - } - }) - ) - ); - - return { - itemsDeleted, - errors, - }; - }, - }); - - /** - * Pause auto-follow pattern(s) - */ - server.route({ - path: `${API_BASE_PATH}/auto_follow_patterns/{id}/pause`, - method: 'POST', - config: { - pre: [licensePreRouting], - }, - handler: async request => { - const callWithRequest = callWithRequestFactory(server, request); - const { id } = request.params; - const ids = id.split(','); - - const itemsPaused = []; - const errors = []; - - await Promise.all( - ids.map(_id => - callWithRequest('ccr.pauseAutoFollowPattern', { id: _id }) - .then(() => itemsPaused.push(_id)) - .catch(err => { - if (isEsError(err)) { - errors.push({ id: _id, error: wrapEsError(err) }); - } else { - errors.push({ id: _id, error: wrapUnknownError(err) }); - } - }) - ) - ); - - return { - itemsPaused, - errors, - }; - }, - }); - - /** - * Resume auto-follow pattern(s) - */ - server.route({ - path: `${API_BASE_PATH}/auto_follow_patterns/{id}/resume`, - method: 'POST', - config: { - pre: [licensePreRouting], - }, - handler: async request => { - const callWithRequest = callWithRequestFactory(server, request); - const { id } = request.params; - const ids = id.split(','); - - const itemsResumed = []; - const errors = []; - - await Promise.all( - ids.map(_id => - callWithRequest('ccr.resumeAutoFollowPattern', { id: _id }) - .then(() => itemsResumed.push(_id)) - .catch(err => { - if (isEsError(err)) { - errors.push({ id: _id, error: wrapEsError(err) }); - } else { - errors.push({ id: _id, error: wrapUnknownError(err) }); - } - }) - ) - ); - - return { - itemsResumed, - errors, - }; - }, - }); -}; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/routes/api/ccr.js b/x-pack/legacy/plugins/cross_cluster_replication/server/routes/api/ccr.js deleted file mode 100644 index 8255eb6e86b076..00000000000000 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/routes/api/ccr.js +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Boom from 'boom'; - -import { API_BASE_PATH } from '../../../common/constants'; -import { callWithRequestFactory } from '../../lib/call_with_request_factory'; -import { isEsErrorFactory } from '../../lib/is_es_error_factory'; -import { wrapEsError, wrapUnknownError } from '../../lib/error_wrappers'; -import { deserializeAutoFollowStats } from '../../lib/ccr_stats_serialization'; -import { licensePreRoutingFactory } from '../../lib/license_pre_routing_factory'; - -export const registerCcrRoutes = server => { - const isEsError = isEsErrorFactory(server); - const licensePreRouting = licensePreRoutingFactory(server); - - /** - * Returns Auto-follow stats - */ - server.route({ - path: `${API_BASE_PATH}/stats/auto_follow`, - method: 'GET', - config: { - pre: [licensePreRouting], - }, - handler: async request => { - const callWithRequest = callWithRequestFactory(server, request); - - try { - const { auto_follow_stats: autoFollowStats } = await callWithRequest('ccr.stats'); - - return deserializeAutoFollowStats(autoFollowStats); - } catch (err) { - if (isEsError(err)) { - throw wrapEsError(err); - } - throw wrapUnknownError(err); - } - }, - }); - - /** - * Returns whether the user has CCR permissions - */ - server.route({ - path: `${API_BASE_PATH}/permissions`, - method: 'GET', - config: { - pre: [licensePreRouting], - }, - handler: async request => { - const xpackMainPlugin = server.plugins.xpack_main; - const xpackInfo = xpackMainPlugin && xpackMainPlugin.info; - - if (!xpackInfo) { - // xpackInfo is updated via poll, so it may not be available until polling has begun. - // In this rare situation, tell the client the service is temporarily unavailable. - throw new Boom('Security info unavailable', { statusCode: 503 }); - } - - const securityInfo = xpackInfo && xpackInfo.isAvailable() && xpackInfo.feature('security'); - if (!securityInfo || !securityInfo.isAvailable() || !securityInfo.isEnabled()) { - // If security isn't enabled or available (in the case where security is enabled but license reverted to Basic) let the user use CCR. - return { - hasPermission: true, - missingClusterPrivileges: [], - }; - } - - const callWithRequest = callWithRequestFactory(server, request); - - try { - const { has_all_requested: hasPermission, cluster } = await callWithRequest( - 'ccr.permissions', - { - body: { - cluster: ['manage', 'manage_ccr'], - }, - } - ); - - const missingClusterPrivileges = Object.keys(cluster).reduce( - (permissions, permissionName) => { - if (!cluster[permissionName]) { - permissions.push(permissionName); - return permissions; - } - }, - [] - ); - - return { - hasPermission, - missingClusterPrivileges, - }; - } catch (err) { - if (isEsError(err)) { - throw wrapEsError(err); - } - throw wrapUnknownError(err); - } - }, - }); -}; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/routes/api/follower_index.js b/x-pack/legacy/plugins/cross_cluster_replication/server/routes/api/follower_index.js deleted file mode 100644 index e532edaa396366..00000000000000 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/routes/api/follower_index.js +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Boom from 'boom'; - -import { - deserializeFollowerIndex, - deserializeListFollowerIndices, - serializeFollowerIndex, - serializeAdvancedSettings, -} from '../../../common/services/follower_index_serialization'; -import { API_BASE_PATH } from '../../../common/constants'; -import { removeEmptyFields } from '../../../common/services/utils'; -import { callWithRequestFactory } from '../../lib/call_with_request_factory'; -import { isEsErrorFactory } from '../../lib/is_es_error_factory'; -import { wrapEsError, wrapUnknownError } from '../../lib/error_wrappers'; -import { licensePreRoutingFactory } from '../../lib/license_pre_routing_factory'; - -export const registerFollowerIndexRoutes = server => { - const isEsError = isEsErrorFactory(server); - const licensePreRouting = licensePreRoutingFactory(server); - - /** - * Returns a list of all follower indices - */ - server.route({ - path: `${API_BASE_PATH}/follower_indices`, - method: 'GET', - config: { - pre: [licensePreRouting], - }, - handler: async request => { - const callWithRequest = callWithRequestFactory(server, request); - - try { - const { follower_indices: followerIndices } = await callWithRequest('ccr.info', { - id: '_all', - }); - - const { - follow_stats: { indices: followerIndicesStats }, - } = await callWithRequest('ccr.stats'); - - const followerIndicesStatsMap = followerIndicesStats.reduce((map, stats) => { - map[stats.index] = stats; - return map; - }, {}); - - const collatedFollowerIndices = followerIndices.map(followerIndex => { - return { - ...followerIndex, - ...followerIndicesStatsMap[followerIndex.follower_index], - }; - }); - - return { - indices: deserializeListFollowerIndices(collatedFollowerIndices), - }; - } catch (err) { - if (isEsError(err)) { - throw wrapEsError(err); - } - throw wrapUnknownError(err); - } - }, - }); - - /** - * Returns a single follower index pattern - */ - server.route({ - path: `${API_BASE_PATH}/follower_indices/{id}`, - method: 'GET', - config: { - pre: [licensePreRouting], - }, - handler: async request => { - const callWithRequest = callWithRequestFactory(server, request); - const { id } = request.params; - - try { - const { follower_indices: followerIndices } = await callWithRequest('ccr.info', { id }); - - const followerIndexInfo = followerIndices && followerIndices[0]; - - if (!followerIndexInfo) { - const error = Boom.notFound(`The follower index "${id}" does not exist.`); - throw error; - } - - // If this follower is paused, skip call to ES stats api since it will return 404 - if (followerIndexInfo.status === 'paused') { - return deserializeFollowerIndex({ - ...followerIndexInfo, - }); - } else { - const { indices: followerIndicesStats } = await callWithRequest( - 'ccr.followerIndexStats', - { id } - ); - - return deserializeFollowerIndex({ - ...followerIndexInfo, - ...(followerIndicesStats ? followerIndicesStats[0] : {}), - }); - } - } catch (err) { - if (isEsError(err)) { - throw wrapEsError(err); - } - throw wrapUnknownError(err); - } - }, - }); - - /** - * Create a follower index - */ - server.route({ - path: `${API_BASE_PATH}/follower_indices`, - method: 'POST', - config: { - pre: [licensePreRouting], - }, - handler: async request => { - const callWithRequest = callWithRequestFactory(server, request); - const { name, ...rest } = request.payload; - const body = removeEmptyFields(serializeFollowerIndex(rest)); - - try { - return await callWithRequest('ccr.saveFollowerIndex', { name, body }); - } catch (err) { - if (isEsError(err)) { - throw wrapEsError(err); - } - throw wrapUnknownError(err); - } - }, - }); - - /** - * Edit a follower index - */ - server.route({ - path: `${API_BASE_PATH}/follower_indices/{id}`, - method: 'PUT', - config: { - pre: [licensePreRouting], - }, - handler: async request => { - const callWithRequest = callWithRequestFactory(server, request); - const { id } = request.params; - - async function isFollowerIndexPaused() { - const { follower_indices: followerIndices } = await callWithRequest('ccr.info', { id }); - - const followerIndexInfo = followerIndices && followerIndices[0]; - - if (!followerIndexInfo) { - const error = Boom.notFound(`The follower index "${id}" does not exist.`); - throw error; - } - - return followerIndexInfo.status === 'paused'; - } - - // We need to first pause the follower and then resume it passing the advanced settings - try { - // Retrieve paused state instead of pulling it from the payload to ensure it's not stale. - const isPaused = await isFollowerIndexPaused(); - // Pause follower if not already paused - if (!isPaused) { - await callWithRequest('ccr.pauseFollowerIndex', { id }); - } - - // Resume follower - const body = removeEmptyFields(serializeAdvancedSettings(request.payload)); - return await callWithRequest('ccr.resumeFollowerIndex', { id, body }); - } catch (err) { - if (isEsError(err)) { - throw wrapEsError(err); - } - throw wrapUnknownError(err); - } - }, - }); - - /** - * Pauses a follower index - */ - server.route({ - path: `${API_BASE_PATH}/follower_indices/{id}/pause`, - method: 'PUT', - config: { - pre: [licensePreRouting], - }, - handler: async request => { - const callWithRequest = callWithRequestFactory(server, request); - const { id } = request.params; - const ids = id.split(','); - - const itemsPaused = []; - const errors = []; - - await Promise.all( - ids.map(_id => - callWithRequest('ccr.pauseFollowerIndex', { id: _id }) - .then(() => itemsPaused.push(_id)) - .catch(err => { - if (isEsError(err)) { - errors.push({ id: _id, error: wrapEsError(err) }); - } else { - errors.push({ id: _id, error: wrapUnknownError(err) }); - } - }) - ) - ); - - return { - itemsPaused, - errors, - }; - }, - }); - - /** - * Resumes a follower index - */ - server.route({ - path: `${API_BASE_PATH}/follower_indices/{id}/resume`, - method: 'PUT', - config: { - pre: [licensePreRouting], - }, - handler: async request => { - const callWithRequest = callWithRequestFactory(server, request); - const { id } = request.params; - const ids = id.split(','); - - const itemsResumed = []; - const errors = []; - - await Promise.all( - ids.map(_id => - callWithRequest('ccr.resumeFollowerIndex', { id: _id }) - .then(() => itemsResumed.push(_id)) - .catch(err => { - if (isEsError(err)) { - errors.push({ id: _id, error: wrapEsError(err) }); - } else { - errors.push({ id: _id, error: wrapUnknownError(err) }); - } - }) - ) - ); - - return { - itemsResumed, - errors, - }; - }, - }); - - /** - * Unfollow follower index's leader index - */ - server.route({ - path: `${API_BASE_PATH}/follower_indices/{id}/unfollow`, - method: 'PUT', - config: { - pre: [licensePreRouting], - }, - handler: async request => { - const callWithRequest = callWithRequestFactory(server, request); - const { id } = request.params; - const ids = id.split(','); - - const itemsUnfollowed = []; - const itemsNotOpen = []; - const errors = []; - - await Promise.all( - ids.map(async _id => { - try { - // Try to pause follower, let it fail silently since it may already be paused - try { - await callWithRequest('ccr.pauseFollowerIndex', { id: _id }); - } catch (e) { - // Swallow errors - } - - // Close index - await callWithRequest('indices.close', { index: _id }); - - // Unfollow leader - await callWithRequest('ccr.unfollowLeaderIndex', { id: _id }); - - // Try to re-open the index, store failures in a separate array to surface warnings in the UI - // This will allow users to query their index normally after unfollowing - try { - await callWithRequest('indices.open', { index: _id }); - } catch (e) { - itemsNotOpen.push(_id); - } - - // Push success - itemsUnfollowed.push(_id); - } catch (err) { - if (isEsError(err)) { - errors.push({ id: _id, error: wrapEsError(err) }); - } else { - errors.push({ id: _id, error: wrapUnknownError(err) }); - } - } - }) - ); - - return { - itemsUnfollowed, - itemsNotOpen, - errors, - }; - }, - }); -}; diff --git a/x-pack/test/api_integration/apis/management/cross_cluster_replication/auto_follow_pattern.js b/x-pack/test/api_integration/apis/management/cross_cluster_replication/auto_follow_pattern.js index 30459be6ee1dd5..3efb4d6600f7fd 100644 --- a/x-pack/test/api_integration/apis/management/cross_cluster_replication/auto_follow_pattern.js +++ b/x-pack/test/api_integration/apis/management/cross_cluster_replication/auto_follow_pattern.js @@ -41,7 +41,7 @@ export default function({ getService }) { payload.remoteCluster = 'unknown-cluster'; const { body } = await createAutoFollowPattern(undefined, payload).expect(404); - expect(body.cause[0]).to.contain('no such remote cluster'); + expect(body.attributes.cause[0]).to.contain('no such remote cluster'); }); }); @@ -52,6 +52,7 @@ export default function({ getService }) { it('should create an auto-follow pattern when cluster is known', async () => { const name = getRandomString(); const { body } = await createAutoFollowPattern(name).expect(200); + console.log(body); expect(body.acknowledged).to.eql(true); }); @@ -62,7 +63,7 @@ export default function({ getService }) { const name = getRandomString(); const { body } = await getAutoFollowPattern(name).expect(404); - expect(body.cause).not.to.be(undefined); + expect(body.attributes.cause).not.to.be(undefined); }); it('should return an auto-follow pattern that was created', async () => { diff --git a/x-pack/test/api_integration/apis/management/cross_cluster_replication/follower_indices.js b/x-pack/test/api_integration/apis/management/cross_cluster_replication/follower_indices.js index a5b12668ad9b99..5f9ebbd2a0a3fe 100644 --- a/x-pack/test/api_integration/apis/management/cross_cluster_replication/follower_indices.js +++ b/x-pack/test/api_integration/apis/management/cross_cluster_replication/follower_indices.js @@ -47,13 +47,13 @@ export default function({ getService }) { payload.remoteCluster = 'unknown-cluster'; const { body } = await createFollowerIndex(undefined, payload).expect(404); - expect(body.cause[0]).to.contain('no such remote cluster'); + expect(body.attributes.cause[0]).to.contain('no such remote cluster'); }); it('should throw a 404 error trying to follow an unknown index', async () => { const payload = getFollowerIndexPayload(); const { body } = await createFollowerIndex(undefined, payload).expect(404); - expect(body.cause[0]).to.contain('no such index'); + expect(body.attributes.cause[0]).to.contain('no such index'); }); it('should create a follower index that follows an existing remote index', async () => { @@ -75,7 +75,7 @@ export default function({ getService }) { const name = getRandomString(); const { body } = await getFollowerIndex(name).expect(404); - expect(body.cause[0]).to.contain('no such index'); + expect(body.attributes.cause[0]).to.contain('no such index'); }); it('should return a follower index that was created', async () => {