From b9adddf9af07feab55e64b125f02caf833554afa Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Thu, 2 Apr 2020 05:02:10 -0700 Subject: [PATCH 01/20] Move CCR to plugins directory. --- .../cross_cluster_replication/common/constants/app.ts | 0 .../common/constants/base_path.ts | 0 .../cross_cluster_replication/common/constants/index.ts | 0 .../cross_cluster_replication/common/constants/plugin.ts | 0 .../common/constants/settings.ts | 0 .../follower_index_serialization.test.js.snap | 0 .../common/services/auto_follow_pattern_serialization.js | 0 .../services/auto_follow_pattern_serialization.test.js | 0 .../common/services/follower_index_serialization.js | 0 .../common/services/follower_index_serialization.test.js | 0 .../cross_cluster_replication/common/services/utils.js | 0 .../common/services/utils.test.js | 0 .../fixtures/auto_follow_pattern.js | 2 +- .../cross_cluster_replication/fixtures/es_errors.js | 0 .../cross_cluster_replication/fixtures/follower_index.js | 2 +- .../plugins/cross_cluster_replication/fixtures/index.js | 0 .../plugins/cross_cluster_replication/index.js | 2 +- .../client_integration/auto_follow_pattern_add.test.js | 2 +- .../client_integration/auto_follow_pattern_edit.test.js | 4 ++-- .../client_integration/auto_follow_pattern_list.test.js | 4 ++-- .../client_integration/follower_index_add.test.js | 4 ++-- .../client_integration/follower_index_edit.test.js | 4 ++-- .../client_integration/follower_indices_list.test.js | 2 +- .../helpers/auto_follow_pattern_add.helpers.js | 6 +++--- .../helpers/auto_follow_pattern_edit.helpers.js | 6 +++--- .../helpers/auto_follow_pattern_list.helpers.js | 6 +++--- .../__jest__/client_integration/helpers/constants.js | 0 .../helpers/follower_index_add.helpers.js | 6 +++--- .../helpers/follower_index_edit.helpers.js | 6 +++--- .../helpers/follower_index_list.helpers.js | 6 +++--- .../__jest__/client_integration/helpers/home.helpers.js | 8 ++++---- .../__jest__/client_integration/helpers/http_requests.js | 0 .../public}/__jest__/client_integration/helpers/index.js | 0 .../client_integration/helpers/setup_environment.js | 2 +- .../public}/__jest__/client_integration/home.test.js | 2 +- .../cross_cluster_replication/public}/app/_app.scss | 0 .../cross_cluster_replication/public}/app/app.js | 2 +- .../__snapshots__/auto_follow_pattern_form.test.js.snap | 0 .../auto_follow_pattern_action_menu.container.ts | 0 .../auto_follow_pattern_action_menu.tsx | 0 .../components/auto_follow_pattern_action_menu/index.ts | 0 .../components/auto_follow_pattern_delete_provider.d.ts | 0 .../app/components/auto_follow_pattern_delete_provider.js | 2 +- .../public}/app/components/auto_follow_pattern_form.js | 4 ++-- .../app/components/auto_follow_pattern_form.test.js | 0 .../app/components/auto_follow_pattern_indices_preview.js | 0 .../app/components/auto_follow_pattern_page_title.js | 0 .../app/components/auto_follow_pattern_request_flyout.js | 2 +- .../__snapshots__/follower_index_form.test.js.snap | 0 .../follower_index_form/advanced_settings_fields.js | 0 .../components/follower_index_form/follower_index_form.js | 2 +- .../follower_index_form/follower_index_form.test.js | 0 .../follower_index_form/follower_index_request_flyout.js | 2 +- .../public}/app/components/follower_index_form/index.js | 0 .../public}/app/components/follower_index_page_title.js | 0 .../app/components/follower_index_pause_provider.js | 2 +- .../app/components/follower_index_resume_provider.js | 2 +- .../app/components/follower_index_unfollow_provider.js | 2 +- .../public}/app/components/form_entry_row.js | 0 .../public}/app/components/index.js | 0 .../public}/app/components/remote_clusters_form_field.js | 2 +- .../public}/app/components/remote_clusters_provider.js | 0 .../public}/app/components/section_error.js | 0 .../public}/app/components/section_loading.js | 0 .../public}/app/components/section_unauthorized.js | 0 .../public}/app/constants/api.js | 0 .../public}/app/constants/index.js | 0 .../public}/app/constants/sections.js | 0 .../public}/app/constants/ui_metric.js | 0 .../cross_cluster_replication/public}/app/index.js | 0 .../auto_follow_pattern_add.container.js | 0 .../auto_follow_pattern_add/auto_follow_pattern_add.js | 0 .../public}/app/sections/auto_follow_pattern_add/index.js | 0 .../auto_follow_pattern_edit.container.js | 0 .../auto_follow_pattern_edit/auto_follow_pattern_edit.js | 0 .../app/sections/auto_follow_pattern_edit/index.js | 0 .../follower_index_add/follower_index_add.container.js | 0 .../app/sections/follower_index_add/follower_index_add.js | 0 .../public}/app/sections/follower_index_add/index.js | 0 .../follower_index_edit/follower_index_edit.container.js | 0 .../sections/follower_index_edit/follower_index_edit.js | 0 .../public}/app/sections/follower_index_edit/index.js | 0 .../auto_follow_pattern_list.container.js | 0 .../auto_follow_pattern_list/auto_follow_pattern_list.js | 0 .../auto_follow_pattern_table.container.js | 0 .../auto_follow_pattern_table.js | 0 .../components/auto_follow_pattern_table/index.js | 0 .../components/detail_panel/detail_panel.container.js | 0 .../components/detail_panel/detail_panel.js | 2 +- .../components/detail_panel/index.js | 0 .../home/auto_follow_pattern_list/components/index.js | 0 .../app/sections/home/auto_follow_pattern_list/index.js | 0 .../components/context_menu/context_menu.js | 0 .../components/context_menu/index.js | 0 .../components/detail_panel/detail_panel.container.js | 0 .../components/detail_panel/detail_panel.js | 2 +- .../components/detail_panel/index.js | 0 .../follower_indices_table.container.js | 0 .../follower_indices_table/follower_indices_table.js | 0 .../components/follower_indices_table/index.js | 0 .../home/follower_indices_list/components/index.js | 0 .../follower_indices_list.container.js | 0 .../home/follower_indices_list/follower_indices_list.js | 0 .../app/sections/home/follower_indices_list/index.js | 0 .../public}/app/sections/home/home.container.js | 0 .../public}/app/sections/home/home.js | 2 +- .../public}/app/sections/home/index.js | 0 .../public}/app/sections/index.js | 0 .../auto_follow_pattern_validators.test.js.snap | 0 .../cross_cluster_replication/public}/app/services/api.js | 4 ++-- .../public}/app/services/auto_follow_errors.js | 0 .../public}/app/services/auto_follow_errors.test.js | 0 .../public}/app/services/auto_follow_pattern.js | 0 .../public}/app/services/auto_follow_pattern.test.js | 0 .../app/services/auto_follow_pattern_validators.js | 4 ++-- .../app/services/auto_follow_pattern_validators.test.js | 0 .../public}/app/services/breadcrumbs.mock.ts | 0 .../public}/app/services/breadcrumbs.ts | 2 +- .../public}/app/services/documentation_links.ts | 0 .../app/services/follower_index_default_settings.js | 2 +- .../public}/app/services/get_remote_cluster_name.js | 0 .../public}/app/services/input_validation.js | 2 +- .../public}/app/services/notifications.ts | 0 .../public}/app/services/query_params.js | 0 .../public}/app/services/routing.js | 2 +- .../public}/app/services/track_ui_metric.js | 2 +- .../public}/app/services/utils.js | 0 .../public}/app/services/utils.test.js | 0 .../public}/app/store/action_types.js | 0 .../public}/app/store/actions/api.js | 0 .../public}/app/store/actions/auto_follow_pattern.js | 0 .../public}/app/store/actions/ccr.js | 0 .../public}/app/store/actions/follower_index.js | 0 .../public}/app/store/actions/index.js | 0 .../cross_cluster_replication/public}/app/store/index.js | 0 .../public}/app/store/reducers/api.js | 0 .../public}/app/store/reducers/api.test.js | 0 .../public}/app/store/reducers/auto_follow_pattern.js | 0 .../public}/app/store/reducers/follower_index.js | 0 .../public}/app/store/reducers/index.js | 0 .../public}/app/store/reducers/stats.js | 0 .../public}/app/store/selectors/index.js | 0 .../cross_cluster_replication/public}/app/store/store.js | 0 .../public}/extend_index_management.ts | 0 .../plugins/cross_cluster_replication/public/index.js | 0 .../plugins/cross_cluster_replication/public/index.scss | 0 .../cross_cluster_replication/public}/index.ts | 0 .../plugins/cross_cluster_replication/public/main.html | 0 .../cross_cluster_replication/public}/plugin.ts | 0 .../cross_cluster_replication/public/register_routes.js | 4 ++-- .../server}/client/elasticsearch_ccr.js | 0 .../server}/cross_cluster_replication_data.ts | 0 .../cross_cluster_replication/server}/index.ts | 0 .../__snapshots__/ccr_stats_serialization.test.js.snap | 0 .../call_with_request_factory.js | 0 .../server}/lib/call_with_request_factory/index.js | 0 .../server}/lib/ccr_stats_serialization.js | 0 .../server}/lib/ccr_stats_serialization.test.js | 0 .../server}/lib/check_license/check_license.js | 0 .../server}/lib/check_license/index.js | 0 .../lib/error_wrappers/__tests__/wrap_es_error.test.js | 0 .../server}/lib/error_wrappers/index.ts | 0 .../server}/lib/error_wrappers/wrap_es_error.ts | 0 .../cross_cluster_replication/server}/lib/is_es_error.ts | 0 .../is_es_error_factory/__tests__/is_es_error_factory.js | 0 .../server}/lib/is_es_error_factory/index.ts | 0 .../lib/is_es_error_factory/is_es_error_factory.ts | 0 .../__jest__/license_pre_routing_factory.test.ts | 0 .../server}/lib/license_pre_routing_factory/index.ts | 0 .../license_pre_routing_factory.ts | 2 +- .../server}/lib/register_license_checker/index.js | 0 .../register_license_checker/register_license_checker.js | 2 +- .../cross_cluster_replication/server}/plugin.ts | 0 .../routes/api/__jest__/auto_follow_pattern.test.js | 4 ++-- .../server}/routes/api/__jest__/follower_index.test.js | 4 ++-- .../server}/routes/api/__jest__/helpers.ts | 0 .../server}/routes/api/auto_follow_pattern.ts | 4 ++-- .../cross_cluster_replication/server}/routes/api/ccr.ts | 2 +- .../server}/routes/api/follower_index.ts | 6 +++--- .../server}/routes/map_to_kibana_http_error.ts | 0 .../server}/routes/register_routes.ts | 0 .../cross_cluster_replication/server}/routes/types.ts | 0 182 files changed, 74 insertions(+), 74 deletions(-) rename x-pack/{legacy => }/plugins/cross_cluster_replication/common/constants/app.ts (100%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/common/constants/base_path.ts (100%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/common/constants/index.ts (100%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/common/constants/plugin.ts (100%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/common/constants/settings.ts (100%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/common/services/__snapshots__/follower_index_serialization.test.js.snap (100%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.js (100%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.test.js (100%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/common/services/follower_index_serialization.js (100%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/common/services/follower_index_serialization.test.js (100%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/common/services/utils.js (100%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/common/services/utils.test.js (100%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/fixtures/auto_follow_pattern.js (95%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/fixtures/es_errors.js (100%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/fixtures/follower_index.js (99%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/fixtures/index.js (100%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/index.js (97%) rename x-pack/{legacy/plugins/cross_cluster_replication => plugins/cross_cluster_replication/public}/__jest__/client_integration/auto_follow_pattern_add.test.js (99%) rename x-pack/{legacy/plugins/cross_cluster_replication => plugins/cross_cluster_replication/public}/__jest__/client_integration/auto_follow_pattern_edit.test.js (95%) rename x-pack/{legacy/plugins/cross_cluster_replication => plugins/cross_cluster_replication/public}/__jest__/client_integration/auto_follow_pattern_list.test.js (98%) rename x-pack/{legacy/plugins/cross_cluster_replication => plugins/cross_cluster_replication/public}/__jest__/client_integration/follower_index_add.test.js (98%) rename x-pack/{legacy/plugins/cross_cluster_replication => plugins/cross_cluster_replication/public}/__jest__/client_integration/follower_index_edit.test.js (96%) rename x-pack/{legacy/plugins/cross_cluster_replication => plugins/cross_cluster_replication/public}/__jest__/client_integration/follower_indices_list.test.js (99%) rename x-pack/{legacy/plugins/cross_cluster_replication => plugins/cross_cluster_replication/public}/__jest__/client_integration/helpers/auto_follow_pattern_add.helpers.js (76%) rename x-pack/{legacy/plugins/cross_cluster_replication => plugins/cross_cluster_replication/public}/__jest__/client_integration/helpers/auto_follow_pattern_edit.helpers.js (82%) rename x-pack/{legacy/plugins/cross_cluster_replication => plugins/cross_cluster_replication/public}/__jest__/client_integration/helpers/auto_follow_pattern_list.helpers.js (92%) rename x-pack/{legacy/plugins/cross_cluster_replication => plugins/cross_cluster_replication/public}/__jest__/client_integration/helpers/constants.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication => plugins/cross_cluster_replication/public}/__jest__/client_integration/helpers/follower_index_add.helpers.js (79%) rename x-pack/{legacy/plugins/cross_cluster_replication => plugins/cross_cluster_replication/public}/__jest__/client_integration/helpers/follower_index_edit.helpers.js (84%) rename x-pack/{legacy/plugins/cross_cluster_replication => plugins/cross_cluster_replication/public}/__jest__/client_integration/helpers/follower_index_list.helpers.js (90%) rename x-pack/{legacy/plugins/cross_cluster_replication => plugins/cross_cluster_replication/public}/__jest__/client_integration/helpers/home.helpers.js (68%) rename x-pack/{legacy/plugins/cross_cluster_replication => plugins/cross_cluster_replication/public}/__jest__/client_integration/helpers/http_requests.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication => plugins/cross_cluster_replication/public}/__jest__/client_integration/helpers/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication => plugins/cross_cluster_replication/public}/__jest__/client_integration/helpers/setup_environment.js (91%) rename x-pack/{legacy/plugins/cross_cluster_replication => plugins/cross_cluster_replication/public}/__jest__/client_integration/home.test.js (97%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/_app.scss (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/app.js (99%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/__snapshots__/auto_follow_pattern_form.test.js.snap (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/auto_follow_pattern_action_menu/auto_follow_pattern_action_menu.container.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/auto_follow_pattern_action_menu/auto_follow_pattern_action_menu.tsx (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/auto_follow_pattern_action_menu/index.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/auto_follow_pattern_delete_provider.d.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/auto_follow_pattern_delete_provider.js (98%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/auto_follow_pattern_form.js (99%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/auto_follow_pattern_form.test.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/auto_follow_pattern_indices_preview.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/auto_follow_pattern_page_title.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/auto_follow_pattern_request_flyout.js (96%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/follower_index_form/__snapshots__/follower_index_form.test.js.snap (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/follower_index_form/advanced_settings_fields.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/follower_index_form/follower_index_form.js (99%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/follower_index_form/follower_index_form.test.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/follower_index_form/follower_index_request_flyout.js (96%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/follower_index_form/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/follower_index_page_title.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/follower_index_pause_provider.js (98%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/follower_index_resume_provider.js (98%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/follower_index_unfollow_provider.js (98%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/form_entry_row.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/remote_clusters_form_field.js (99%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/remote_clusters_provider.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/section_error.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/section_loading.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/components/section_unauthorized.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/constants/api.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/constants/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/constants/sections.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/constants/ui_metric.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.container.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/auto_follow_pattern_add/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.container.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/auto_follow_pattern_edit/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/follower_index_add/follower_index_add.container.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/follower_index_add/follower_index_add.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/follower_index_add/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/follower_index_edit/follower_index_edit.container.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/follower_index_edit/follower_index_edit.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/follower_index_edit/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.container.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.container.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.container.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js (99%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/auto_follow_pattern_list/components/detail_panel/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/auto_follow_pattern_list/components/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/auto_follow_pattern_list/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/follower_indices_list/components/context_menu/context_menu.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/follower_indices_list/components/context_menu/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.container.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.js (99%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/follower_indices_list/components/detail_panel/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/follower_indices_list/components/follower_indices_table/follower_indices_table.container.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/follower_indices_list/components/follower_indices_table/follower_indices_table.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/follower_indices_list/components/follower_indices_table/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/follower_indices_list/components/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/follower_indices_list/follower_indices_list.container.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/follower_indices_list/follower_indices_list.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/follower_indices_list/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/home.container.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/home.js (97%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/home/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/sections/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/__snapshots__/auto_follow_pattern_validators.test.js.snap (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/api.js (98%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/auto_follow_errors.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/auto_follow_errors.test.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/auto_follow_pattern.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/auto_follow_pattern.test.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/auto_follow_pattern_validators.js (97%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/auto_follow_pattern_validators.test.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/breadcrumbs.mock.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/breadcrumbs.ts (92%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/documentation_links.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/follower_index_default_settings.js (89%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/get_remote_cluster_name.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/input_validation.js (97%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/notifications.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/query_params.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/routing.js (99%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/track_ui_metric.js (92%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/utils.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/services/utils.test.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/store/action_types.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/store/actions/api.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/store/actions/auto_follow_pattern.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/store/actions/ccr.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/store/actions/follower_index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/store/actions/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/store/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/store/reducers/api.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/store/reducers/api.test.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/store/reducers/auto_follow_pattern.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/store/reducers/follower_index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/store/reducers/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/store/reducers/stats.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/store/selectors/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/app/store/store.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/extend_index_management.ts (100%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/public/index.js (100%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/public/index.scss (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/index.ts (100%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/public/main.html (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/public/np_ready => plugins/cross_cluster_replication/public}/plugin.ts (100%) rename x-pack/{legacy => }/plugins/cross_cluster_replication/public/register_routes.js (97%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/client/elasticsearch_ccr.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/cross_cluster_replication_data.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/index.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/__snapshots__/ccr_stats_serialization.test.js.snap (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/call_with_request_factory/call_with_request_factory.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/call_with_request_factory/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/ccr_stats_serialization.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/ccr_stats_serialization.test.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/check_license/check_license.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/check_license/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/error_wrappers/__tests__/wrap_es_error.test.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/error_wrappers/index.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/error_wrappers/wrap_es_error.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/is_es_error.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/is_es_error_factory/__tests__/is_es_error_factory.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/is_es_error_factory/index.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/is_es_error_factory/is_es_error_factory.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/license_pre_routing_factory/__jest__/license_pre_routing_factory.test.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/license_pre_routing_factory/index.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/license_pre_routing_factory/license_pre_routing_factory.ts (93%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/register_license_checker/index.js (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/lib/register_license_checker/register_license_checker.js (94%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/plugin.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/routes/api/__jest__/auto_follow_pattern.test.js (98%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/routes/api/__jest__/follower_index.test.js (98%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/routes/api/__jest__/helpers.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/routes/api/auto_follow_pattern.ts (98%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/routes/api/ccr.ts (98%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/routes/api/follower_index.ts (98%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/routes/map_to_kibana_http_error.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/routes/register_routes.ts (100%) rename x-pack/{legacy/plugins/cross_cluster_replication/server/np_ready => plugins/cross_cluster_replication/server}/routes/types.ts (100%) diff --git a/x-pack/legacy/plugins/cross_cluster_replication/common/constants/app.ts b/x-pack/plugins/cross_cluster_replication/common/constants/app.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/common/constants/app.ts rename to x-pack/plugins/cross_cluster_replication/common/constants/app.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/common/constants/base_path.ts b/x-pack/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.ts rename to x-pack/plugins/cross_cluster_replication/common/constants/base_path.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/common/constants/index.ts b/x-pack/plugins/cross_cluster_replication/common/constants/index.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/common/constants/index.ts rename to x-pack/plugins/cross_cluster_replication/common/constants/index.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/common/constants/plugin.ts b/x-pack/plugins/cross_cluster_replication/common/constants/plugin.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/common/constants/plugin.ts rename to x-pack/plugins/cross_cluster_replication/common/constants/plugin.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/common/constants/settings.ts b/x-pack/plugins/cross_cluster_replication/common/constants/settings.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/common/constants/settings.ts rename to x-pack/plugins/cross_cluster_replication/common/constants/settings.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/common/services/__snapshots__/follower_index_serialization.test.js.snap b/x-pack/plugins/cross_cluster_replication/common/services/__snapshots__/follower_index_serialization.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/common/services/__snapshots__/follower_index_serialization.test.js.snap rename to x-pack/plugins/cross_cluster_replication/common/services/__snapshots__/follower_index_serialization.test.js.snap diff --git a/x-pack/legacy/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.js b/x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.js rename to x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.test.js b/x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.test.js rename to x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/common/services/follower_index_serialization.js b/x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/common/services/follower_index_serialization.js rename to x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/common/services/follower_index_serialization.test.js b/x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/common/services/follower_index_serialization.test.js rename to x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/common/services/utils.js b/x-pack/plugins/cross_cluster_replication/common/services/utils.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/common/services/utils.js rename to x-pack/plugins/cross_cluster_replication/common/services/utils.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/common/services/utils.test.js b/x-pack/plugins/cross_cluster_replication/common/services/utils.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/common/services/utils.test.js rename to x-pack/plugins/cross_cluster_replication/common/services/utils.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/fixtures/auto_follow_pattern.js b/x-pack/plugins/cross_cluster_replication/fixtures/auto_follow_pattern.js similarity index 95% rename from x-pack/legacy/plugins/cross_cluster_replication/fixtures/auto_follow_pattern.js rename to x-pack/plugins/cross_cluster_replication/fixtures/auto_follow_pattern.js index 804fe80cd27b4..a5e9a636b4c04 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/fixtures/auto_follow_pattern.js +++ b/x-pack/plugins/cross_cluster_replication/fixtures/auto_follow_pattern.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { getRandomString } from '../../../../test_utils'; +import { getRandomString } from '../../../test_utils'; export const getAutoFollowPatternMock = ( name = getRandomString(), diff --git a/x-pack/legacy/plugins/cross_cluster_replication/fixtures/es_errors.js b/x-pack/plugins/cross_cluster_replication/fixtures/es_errors.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/fixtures/es_errors.js rename to x-pack/plugins/cross_cluster_replication/fixtures/es_errors.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/fixtures/follower_index.js b/x-pack/plugins/cross_cluster_replication/fixtures/follower_index.js similarity index 99% rename from x-pack/legacy/plugins/cross_cluster_replication/fixtures/follower_index.js rename to x-pack/plugins/cross_cluster_replication/fixtures/follower_index.js index 6c535a665978c..d02689beef657 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/fixtures/follower_index.js +++ b/x-pack/plugins/cross_cluster_replication/fixtures/follower_index.js @@ -6,7 +6,7 @@ const Chance = require('chance'); // eslint-disable-line import/no-extraneous-dependencies const chance = new Chance(); -import { getRandomString } from '../../../../test_utils'; +import { getRandomString } from '../../../test_utils'; const serializeShard = ({ id, diff --git a/x-pack/legacy/plugins/cross_cluster_replication/fixtures/index.js b/x-pack/plugins/cross_cluster_replication/fixtures/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/fixtures/index.js rename to x-pack/plugins/cross_cluster_replication/fixtures/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/index.js b/x-pack/plugins/cross_cluster_replication/index.js similarity index 97% rename from x-pack/legacy/plugins/cross_cluster_replication/index.js rename to x-pack/plugins/cross_cluster_replication/index.js index aff4cc5b56738..8c3d07cdaaf0d 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/index.js +++ b/x-pack/plugins/cross_cluster_replication/index.js @@ -6,7 +6,7 @@ import { resolve } from 'path'; import { PLUGIN } from './common/constants'; -import { plugin } from './server/np_ready'; +import { plugin } from './server'; export function crossClusterReplication(kibana) { return new kibana.Plugin({ diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_add.test.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_add.test.js similarity index 99% rename from x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_add.test.js rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_add.test.js index 2be00e70f6f84..d2f8830e47d13 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_add.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__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 '../../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/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_edit.test.js similarity index 95% rename from x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_edit.test.js rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_edit.test.js index abc3e5dc9def2..760105beb7f8a 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_edit.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_edit.test.js @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../public/np_ready/app/services/breadcrumbs.mock'; -import { AutoFollowPatternForm } from '../../public/np_ready/app/components/auto_follow_pattern_form'; +import '../../app/services/breadcrumbs.mock'; +import { AutoFollowPatternForm } from '../../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/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_list.test.js similarity index 98% rename from x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_list.test.js rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_list.test.js index 20e982856dc19..8a47b18214449 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/auto_follow_pattern_list.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_list.test.js @@ -4,10 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../public/np_ready/app/services/breadcrumbs.mock'; +import '../../app/services/breadcrumbs.mock'; import { setupEnvironment, pageHelpers, nextTick, getRandomString } from './helpers'; -import { getAutoFollowPatternClientMock } from '../../fixtures/auto_follow_pattern'; +import { getAutoFollowPatternClientMock } from '../../../fixtures/auto_follow_pattern'; jest.mock('ui/new_platform'); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_index_add.test.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_index_add.test.js similarity index 98% rename from x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_index_add.test.js rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_index_add.test.js index 7680be9d858a4..16e3726d7fede 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_index_add.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_index_add.test.js @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../public/np_ready/app/services/breadcrumbs.mock'; +import '../../app/services/breadcrumbs.mock'; import { setupEnvironment, pageHelpers, nextTick } from './helpers'; -import { RemoteClustersFormField } from '../../public/np_ready/app/components'; +import { RemoteClustersFormField } from '../../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/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_index_edit.test.js similarity index 96% rename from x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_index_edit.test.js rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_index_edit.test.js index cfa37ff2e0358..4e54d8e9d7c40 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_index_edit.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_index_edit.test.js @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../public/np_ready/app/services/breadcrumbs.mock'; +import '../../app/services/breadcrumbs.mock'; import { setupEnvironment, pageHelpers, nextTick } from './helpers'; -import { FollowerIndexForm } from '../../public/np_ready/app/components/follower_index_form/follower_index_form'; +import { FollowerIndexForm } from '../../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/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js similarity index 99% rename from x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_indices_list.test.js rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js index dde31d1d166f9..96e5b4fe1eb4b 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/follower_indices_list.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js @@ -6,7 +6,7 @@ import { setupEnvironment, pageHelpers, nextTick, getRandomString } from './helpers'; -import { getFollowerIndexMock } from '../../fixtures/follower_index'; +import { getFollowerIndexMock } from '../../../fixtures/follower_index'; jest.mock('ui/new_platform'); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_add.helpers.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_add.helpers.js similarity index 76% rename from x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_add.helpers.js rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_add.helpers.js index 1f64e589bc4c1..24d759b8e68c3 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_add.helpers.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_add.helpers.js @@ -5,9 +5,9 @@ */ import { registerTestBed } from '../../../../../../test_utils'; -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'; +import { AutoFollowPatternAdd } from '../../../app/sections/auto_follow_pattern_add'; +import { ccrStore } from '../../../app/store'; +import routing from '../../../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/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_edit.helpers.js similarity index 82% rename from x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_edit.helpers.js rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_edit.helpers.js index 2b110c6552072..8b245227fed6c 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_edit.helpers.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_edit.helpers.js @@ -5,9 +5,9 @@ */ import { registerTestBed } from '../../../../../../test_utils'; -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 { AutoFollowPatternEdit } from '../../../app/sections/auto_follow_pattern_edit'; +import { ccrStore } from '../../../app/store'; +import routing from '../../../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/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_list.helpers.js similarity index 92% rename from x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_list.helpers.js rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_list.helpers.js index 1d3e8ad6dff83..7588ed1fd82b6 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/auto_follow_pattern_list.helpers.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_list.helpers.js @@ -5,9 +5,9 @@ */ import { registerTestBed, findTestSubject } from '../../../../../../test_utils'; -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'; +import { AutoFollowPatternList } from '../../../app/sections/home/auto_follow_pattern_list'; +import { ccrStore } from '../../../app/store'; +import routing from '../../../app/services/routing'; const testBedConfig = { store: ccrStore, diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/constants.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/constants.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/constants.js rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/constants.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_add.helpers.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_add.helpers.js similarity index 79% rename from x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_add.helpers.js rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_add.helpers.js index f74baa1b2ad0a..82acd8b2156bd 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_add.helpers.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_add.helpers.js @@ -5,9 +5,9 @@ */ import { registerTestBed } from '../../../../../../test_utils'; -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'; +import { FollowerIndexAdd } from '../../../app/sections/follower_index_add'; +import { ccrStore } from '../../../app/store'; +import routing from '../../../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/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_edit.helpers.js similarity index 84% rename from x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_edit.helpers.js rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_edit.helpers.js index 47f8539bb593b..45e21a6d32eab 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_edit.helpers.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_edit.helpers.js @@ -5,9 +5,9 @@ */ import { registerTestBed } from '../../../../../../test_utils'; -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 { FollowerIndexEdit } from '../../../app/sections/follower_index_edit'; +import { ccrStore } from '../../../app/store'; +import routing from '../../../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/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_list.helpers.js similarity index 90% rename from x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_list.helpers.js rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_list.helpers.js index 2154e11e17b1f..075b38fee1708 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/follower_index_list.helpers.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_list.helpers.js @@ -5,9 +5,9 @@ */ import { registerTestBed, findTestSubject } from '../../../../../../test_utils'; -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'; +import { FollowerIndicesList } from '../../../app/sections/home/follower_indices_list'; +import { ccrStore } from '../../../app/store'; +import routing from '../../../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/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/home.helpers.js similarity index 68% rename from x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/home.helpers.js rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/home.helpers.js index 664ad909ba8e7..3260f54e2cf20 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/home.helpers.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/home.helpers.js @@ -5,10 +5,10 @@ */ import { registerTestBed } from '../../../../../../test_utils'; -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'; +import { CrossClusterReplicationHome } from '../../../app/sections/home/home'; +import { ccrStore } from '../../../app/store'; +import routing from '../../../app/services/routing'; +import { BASE_PATH } from '../../../../../../legacy/common/constants'; const testBedConfig = { store: ccrStore, diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/http_requests.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/http_requests.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/http_requests.js rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/http_requests.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/index.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/index.js rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/setup_environment.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/setup_environment.js similarity index 91% rename from x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/setup_environment.js rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/setup_environment.js index 3562ad0df5b51..6dedbbfa79b19 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/helpers/setup_environment.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/setup_environment.js @@ -7,7 +7,7 @@ import axios from 'axios'; import axiosXhrAdapter from 'axios/lib/adapters/xhr'; -import { setHttpClient } from '../../../public/np_ready/app/services/api'; +import { setHttpClient } from '../../../app/services/api'; import { init as initHttpRequests } from './http_requests'; export const setupEnvironment = () => { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/home.test.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/home.test.js similarity index 97% rename from x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/home.test.js rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/home.test.js index 2c536d069ef53..855675a9e9c7a 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/__jest__/client_integration/home.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/home.test.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../public/np_ready/app/services/breadcrumbs.mock'; +import '../../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/public/np_ready/app/_app.scss b/x-pack/plugins/cross_cluster_replication/public/app/_app.scss similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/_app.scss rename to x-pack/plugins/cross_cluster_replication/public/app/_app.scss diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/app.js b/x-pack/plugins/cross_cluster_replication/public/app/app.js similarity index 99% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/app.js rename to x-pack/plugins/cross_cluster_replication/public/app/app.js index 968646a4bd1b0..bdf8ff0e90ab9 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/app.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/app.js @@ -20,7 +20,7 @@ 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'; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/__snapshots__/auto_follow_pattern_form.test.js.snap b/x-pack/plugins/cross_cluster_replication/public/app/components/__snapshots__/auto_follow_pattern_form.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/__snapshots__/auto_follow_pattern_form.test.js.snap rename to x-pack/plugins/cross_cluster_replication/public/app/components/__snapshots__/auto_follow_pattern_form.test.js.snap diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_action_menu/auto_follow_pattern_action_menu.container.ts b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/components/auto_follow_pattern_action_menu/auto_follow_pattern_action_menu.container.ts rename to x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/components/auto_follow_pattern_action_menu/auto_follow_pattern_action_menu.tsx b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/components/auto_follow_pattern_action_menu/auto_follow_pattern_action_menu.tsx rename to x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_action_menu/auto_follow_pattern_action_menu.tsx diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_action_menu/index.ts b/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_action_menu/index.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_action_menu/index.ts rename to x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_action_menu/index.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_delete_provider.d.ts b/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_delete_provider.d.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_delete_provider.d.ts rename to x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_delete_provider.d.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_delete_provider.js b/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_delete_provider.js similarity index 98% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_delete_provider.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_delete_provider.js index 7803b329e6258..f9c03165dcf97 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_delete_provider.js +++ b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/components/auto_follow_pattern_form.js b/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_form.js similarity index 99% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_form.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_form.js index 5bc5d8ba6e402..4e36b288879f0 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_form.js +++ b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/components/auto_follow_pattern_form.test.js b/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_form.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_form.test.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_form.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_indices_preview.js b/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_indices_preview.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_indices_preview.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_indices_preview.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_page_title.js b/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_page_title.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_page_title.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_page_title.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_request_flyout.js b/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_request_flyout.js similarity index 96% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_request_flyout.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_request_flyout.js index 1377ccc9debd6..7e0bd510a1a86 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/auto_follow_pattern_request_flyout.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_request_flyout.js @@ -26,7 +26,7 @@ import { EuiTitle, } from '@elastic/eui'; -import { serializeAutoFollowPattern } from '../../../../common/services/auto_follow_pattern_serialization'; +import { serializeAutoFollowPattern } from '../../../common/services/auto_follow_pattern_serialization'; export class AutoFollowPatternRequestFlyout extends PureComponent { static propTypes = { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/__snapshots__/follower_index_form.test.js.snap b/x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_form/__snapshots__/follower_index_form.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/__snapshots__/follower_index_form.test.js.snap rename to x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_form/__snapshots__/follower_index_form.test.js.snap diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/advanced_settings_fields.js b/x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_form/advanced_settings_fields.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/advanced_settings_fields.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_form/advanced_settings_fields.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_form.js b/x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_form/follower_index_form.js similarity index 99% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_form.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_form/follower_index_form.js index 50b22289e30f8..02dc8ba61dd83 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_form.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_form/follower_index_form.js @@ -28,7 +28,7 @@ import { EuiTitle, } from '@elastic/eui'; -import { indices } from '../../../../../../../../../src/plugins/es_ui_shared/public'; +import { indices } from '../../../../../../../src/plugins/es_ui_shared/public'; import { indexNameValidator, leaderIndexValidator } from '../../services/input_validation'; import routing from '../../services/routing'; import { getFatalErrors } from '../../services/notifications'; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_form.test.js b/x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_form/follower_index_form.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_form.test.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_form/follower_index_form.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_request_flyout.js b/x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_form/follower_index_request_flyout.js similarity index 96% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_request_flyout.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_form/follower_index_request_flyout.js index cb02a929b16f8..cba1c104e45d9 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/follower_index_request_flyout.js +++ b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/components/follower_index_form/index.js b/x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_form/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_form/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_form/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_page_title.js b/x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_page_title.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_page_title.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_page_title.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_pause_provider.js b/x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_pause_provider.js similarity index 98% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_pause_provider.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_pause_provider.js index 56372425b708f..5965bfd8cc603 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_pause_provider.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_pause_provider.js @@ -12,7 +12,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EuiConfirmModal, EuiOverlayMask } from '@elastic/eui'; import { pauseFollowerIndex } from '../store/actions'; -import { arrify } from '../../../../common/services/utils'; +import { arrify } from '../../../common/services/utils'; import { areAllSettingsDefault } from '../services/follower_index_default_settings'; class FollowerIndexPauseProviderUi extends PureComponent { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_resume_provider.js b/x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_resume_provider.js similarity index 98% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_resume_provider.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_resume_provider.js index 56e1d93106807..e4749d9e5cf38 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_resume_provider.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_resume_provider.js @@ -13,7 +13,7 @@ import { EuiConfirmModal, EuiLink, EuiOverlayMask } from '@elastic/eui'; import routing from '../services/routing'; import { resumeFollowerIndex } from '../store/actions'; -import { arrify } from '../../../../common/services/utils'; +import { arrify } from '../../../common/services/utils'; class FollowerIndexResumeProviderUi extends PureComponent { static propTypes = { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_unfollow_provider.js b/x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_unfollow_provider.js similarity index 98% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_unfollow_provider.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_unfollow_provider.js index 8ebc38e9296c1..f3b267a69b18c 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/follower_index_unfollow_provider.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/components/follower_index_unfollow_provider.js @@ -12,7 +12,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EuiConfirmModal, EuiOverlayMask } from '@elastic/eui'; import { unfollowLeaderIndex } from '../store/actions'; -import { arrify } from '../../../../common/services/utils'; +import { arrify } from '../../../common/services/utils'; class FollowerIndexUnfollowProviderUi extends PureComponent { static propTypes = { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/form_entry_row.js b/x-pack/plugins/cross_cluster_replication/public/app/components/form_entry_row.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/form_entry_row.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/form_entry_row.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/index.js b/x-pack/plugins/cross_cluster_replication/public/app/components/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/remote_clusters_form_field.js b/x-pack/plugins/cross_cluster_replication/public/app/components/remote_clusters_form_field.js similarity index 99% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/remote_clusters_form_field.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/remote_clusters_form_field.js index 6a4eb7e775f3c..ad6cfdd18c6f4 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/remote_clusters_form_field.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/components/remote_clusters_form_field.js @@ -19,7 +19,7 @@ import { } from '@elastic/eui'; import routing from '../services/routing'; -import { BASE_PATH_REMOTE_CLUSTERS } from '../../../../common/constants'; +import { BASE_PATH_REMOTE_CLUSTERS } from '../../../common/constants'; const errorMessages = { noClusterFound: () => ( diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/remote_clusters_provider.js b/x-pack/plugins/cross_cluster_replication/public/app/components/remote_clusters_provider.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/remote_clusters_provider.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/remote_clusters_provider.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/section_error.js b/x-pack/plugins/cross_cluster_replication/public/app/components/section_error.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/section_error.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/section_error.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/section_loading.js b/x-pack/plugins/cross_cluster_replication/public/app/components/section_loading.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/section_loading.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/section_loading.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/section_unauthorized.js b/x-pack/plugins/cross_cluster_replication/public/app/components/section_unauthorized.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/components/section_unauthorized.js rename to x-pack/plugins/cross_cluster_replication/public/app/components/section_unauthorized.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/api.js b/x-pack/plugins/cross_cluster_replication/public/app/constants/api.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/api.js rename to x-pack/plugins/cross_cluster_replication/public/app/constants/api.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/index.js b/x-pack/plugins/cross_cluster_replication/public/app/constants/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/constants/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/sections.js b/x-pack/plugins/cross_cluster_replication/public/app/constants/sections.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/sections.js rename to x-pack/plugins/cross_cluster_replication/public/app/constants/sections.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/ui_metric.js b/x-pack/plugins/cross_cluster_replication/public/app/constants/ui_metric.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/constants/ui_metric.js rename to x-pack/plugins/cross_cluster_replication/public/app/constants/ui_metric.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/index.js b/x-pack/plugins/cross_cluster_replication/public/app/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.container.js b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.container.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_add/auto_follow_pattern_add.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_add/index.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_add/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_add/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_add/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.container.js b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.container.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_edit/index.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/auto_follow_pattern_edit/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_add/follower_index_add.container.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/follower_index_add/follower_index_add.container.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_add/follower_index_add.container.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/follower_index_add/follower_index_add.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_add/follower_index_add.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/follower_index_add/follower_index_add.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_add/follower_index_add.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/follower_index_add/follower_index_add.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_add/index.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/follower_index_add/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_add/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/follower_index_add/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_edit/follower_index_edit.container.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/follower_index_edit/follower_index_edit.container.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_edit/follower_index_edit.container.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/follower_index_edit/follower_index_edit.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_edit/follower_index_edit.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/follower_index_edit/follower_index_edit.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_edit/follower_index_edit.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/follower_index_edit/follower_index_edit.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_edit/index.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/follower_index_edit/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/follower_index_edit/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/follower_index_edit/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.container.js b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.container.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.js b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.js diff --git a/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 b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.container.js rename to x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.js b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.js rename to x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/index.js b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/index.js rename to x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.container.js b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.container.js rename to x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js index 1a6d5e6efe35a..51db467cc78b1 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js +++ b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/auto_follow_pattern_list/components/detail_panel/index.js b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/auto_follow_pattern_list/components/detail_panel/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/components/index.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/components/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/index.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/auto_follow_pattern_list/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/context_menu/context_menu.js b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/follower_indices_list/components/context_menu/context_menu.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/context_menu/context_menu.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/context_menu/index.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/context_menu/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/context_menu/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/context_menu/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.container.js b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.container.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.js b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.js index 3e8cf6d3e2f78..4020b75a04de2 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/detail_panel/detail_panel.js +++ b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/follower_indices_list/components/detail_panel/index.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/detail_panel/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/detail_panel/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/detail_panel/index.js diff --git a/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 b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/follower_indices_list/components/follower_indices_table/follower_indices_table.container.js rename to x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/follower_indices_list/components/follower_indices_table/follower_indices_table.js b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/follower_indices_list/components/follower_indices_table/follower_indices_table.js rename to x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/follower_indices_list/components/follower_indices_table/index.js b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/sections/home/follower_indices_list/components/follower_indices_table/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/follower_indices_table/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/index.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/components/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/follower_indices_list.container.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/follower_indices_list.container.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/follower_indices_list.container.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/follower_indices_list.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/follower_indices_list.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/follower_indices_list.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/follower_indices_list.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/follower_indices_list.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/index.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/follower_indices_list/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/home.container.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/home.container.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/home.container.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/home.container.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/home.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/home.js similarity index 97% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/home.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/home.js index 88db909612245..a8babd1f3995f 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/home.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/home.js @@ -10,7 +10,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EuiPageBody, EuiPageContent, EuiSpacer, EuiTab, EuiTabs, EuiTitle } from '@elastic/eui'; -import { BASE_PATH } from '../../../../../common/constants'; +import { BASE_PATH } from '../../../../common/constants'; import { setBreadcrumbs, listBreadcrumb } from '../../services/breadcrumbs'; import routing from '../../services/routing'; import { AutoFollowPatternList } from './auto_follow_pattern_list'; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/index.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/home/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/home/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/index.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/sections/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/sections/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/__snapshots__/auto_follow_pattern_validators.test.js.snap b/x-pack/plugins/cross_cluster_replication/public/app/services/__snapshots__/auto_follow_pattern_validators.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/__snapshots__/auto_follow_pattern_validators.test.js.snap rename to x-pack/plugins/cross_cluster_replication/public/app/services/__snapshots__/auto_follow_pattern_validators.test.js.snap diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/api.js b/x-pack/plugins/cross_cluster_replication/public/app/services/api.js similarity index 98% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/api.js rename to x-pack/plugins/cross_cluster_replication/public/app/services/api.js index 24bc7e17356e2..adff40ef29be6 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/api.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/services/api.js @@ -7,8 +7,8 @@ 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, diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_errors.js b/x-pack/plugins/cross_cluster_replication/public/app/services/auto_follow_errors.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_errors.js rename to x-pack/plugins/cross_cluster_replication/public/app/services/auto_follow_errors.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_errors.test.js b/x-pack/plugins/cross_cluster_replication/public/app/services/auto_follow_errors.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_errors.test.js rename to x-pack/plugins/cross_cluster_replication/public/app/services/auto_follow_errors.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern.js b/x-pack/plugins/cross_cluster_replication/public/app/services/auto_follow_pattern.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern.js rename to x-pack/plugins/cross_cluster_replication/public/app/services/auto_follow_pattern.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern.test.js b/x-pack/plugins/cross_cluster_replication/public/app/services/auto_follow_pattern.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern.test.js rename to x-pack/plugins/cross_cluster_replication/public/app/services/auto_follow_pattern.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern_validators.js b/x-pack/plugins/cross_cluster_replication/public/app/services/auto_follow_pattern_validators.js similarity index 97% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern_validators.js rename to x-pack/plugins/cross_cluster_replication/public/app/services/auto_follow_pattern_validators.js index 1b5a39658ee46..cf394d4b3c7d8 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern_validators.js +++ b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/services/auto_follow_pattern_validators.test.js b/x-pack/plugins/cross_cluster_replication/public/app/services/auto_follow_pattern_validators.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/auto_follow_pattern_validators.test.js rename to x-pack/plugins/cross_cluster_replication/public/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/plugins/cross_cluster_replication/public/app/services/breadcrumbs.mock.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/breadcrumbs.mock.ts rename to x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.mock.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/breadcrumbs.ts b/x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.ts similarity index 92% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/breadcrumbs.ts rename to x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.ts index dc64cdee07f7d..69b68ab01fc5d 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/breadcrumbs.ts +++ b/x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.ts @@ -6,7 +6,7 @@ import { i18n } from '@kbn/i18n'; import { ChromeBreadcrumb } from 'src/core/public'; -import { ManagementAppMountParams } from '../../../../../../../../src/plugins/management/public'; +import { ManagementAppMountParams } from '../../../../../../../src/plugins/management/public'; import { BASE_PATH } from '../../../../common/constants'; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/documentation_links.ts b/x-pack/plugins/cross_cluster_replication/public/app/services/documentation_links.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/documentation_links.ts rename to x-pack/plugins/cross_cluster_replication/public/app/services/documentation_links.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/follower_index_default_settings.js b/x-pack/plugins/cross_cluster_replication/public/app/services/follower_index_default_settings.js similarity index 89% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/follower_index_default_settings.js rename to x-pack/plugins/cross_cluster_replication/public/app/services/follower_index_default_settings.js index d20fa76ef5451..118a54887d404 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/follower_index_default_settings.js +++ b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/services/get_remote_cluster_name.js b/x-pack/plugins/cross_cluster_replication/public/app/services/get_remote_cluster_name.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/get_remote_cluster_name.js rename to x-pack/plugins/cross_cluster_replication/public/app/services/get_remote_cluster_name.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/input_validation.js b/x-pack/plugins/cross_cluster_replication/public/app/services/input_validation.js similarity index 97% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/input_validation.js rename to x-pack/plugins/cross_cluster_replication/public/app/services/input_validation.js index 64c3e8412437e..7e2b45b625c1f 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/input_validation.js +++ b/x-pack/plugins/cross_cluster_replication/public/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/plugins/cross_cluster_replication/public/app/services/notifications.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/notifications.ts rename to x-pack/plugins/cross_cluster_replication/public/app/services/notifications.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/query_params.js b/x-pack/plugins/cross_cluster_replication/public/app/services/query_params.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/query_params.js rename to x-pack/plugins/cross_cluster_replication/public/app/services/query_params.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/routing.js b/x-pack/plugins/cross_cluster_replication/public/app/services/routing.js similarity index 99% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/routing.js rename to x-pack/plugins/cross_cluster_replication/public/app/services/routing.js index 965aeaaad22ad..487b1068794f9 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/routing.js +++ b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/services/track_ui_metric.js b/x-pack/plugins/cross_cluster_replication/public/app/services/track_ui_metric.js similarity index 92% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/track_ui_metric.js rename to x-pack/plugins/cross_cluster_replication/public/app/services/track_ui_metric.js index 36b9c185b487d..d3effd1dd7e16 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/track_ui_metric.js +++ b/x-pack/plugins/cross_cluster_replication/public/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/np_ready/app/services/utils.js b/x-pack/plugins/cross_cluster_replication/public/app/services/utils.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/utils.js rename to x-pack/plugins/cross_cluster_replication/public/app/services/utils.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/utils.test.js b/x-pack/plugins/cross_cluster_replication/public/app/services/utils.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/services/utils.test.js rename to x-pack/plugins/cross_cluster_replication/public/app/services/utils.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/action_types.js b/x-pack/plugins/cross_cluster_replication/public/app/store/action_types.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/action_types.js rename to x-pack/plugins/cross_cluster_replication/public/app/store/action_types.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/api.js b/x-pack/plugins/cross_cluster_replication/public/app/store/actions/api.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/api.js rename to x-pack/plugins/cross_cluster_replication/public/app/store/actions/api.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/auto_follow_pattern.js b/x-pack/plugins/cross_cluster_replication/public/app/store/actions/auto_follow_pattern.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/auto_follow_pattern.js rename to x-pack/plugins/cross_cluster_replication/public/app/store/actions/auto_follow_pattern.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/ccr.js b/x-pack/plugins/cross_cluster_replication/public/app/store/actions/ccr.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/ccr.js rename to x-pack/plugins/cross_cluster_replication/public/app/store/actions/ccr.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/follower_index.js b/x-pack/plugins/cross_cluster_replication/public/app/store/actions/follower_index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/follower_index.js rename to x-pack/plugins/cross_cluster_replication/public/app/store/actions/follower_index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/index.js b/x-pack/plugins/cross_cluster_replication/public/app/store/actions/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/actions/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/store/actions/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/index.js b/x-pack/plugins/cross_cluster_replication/public/app/store/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/store/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/api.js b/x-pack/plugins/cross_cluster_replication/public/app/store/reducers/api.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/api.js rename to x-pack/plugins/cross_cluster_replication/public/app/store/reducers/api.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/api.test.js b/x-pack/plugins/cross_cluster_replication/public/app/store/reducers/api.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/api.test.js rename to x-pack/plugins/cross_cluster_replication/public/app/store/reducers/api.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/auto_follow_pattern.js b/x-pack/plugins/cross_cluster_replication/public/app/store/reducers/auto_follow_pattern.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/auto_follow_pattern.js rename to x-pack/plugins/cross_cluster_replication/public/app/store/reducers/auto_follow_pattern.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/follower_index.js b/x-pack/plugins/cross_cluster_replication/public/app/store/reducers/follower_index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/follower_index.js rename to x-pack/plugins/cross_cluster_replication/public/app/store/reducers/follower_index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/index.js b/x-pack/plugins/cross_cluster_replication/public/app/store/reducers/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/store/reducers/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/stats.js b/x-pack/plugins/cross_cluster_replication/public/app/store/reducers/stats.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/reducers/stats.js rename to x-pack/plugins/cross_cluster_replication/public/app/store/reducers/stats.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/selectors/index.js b/x-pack/plugins/cross_cluster_replication/public/app/store/selectors/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/selectors/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/store/selectors/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/store.js b/x-pack/plugins/cross_cluster_replication/public/app/store/store.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/app/store/store.js rename to x-pack/plugins/cross_cluster_replication/public/app/store/store.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/extend_index_management.ts b/x-pack/plugins/cross_cluster_replication/public/extend_index_management.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/extend_index_management.ts rename to x-pack/plugins/cross_cluster_replication/public/extend_index_management.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/index.js b/x-pack/plugins/cross_cluster_replication/public/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/index.js rename to x-pack/plugins/cross_cluster_replication/public/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/index.scss b/x-pack/plugins/cross_cluster_replication/public/index.scss similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/index.scss rename to x-pack/plugins/cross_cluster_replication/public/index.scss diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/index.ts b/x-pack/plugins/cross_cluster_replication/public/index.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/index.ts rename to x-pack/plugins/cross_cluster_replication/public/index.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/main.html b/x-pack/plugins/cross_cluster_replication/public/main.html similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/main.html rename to x-pack/plugins/cross_cluster_replication/public/main.html diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/plugin.ts b/x-pack/plugins/cross_cluster_replication/public/plugin.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/public/np_ready/plugin.ts rename to x-pack/plugins/cross_cluster_replication/public/plugin.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/public/register_routes.js b/x-pack/plugins/cross_cluster_replication/public/register_routes.js similarity index 97% rename from x-pack/legacy/plugins/cross_cluster_replication/public/register_routes.js rename to x-pack/plugins/cross_cluster_replication/public/register_routes.js index 838939f46e523..055cfd229183b 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/public/register_routes.js +++ b/x-pack/plugins/cross_cluster_replication/public/register_routes.js @@ -15,12 +15,12 @@ import { i18n } from '@kbn/i18n'; import template from './main.html'; import { BASE_PATH } from '../common/constants'; -import { plugin } from './np_ready'; +import { plugin } from './index'; /** * TODO: When this file is deleted, use the management section for rendering */ -import { renderReact } from './np_ready/app'; +import { renderReact } from './app'; const isAvailable = xpackInfo.get('features.crossClusterReplication.isAvailable'); const isActive = xpackInfo.get('features.crossClusterReplication.isActive'); diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/client/elasticsearch_ccr.js b/x-pack/plugins/cross_cluster_replication/server/client/elasticsearch_ccr.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/client/elasticsearch_ccr.js rename to x-pack/plugins/cross_cluster_replication/server/client/elasticsearch_ccr.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/cross_cluster_replication_data.ts b/x-pack/plugins/cross_cluster_replication/server/cross_cluster_replication_data.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/cross_cluster_replication_data.ts rename to x-pack/plugins/cross_cluster_replication/server/cross_cluster_replication_data.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/index.ts b/x-pack/plugins/cross_cluster_replication/server/index.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/index.ts rename to x-pack/plugins/cross_cluster_replication/server/index.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/__snapshots__/ccr_stats_serialization.test.js.snap b/x-pack/plugins/cross_cluster_replication/server/lib/__snapshots__/ccr_stats_serialization.test.js.snap similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/__snapshots__/ccr_stats_serialization.test.js.snap rename to x-pack/plugins/cross_cluster_replication/server/lib/__snapshots__/ccr_stats_serialization.test.js.snap diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/call_with_request_factory/call_with_request_factory.js b/x-pack/plugins/cross_cluster_replication/server/lib/call_with_request_factory/call_with_request_factory.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/call_with_request_factory/call_with_request_factory.js rename to x-pack/plugins/cross_cluster_replication/server/lib/call_with_request_factory/call_with_request_factory.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/call_with_request_factory/index.js b/x-pack/plugins/cross_cluster_replication/server/lib/call_with_request_factory/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/call_with_request_factory/index.js rename to x-pack/plugins/cross_cluster_replication/server/lib/call_with_request_factory/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/ccr_stats_serialization.js b/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/ccr_stats_serialization.js rename to x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/ccr_stats_serialization.test.js b/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/ccr_stats_serialization.test.js rename to x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/check_license/check_license.js b/x-pack/plugins/cross_cluster_replication/server/lib/check_license/check_license.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/check_license/check_license.js rename to x-pack/plugins/cross_cluster_replication/server/lib/check_license/check_license.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/check_license/index.js b/x-pack/plugins/cross_cluster_replication/server/lib/check_license/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/check_license/index.js rename to x-pack/plugins/cross_cluster_replication/server/lib/check_license/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/error_wrappers/__tests__/wrap_es_error.test.js b/x-pack/plugins/cross_cluster_replication/server/lib/error_wrappers/__tests__/wrap_es_error.test.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/error_wrappers/__tests__/wrap_es_error.test.js rename to x-pack/plugins/cross_cluster_replication/server/lib/error_wrappers/__tests__/wrap_es_error.test.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/error_wrappers/index.ts b/x-pack/plugins/cross_cluster_replication/server/lib/error_wrappers/index.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/error_wrappers/index.ts rename to x-pack/plugins/cross_cluster_replication/server/lib/error_wrappers/index.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/error_wrappers/wrap_es_error.ts b/x-pack/plugins/cross_cluster_replication/server/lib/error_wrappers/wrap_es_error.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/error_wrappers/wrap_es_error.ts rename to x-pack/plugins/cross_cluster_replication/server/lib/error_wrappers/wrap_es_error.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/is_es_error.ts b/x-pack/plugins/cross_cluster_replication/server/lib/is_es_error.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/is_es_error.ts rename to x-pack/plugins/cross_cluster_replication/server/lib/is_es_error.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/is_es_error_factory/__tests__/is_es_error_factory.js b/x-pack/plugins/cross_cluster_replication/server/lib/is_es_error_factory/__tests__/is_es_error_factory.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/is_es_error_factory/__tests__/is_es_error_factory.js rename to x-pack/plugins/cross_cluster_replication/server/lib/is_es_error_factory/__tests__/is_es_error_factory.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/is_es_error_factory/index.ts b/x-pack/plugins/cross_cluster_replication/server/lib/is_es_error_factory/index.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/is_es_error_factory/index.ts rename to x-pack/plugins/cross_cluster_replication/server/lib/is_es_error_factory/index.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/is_es_error_factory/is_es_error_factory.ts b/x-pack/plugins/cross_cluster_replication/server/lib/is_es_error_factory/is_es_error_factory.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/is_es_error_factory/is_es_error_factory.ts rename to x-pack/plugins/cross_cluster_replication/server/lib/is_es_error_factory/is_es_error_factory.ts 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/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/__jest__/license_pre_routing_factory.test.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/license_pre_routing_factory/__jest__/license_pre_routing_factory.test.ts rename to x-pack/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/__jest__/license_pre_routing_factory.test.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/license_pre_routing_factory/index.ts b/x-pack/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/index.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/license_pre_routing_factory/index.ts rename to x-pack/plugins/cross_cluster_replication/server/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/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/license_pre_routing_factory.ts similarity index 93% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/license_pre_routing_factory/license_pre_routing_factory.ts rename to x-pack/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/license_pre_routing_factory.ts index c47faa940a650..1c9ff9918fe59 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/license_pre_routing_factory/license_pre_routing_factory.ts +++ b/x-pack/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/license_pre_routing_factory.ts @@ -5,7 +5,7 @@ */ import { RequestHandler } from 'src/core/server'; -import { PLUGIN } from '../../../../common/constants'; +import { PLUGIN } from '../../../../../../legacy/common/constants'; export const licensePreRoutingFactory = ({ __LEGACY, diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/register_license_checker/index.js b/x-pack/plugins/cross_cluster_replication/server/lib/register_license_checker/index.js similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/register_license_checker/index.js rename to x-pack/plugins/cross_cluster_replication/server/lib/register_license_checker/index.js diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/register_license_checker/register_license_checker.js b/x-pack/plugins/cross_cluster_replication/server/lib/register_license_checker/register_license_checker.js similarity index 94% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/register_license_checker/register_license_checker.js rename to x-pack/plugins/cross_cluster_replication/server/lib/register_license_checker/register_license_checker.js index b9bb34a80ce79..bd23c6d4fd562 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/lib/register_license_checker/register_license_checker.js +++ b/x-pack/plugins/cross_cluster_replication/server/lib/register_license_checker/register_license_checker.js @@ -5,7 +5,7 @@ */ import { mirrorPluginStatus } from '../../../../../../server/lib/mirror_plugin_status'; -import { PLUGIN } from '../../../../common/constants'; +import { PLUGIN } from '../../../constants'; import { checkLicense } from '../check_license'; export function registerLicenseChecker(__LEGACY) { diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/plugin.ts b/x-pack/plugins/cross_cluster_replication/server/plugin.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/plugin.ts rename to x-pack/plugins/cross_cluster_replication/server/plugin.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/__jest__/auto_follow_pattern.test.js b/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/auto_follow_pattern.test.js similarity index 98% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/__jest__/auto_follow_pattern.test.js rename to x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/auto_follow_pattern.test.js index f3024515c7213..b2cd3b1809e2f 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/__jest__/auto_follow_pattern.test.js +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/auto_follow_pattern.test.js @@ -3,10 +3,10 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { deserializeAutoFollowPattern } from '../../../../../common/services/auto_follow_pattern_serialization'; +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 { getAutoFollowPatternMock, getAutoFollowPatternListMock } from '../../../../fixtures'; import { registerAutoFollowPatternRoutes } from '../auto_follow_pattern'; import { createRouter, callRoute } from './helpers'; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/__jest__/follower_index.test.js b/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/follower_index.test.js similarity index 98% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/__jest__/follower_index.test.js rename to x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/follower_index.test.js index f0139e5bd7011..f4411d7ce0773 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/__jest__/follower_index.test.js +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/follower_index.test.js @@ -3,13 +3,13 @@ * 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'; +} from '../../../../fixtures'; import { callWithRequestFactory } from '../../../lib/call_with_request_factory'; import { isEsErrorFactory } from '../../../lib/is_es_error_factory'; import { registerFollowerIndexRoutes } from '../follower_index'; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/__jest__/helpers.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/helpers.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/__jest__/helpers.ts rename to x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/helpers.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/auto_follow_pattern.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern.ts similarity index 98% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/auto_follow_pattern.ts rename to x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern.ts index d458f1ccb354b..96dbf9fa0da31 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/auto_follow_pattern.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern.ts @@ -13,10 +13,10 @@ import { deserializeListAutoFollowPatterns, serializeAutoFollowPattern, // @ts-ignore -} from '../../../../common/services/auto_follow_pattern_serialization'; +} from '../../../common/services/auto_follow_pattern_serialization'; import { licensePreRoutingFactory } from '../../lib/license_pre_routing_factory'; -import { API_BASE_PATH } from '../../../../common/constants'; +import { API_BASE_PATH } from '../../../common/constants'; import { RouteDependencies } from '../types'; import { mapErrorToKibanaHttpResponse } from '../map_to_kibana_http_error'; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/ccr.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/ccr.ts similarity index 98% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/ccr.ts rename to x-pack/plugins/cross_cluster_replication/server/routes/api/ccr.ts index b08b056ad2c8a..90e1a0a275688 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/ccr.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/ccr.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { API_BASE_PATH } from '../../../../common/constants'; +import { API_BASE_PATH } from '../../../common/constants'; // @ts-ignore import { callWithRequestFactory } from '../../lib/call_with_request_factory'; // @ts-ignore diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/follower_index.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index.ts similarity index 98% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/follower_index.ts rename to x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index.ts index 1d7dacf4a8688..2ddcd5cdf06a6 100644 --- a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/api/follower_index.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index.ts @@ -10,10 +10,10 @@ import { serializeFollowerIndex, serializeAdvancedSettings, // @ts-ignore -} from '../../../../common/services/follower_index_serialization'; -import { API_BASE_PATH } from '../../../../common/constants'; +} from '../../../common/services/follower_index_serialization'; +import { API_BASE_PATH } from '../../../common/constants'; // @ts-ignore -import { removeEmptyFields } from '../../../../common/services/utils'; +import { removeEmptyFields } from '../../../common/services/utils'; // @ts-ignore import { callWithRequestFactory } from '../../lib/call_with_request_factory'; import { licensePreRoutingFactory } from '../../lib/license_pre_routing_factory'; diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/map_to_kibana_http_error.ts b/x-pack/plugins/cross_cluster_replication/server/routes/map_to_kibana_http_error.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/map_to_kibana_http_error.ts rename to x-pack/plugins/cross_cluster_replication/server/routes/map_to_kibana_http_error.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/register_routes.ts b/x-pack/plugins/cross_cluster_replication/server/routes/register_routes.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/register_routes.ts rename to x-pack/plugins/cross_cluster_replication/server/routes/register_routes.ts diff --git a/x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/types.ts b/x-pack/plugins/cross_cluster_replication/server/routes/types.ts similarity index 100% rename from x-pack/legacy/plugins/cross_cluster_replication/server/np_ready/routes/types.ts rename to x-pack/plugins/cross_cluster_replication/server/routes/types.ts From 043496df72980250e6124f60eff9a9c5632ad44c Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Thu, 2 Apr 2020 16:31:31 -0700 Subject: [PATCH 02/20] Migrate server to NP. --- x-pack/index.js | 2 - .../common/constants/base_path.ts | 11 - .../common/constants/index.ts | 41 +- .../common/constants/plugin.ts | 9 - .../common/constants/settings.ts | 18 - .../cross_cluster_replication/index.js | 57 --- .../cross_cluster_replication/kibana.json | 18 + ...sticsearch_ccr.js => elasticsearch_ccr.ts} | 2 +- .../server/config.ts | 16 + .../server/cross_cluster_replication_data.ts | 36 -- .../cross_cluster_replication/server/index.ts | 10 +- .../call_with_request_factory.js | 20 - .../lib/call_with_request_factory/index.js | 7 - .../server/lib/check_license/check_license.js | 70 ---- .../server/lib/check_license/index.js | 7 - .../__tests__/wrap_es_error.test.js | 33 -- .../lib/error_wrappers/wrap_es_error.ts | 65 ---- .../__tests__/is_es_error_factory.js | 44 --- .../server/lib/is_es_error_factory/index.ts | 7 - .../is_es_error_factory.ts | 18 - .../license_pre_routing_factory.test.ts | 64 ---- .../lib/license_pre_routing_factory/index.ts | 7 - .../license_pre_routing_factory.ts | 32 -- .../lib/register_license_checker/index.js | 7 - .../register_license_checker.js | 21 -- .../server/plugin.ts | 130 +++++-- .../api/__jest__/auto_follow_pattern.test.js | 11 +- .../api/__jest__/follower_index.test.js | 11 +- .../server/routes/api/__jest__/helpers.ts | 3 +- .../server/routes/api/auto_follow_pattern.ts | 301 --------------- .../routes/api/auto_follow_pattern/index.ts | 24 ++ .../register_create_route.ts | 82 ++++ .../register_delete_route.ts | 72 ++++ .../register_fetch_route.ts | 46 +++ .../auto_follow_pattern/register_get_route.ts | 56 +++ .../register_pause_route.ts | 65 ++++ .../register_resume_route.ts | 65 ++++ .../register_update_route.ts | 55 +++ .../server/routes/api/ccr.ts | 112 ------ .../api/cross_cluster_replication/index.ts | 14 + .../register_permissions_route.ts | 68 ++++ .../register_stats_route.ts | 42 +++ .../server/routes/api/follower_index.ts | 357 ------------------ .../server/routes/api/follower_index/index.ts | 24 ++ .../follower_index/register_create_route.ts | 58 +++ .../follower_index/register_fetch_route.ts | 65 ++++ .../api/follower_index/register_get_route.ts | 81 ++++ .../follower_index/register_pause_route.ts | 63 ++++ .../follower_index/register_resume_route.ts | 63 ++++ .../follower_index/register_unfollow_route.ts | 94 +++++ .../follower_index/register_update_route.ts | 75 ++++ .../routes/{register_routes.ts => index.ts} | 13 +- .../server/routes/map_to_kibana_http_error.ts | 26 -- .../server/routes/types.ts | 13 - .../services/add_base_path.ts} | 7 +- .../{lib/error_wrappers => services}/index.ts | 3 +- .../server/services/license.ts | 82 ++++ .../cross_cluster_replication/server/types.ts | 27 ++ 58 files changed, 1426 insertions(+), 1404 deletions(-) delete mode 100644 x-pack/plugins/cross_cluster_replication/common/constants/base_path.ts delete mode 100644 x-pack/plugins/cross_cluster_replication/common/constants/plugin.ts delete mode 100644 x-pack/plugins/cross_cluster_replication/common/constants/settings.ts delete mode 100644 x-pack/plugins/cross_cluster_replication/index.js create mode 100644 x-pack/plugins/cross_cluster_replication/kibana.json rename x-pack/plugins/cross_cluster_replication/server/client/{elasticsearch_ccr.js => elasticsearch_ccr.ts} (97%) create mode 100644 x-pack/plugins/cross_cluster_replication/server/config.ts delete mode 100644 x-pack/plugins/cross_cluster_replication/server/cross_cluster_replication_data.ts delete mode 100644 x-pack/plugins/cross_cluster_replication/server/lib/call_with_request_factory/call_with_request_factory.js delete mode 100644 x-pack/plugins/cross_cluster_replication/server/lib/call_with_request_factory/index.js delete mode 100644 x-pack/plugins/cross_cluster_replication/server/lib/check_license/check_license.js delete mode 100644 x-pack/plugins/cross_cluster_replication/server/lib/check_license/index.js delete mode 100644 x-pack/plugins/cross_cluster_replication/server/lib/error_wrappers/__tests__/wrap_es_error.test.js delete mode 100644 x-pack/plugins/cross_cluster_replication/server/lib/error_wrappers/wrap_es_error.ts delete mode 100644 x-pack/plugins/cross_cluster_replication/server/lib/is_es_error_factory/__tests__/is_es_error_factory.js delete mode 100644 x-pack/plugins/cross_cluster_replication/server/lib/is_es_error_factory/index.ts delete mode 100644 x-pack/plugins/cross_cluster_replication/server/lib/is_es_error_factory/is_es_error_factory.ts delete mode 100644 x-pack/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/__jest__/license_pre_routing_factory.test.ts delete mode 100644 x-pack/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/index.ts delete mode 100644 x-pack/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/license_pre_routing_factory.ts delete mode 100644 x-pack/plugins/cross_cluster_replication/server/lib/register_license_checker/index.js delete mode 100644 x-pack/plugins/cross_cluster_replication/server/lib/register_license_checker/register_license_checker.js delete mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/index.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts delete mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/ccr.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/index.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_permissions_route.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts delete mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/index.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts rename x-pack/plugins/cross_cluster_replication/server/routes/{register_routes.ts => index.ts} (52%) delete mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/map_to_kibana_http_error.ts delete mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/types.ts rename x-pack/plugins/cross_cluster_replication/{common/constants/app.ts => server/services/add_base_path.ts} (64%) rename x-pack/plugins/cross_cluster_replication/server/{lib/error_wrappers => services}/index.ts (74%) create mode 100644 x-pack/plugins/cross_cluster_replication/server/services/license.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/types.ts diff --git a/x-pack/index.js b/x-pack/index.js index 7fbd992120ea6..55aa17efa8eab 100644 --- a/x-pack/index.js +++ b/x-pack/index.js @@ -22,7 +22,6 @@ import { taskManager } from './legacy/plugins/task_manager'; import { rollup } from './legacy/plugins/rollup'; import { siem } from './legacy/plugins/siem'; import { remoteClusters } from './legacy/plugins/remote_clusters'; -import { crossClusterReplication } from './legacy/plugins/cross_cluster_replication'; import { upgradeAssistant } from './legacy/plugins/upgrade_assistant'; import { uptime } from './legacy/plugins/uptime'; import { encryptedSavedObjects } from './legacy/plugins/encrypted_saved_objects'; @@ -51,7 +50,6 @@ module.exports = function(kibana) { rollup(kibana), siem(kibana), remoteClusters(kibana), - crossClusterReplication(kibana), upgradeAssistant(kibana), uptime(kibana), encryptedSavedObjects(kibana), diff --git a/x-pack/plugins/cross_cluster_replication/common/constants/base_path.ts b/x-pack/plugins/cross_cluster_replication/common/constants/base_path.ts deleted file mode 100644 index 0a948793e07db..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/common/constants/base_path.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export const BASE_PATH = '/management/elasticsearch/cross_cluster_replication'; -export const BASE_PATH_REMOTE_CLUSTERS = '/management/elasticsearch/remote_clusters'; -export const API_BASE_PATH = '/api/cross_cluster_replication'; -export const API_REMOTE_CLUSTERS_BASE_PATH = '/api/remote_clusters'; -export const API_INDEX_MANAGEMENT_BASE_PATH = '/api/index_management'; diff --git a/x-pack/plugins/cross_cluster_replication/common/constants/index.ts b/x-pack/plugins/cross_cluster_replication/common/constants/index.ts index 300afb4e2d2ff..cad3b5cae83f0 100644 --- a/x-pack/plugins/cross_cluster_replication/common/constants/index.ts +++ b/x-pack/plugins/cross_cluster_replication/common/constants/index.ts @@ -4,7 +4,40 @@ * you may not use this file except in compliance with the Elastic License. */ -export * from './plugin'; -export * from './base_path'; -export * from './app'; -export * from './settings'; +import { i18n } from '@kbn/i18n'; + +import { LicenseType } from '../../../licensing/common/types'; + +const platinumLicense: LicenseType = 'platinum'; + +export const PLUGIN = { + ID: 'cross_cluster_replication', + TITLE: i18n.translate('xpack.crossClusterReplication.appTitle', { + defaultMessage: 'Cross-Cluster Replication', + }), + minimumLicenseType: platinumLicense, +}; + +export const APPS = { + CCR_APP: 'ccr', + REMOTE_CLUSTER_APP: 'remote_cluster', +}; + +export const BASE_PATH = '/management/elasticsearch/cross_cluster_replication'; +export const BASE_PATH_REMOTE_CLUSTERS = '/management/elasticsearch/remote_clusters'; +export const API_BASE_PATH = '/api/cross_cluster_replication'; +export const API_REMOTE_CLUSTERS_BASE_PATH = '/api/remote_clusters'; +export const API_INDEX_MANAGEMENT_BASE_PATH = '/api/index_management'; + +export const FOLLOWER_INDEX_ADVANCED_SETTINGS = { + maxReadRequestOperationCount: 5120, + maxOutstandingReadRequests: 12, + maxReadRequestSize: '32mb', + maxWriteRequestOperationCount: 5120, + maxWriteRequestSize: '9223372036854775807b', + maxOutstandingWriteRequests: 9, + maxWriteBufferCount: 2147483647, + maxWriteBufferSize: '512mb', + maxRetryDelay: '500ms', + readPollTimeout: '1m', +}; diff --git a/x-pack/plugins/cross_cluster_replication/common/constants/plugin.ts b/x-pack/plugins/cross_cluster_replication/common/constants/plugin.ts deleted file mode 100644 index bd5bb50514c01..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/common/constants/plugin.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export const PLUGIN = { - ID: 'cross_cluster_replication', -}; diff --git a/x-pack/plugins/cross_cluster_replication/common/constants/settings.ts b/x-pack/plugins/cross_cluster_replication/common/constants/settings.ts deleted file mode 100644 index 0993a74c8f1fd..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/common/constants/settings.ts +++ /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. - */ - -export const FOLLOWER_INDEX_ADVANCED_SETTINGS = { - maxReadRequestOperationCount: 5120, - maxOutstandingReadRequests: 12, - maxReadRequestSize: '32mb', - maxWriteRequestOperationCount: 5120, - maxWriteRequestSize: '9223372036854775807b', - maxOutstandingWriteRequests: 9, - maxWriteBufferCount: 2147483647, - maxWriteBufferSize: '512mb', - maxRetryDelay: '500ms', - readPollTimeout: '1m', -}; diff --git a/x-pack/plugins/cross_cluster_replication/index.js b/x-pack/plugins/cross_cluster_replication/index.js deleted file mode 100644 index 8c3d07cdaaf0d..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/index.js +++ /dev/null @@ -1,57 +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 { resolve } from 'path'; -import { PLUGIN } from './common/constants'; -import { plugin } from './server'; - -export function crossClusterReplication(kibana) { - return new kibana.Plugin({ - id: PLUGIN.ID, - configPrefix: 'xpack.ccr', - publicDir: resolve(__dirname, 'public'), - require: ['kibana', 'elasticsearch', 'xpack_main', 'remoteClusters', 'index_management'], - uiExports: { - styleSheetPaths: resolve(__dirname, 'public/index.scss'), - managementSections: ['plugins/cross_cluster_replication'], - injectDefaultVars(server) { - const config = server.config(); - return { - ccrUiEnabled: - config.get('xpack.ccr.ui.enabled') && config.get('xpack.remote_clusters.ui.enabled'), - }; - }, - }, - - config(Joi) { - return Joi.object({ - // display menu item - ui: Joi.object({ - enabled: Joi.boolean().default(true), - }).default(), - - // enable plugin - enabled: Joi.boolean().default(true), - }).default(); - }, - isEnabled(config) { - return ( - config.get('xpack.ccr.enabled') && - config.get('xpack.index_management.enabled') && - config.get('xpack.remote_clusters.enabled') - ); - }, - init: function initCcrPlugin(server) { - 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/plugins/cross_cluster_replication/kibana.json b/x-pack/plugins/cross_cluster_replication/kibana.json new file mode 100644 index 0000000000000..21e878ea153cf --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/kibana.json @@ -0,0 +1,18 @@ +{ + "id": "crossClusterReplication", + "version": "kibana", + "server": true, + "ui": true, + "requiredPlugins": [ + "home", + "licensing", + "management", + "remoteClusters", + "indexManagement" + ], + "optionalPlugins": [ + "usageCollection", + "security" + ], + "configPath": ["xpack", "ccr"] +} diff --git a/x-pack/plugins/cross_cluster_replication/server/client/elasticsearch_ccr.js b/x-pack/plugins/cross_cluster_replication/server/client/elasticsearch_ccr.ts similarity index 97% rename from x-pack/plugins/cross_cluster_replication/server/client/elasticsearch_ccr.js rename to x-pack/plugins/cross_cluster_replication/server/client/elasticsearch_ccr.ts index 91527b8eb7cc5..d4de54391286b 100644 --- a/x-pack/plugins/cross_cluster_replication/server/client/elasticsearch_ccr.js +++ b/x-pack/plugins/cross_cluster_replication/server/client/elasticsearch_ccr.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -export const elasticsearchJsPlugin = (Client, config, components) => { +export const elasticsearchJsPlugin = (Client: any, config: any, components: any) => { const ca = components.clientAction.factory; Client.prototype.ccr = components.clientAction.namespaceFactory(); diff --git a/x-pack/plugins/cross_cluster_replication/server/config.ts b/x-pack/plugins/cross_cluster_replication/server/config.ts new file mode 100644 index 0000000000000..17999d37c76b7 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/config.ts @@ -0,0 +1,16 @@ +/* + * 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, TypeOf } from '@kbn/config-schema'; + +export const configSchema = schema.object({ + enabled: schema.boolean({ defaultValue: true }), + ui: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), +}); + +export type CrossClusterReplicationConfig = TypeOf; diff --git a/x-pack/plugins/cross_cluster_replication/server/cross_cluster_replication_data.ts b/x-pack/plugins/cross_cluster_replication/server/cross_cluster_replication_data.ts deleted file mode 100644 index ae15073b979e1..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/cross_cluster_replication_data.ts +++ /dev/null @@ -1,36 +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 { APICaller } from 'src/core/server'; -import { Index } from '../../../../../plugins/index_management/server'; - -export const ccrDataEnricher = async (indicesList: Index[], callWithRequest: APICaller) => { - if (!indicesList?.length) { - return indicesList; - } - const params = { - path: '/_all/_ccr/info', - method: 'GET', - }; - try { - const { follower_indices: followerIndices } = await callWithRequest( - 'transport.request', - params - ); - return indicesList.map(index => { - const isFollowerIndex = !!followerIndices.find( - (followerIndex: { follower_index: string }) => { - return followerIndex.follower_index === index.name; - } - ); - return { - ...index, - isFollowerIndex, - }; - }); - } catch (e) { - return indicesList; - } -}; diff --git a/x-pack/plugins/cross_cluster_replication/server/index.ts b/x-pack/plugins/cross_cluster_replication/server/index.ts index 7a38d024d99a2..483dccfbd506a 100644 --- a/x-pack/plugins/cross_cluster_replication/server/index.ts +++ b/x-pack/plugins/cross_cluster_replication/server/index.ts @@ -4,8 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import { PluginInitializerContext } from 'src/core/server'; +import { PluginInitializerContext, PluginConfigDescriptor } from 'kibana/server'; import { CrossClusterReplicationServerPlugin } from './plugin'; +import { configSchema, CrossClusterReplicationConfig } from './config'; export const plugin = (ctx: PluginInitializerContext) => new CrossClusterReplicationServerPlugin(ctx); + +export const config: PluginConfigDescriptor = { + schema: configSchema, + exposeToBrowser: { + ui: true, + }, +}; diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/call_with_request_factory/call_with_request_factory.js b/x-pack/plugins/cross_cluster_replication/server/lib/call_with_request_factory/call_with_request_factory.js deleted file mode 100644 index 99d72ce1a0e6e..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/lib/call_with_request_factory/call_with_request_factory.js +++ /dev/null @@ -1,20 +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 { elasticsearchJsPlugin } from '../../client/elasticsearch_ccr'; - -const callWithRequest = once(server => { - const config = { plugins: [elasticsearchJsPlugin] }; - const cluster = server.plugins.elasticsearch.createCluster('ccr', config); - return cluster.callWithRequest; -}); - -export const callWithRequestFactory = (server, request) => { - return (...args) => { - return callWithRequest(server)(request, ...args); - }; -}; diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/call_with_request_factory/index.js b/x-pack/plugins/cross_cluster_replication/server/lib/call_with_request_factory/index.js deleted file mode 100644 index 787814d87dff9..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/lib/call_with_request_factory/index.js +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { callWithRequestFactory } from './call_with_request_factory'; diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/check_license/check_license.js b/x-pack/plugins/cross_cluster_replication/server/lib/check_license/check_license.js deleted file mode 100644 index 6cf12896fa472..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/lib/check_license/check_license.js +++ /dev/null @@ -1,70 +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 { i18n } from '@kbn/i18n'; - -export function checkLicense(xpackLicenseInfo) { - const pluginName = 'Cross-Cluster Replication'; - - // If, for some reason, we cannot get the license information - // from Elasticsearch, assume worst case and disable - if (!xpackLicenseInfo || !xpackLicenseInfo.isAvailable()) { - return { - isAvailable: false, - showLinks: true, - enableLinks: false, - message: i18n.translate( - 'xpack.crossClusterReplication.checkLicense.errorUnavailableMessage', - { - defaultMessage: - 'You cannot use {pluginName} because license information is not available at this time.', - values: { pluginName }, - } - ), - }; - } - - const VALID_LICENSE_MODES = ['trial', 'platinum', 'enterprise']; - - const isLicenseModeValid = xpackLicenseInfo.license.isOneOf(VALID_LICENSE_MODES); - const isLicenseActive = xpackLicenseInfo.license.isActive(); - const licenseType = xpackLicenseInfo.license.getType(); - - // License is not valid - if (!isLicenseModeValid) { - return { - isAvailable: false, - isActive: false, - message: i18n.translate( - 'xpack.crossClusterReplication.checkLicense.errorUnsupportedMessage', - { - defaultMessage: - 'Your {licenseType} license does not support {pluginName}. Please upgrade your license.', - values: { licenseType, pluginName }, - } - ), - }; - } - - // License is valid but not active - if (!isLicenseActive) { - return { - isAvailable: true, - isActive: false, - message: i18n.translate('xpack.crossClusterReplication.checkLicense.errorExpiredMessage', { - defaultMessage: - 'You cannot use {pluginName} because your {licenseType} license has expired', - values: { licenseType, pluginName }, - }), - }; - } - - // License is valid and active - return { - isAvailable: true, - isActive: true, - }; -} diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/check_license/index.js b/x-pack/plugins/cross_cluster_replication/server/lib/check_license/index.js deleted file mode 100644 index f2c070fd44b6e..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/lib/check_license/index.js +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { checkLicense } from './check_license'; diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/error_wrappers/__tests__/wrap_es_error.test.js b/x-pack/plugins/cross_cluster_replication/server/lib/error_wrappers/__tests__/wrap_es_error.test.js deleted file mode 100644 index 11a6fd4e1d816..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/lib/error_wrappers/__tests__/wrap_es_error.test.js +++ /dev/null @@ -1,33 +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 { wrapEsError } from '../wrap_es_error'; - -describe('wrap_es_error', () => { - describe('#wrapEsError', () => { - let originalError; - beforeEach(() => { - originalError = new Error('I am an error'); - originalError.statusCode = 404; - originalError.response = '{}'; - }); - - it('should return the correct object', () => { - const wrappedError = wrapEsError(originalError); - - expect(wrappedError.statusCode).to.be(originalError.statusCode); - expect(wrappedError.message).to.be(originalError.message); - }); - - it('should return the correct object with custom message', () => { - const wrappedError = wrapEsError(originalError, { 404: 'No encontrado!' }); - - expect(wrappedError.statusCode).to.be(originalError.statusCode); - expect(wrappedError.message).to.be('No encontrado!'); - }); - }); -}); diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/error_wrappers/wrap_es_error.ts b/x-pack/plugins/cross_cluster_replication/server/lib/error_wrappers/wrap_es_error.ts deleted file mode 100644 index 8afd5f1a018eb..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/lib/error_wrappers/wrap_es_error.ts +++ /dev/null @@ -1,65 +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. - */ - -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 @typescript-eslint/camelcase - if (caused_by) { - return extractCausedByChain(caused_by, accumulator); - } - - return accumulator; -} - -/** - * Wraps an error thrown by the ES JS client into a Boom error response and returns it - * - * @param err Object Error thrown by ES JS client - * @param statusCodeToMessageMap Object Optional map of HTTP status codes => error messages - */ -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 @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]) { - // 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; - - 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 { message, statusCode }; -} diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/is_es_error_factory/__tests__/is_es_error_factory.js b/x-pack/plugins/cross_cluster_replication/server/lib/is_es_error_factory/__tests__/is_es_error_factory.js deleted file mode 100644 index 5f2141cce9395..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/lib/is_es_error_factory/__tests__/is_es_error_factory.js +++ /dev/null @@ -1,44 +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 { isEsErrorFactory } from '../is_es_error_factory'; -import { set } from 'lodash'; - -class MockAbstractEsError {} - -describe('is_es_error_factory', () => { - let mockServer; - let isEsError; - - beforeEach(() => { - const mockEsErrors = { - _Abstract: MockAbstractEsError, - }; - mockServer = {}; - set(mockServer, 'plugins.elasticsearch.getCluster', () => ({ errors: mockEsErrors })); - - isEsError = isEsErrorFactory(mockServer); - }); - - describe('#isEsErrorFactory', () => { - it('should return a function', () => { - expect(isEsError).to.be.a(Function); - }); - - describe('returned function', () => { - it('should return true if passed-in err is a known esError', () => { - const knownEsError = new MockAbstractEsError(); - expect(isEsError(knownEsError)).to.be(true); - }); - - it('should return false if passed-in err is not a known esError', () => { - const unknownEsError = {}; - expect(isEsError(unknownEsError)).to.be(false); - }); - }); - }); -}); diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/is_es_error_factory/index.ts b/x-pack/plugins/cross_cluster_replication/server/lib/is_es_error_factory/index.ts deleted file mode 100644 index 441648a8701e0..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/lib/is_es_error_factory/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { isEsErrorFactory } from './is_es_error_factory'; diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/is_es_error_factory/is_es_error_factory.ts b/x-pack/plugins/cross_cluster_replication/server/lib/is_es_error_factory/is_es_error_factory.ts deleted file mode 100644 index fc6405b8e7513..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/lib/is_es_error_factory/is_es_error_factory.ts +++ /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 { memoize } from 'lodash'; - -const esErrorsFactory = memoize((server: any) => { - return server.plugins.elasticsearch.getCluster('admin').errors; -}); - -export function isEsErrorFactory(server: any) { - const esErrors = esErrorsFactory(server); - return function isEsError(err: any) { - return err instanceof esErrors._Abstract; - }; -} diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/__jest__/license_pre_routing_factory.test.ts b/x-pack/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/__jest__/license_pre_routing_factory.test.ts deleted file mode 100644 index d22505f0e315a..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/__jest__/license_pre_routing_factory.test.ts +++ /dev/null @@ -1,64 +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 { 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/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/index.ts b/x-pack/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/index.ts deleted file mode 100644 index 0743e443955f4..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { licensePreRoutingFactory } from './license_pre_routing_factory'; diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/license_pre_routing_factory.ts b/x-pack/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/license_pre_routing_factory.ts deleted file mode 100644 index 1c9ff9918fe59..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/lib/license_pre_routing_factory/license_pre_routing_factory.ts +++ /dev/null @@ -1,32 +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 { RequestHandler } from 'src/core/server'; -import { PLUGIN } from '../../../../../../legacy/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/plugins/cross_cluster_replication/server/lib/register_license_checker/index.js b/x-pack/plugins/cross_cluster_replication/server/lib/register_license_checker/index.js deleted file mode 100644 index 7b0f97c38d129..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/lib/register_license_checker/index.js +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { registerLicenseChecker } from './register_license_checker'; diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/register_license_checker/register_license_checker.js b/x-pack/plugins/cross_cluster_replication/server/lib/register_license_checker/register_license_checker.js deleted file mode 100644 index bd23c6d4fd562..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/lib/register_license_checker/register_license_checker.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 { mirrorPluginStatus } from '../../../../../../server/lib/mirror_plugin_status'; -import { PLUGIN } from '../../../constants'; -import { checkLicense } from '../check_license'; - -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', () => { - // Register a function that is called whenever the xpack info changes, - // to re-compute the license check results for this plugin - xpackMainPlugin.info.feature(PLUGIN.ID).registerLicenseCheckResultsGenerator(checkLicense); - }); -} diff --git a/x-pack/plugins/cross_cluster_replication/server/plugin.ts b/x-pack/plugins/cross_cluster_replication/server/plugin.ts index 829de10ad0177..83776a191770b 100644 --- a/x-pack/plugins/cross_cluster_replication/server/plugin.ts +++ b/x-pack/plugins/cross_cluster_replication/server/plugin.ts @@ -4,35 +4,123 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Plugin, PluginInitializerContext, CoreSetup } from 'src/core/server'; +declare module 'kibana/server' { + interface RequestHandlerContext { + crossClusterReplication?: CrossClusterReplicationContext; + } +} -import { IndexManagementPluginSetup } from '../../../../../plugins/index_management/server'; +import { Observable } from 'rxjs'; +import { first } from 'rxjs/operators'; +import { i18n } from '@kbn/i18n'; +import { + CoreSetup, + Plugin, + Logger, + PluginInitializerContext, + APICaller, + IScopedClusterClient, +} from 'src/core/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'; +import { Index } from '../../index_management/server'; +import { PLUGIN } from '../common/constants'; +import { Dependencies } from './types'; +import { registerApiRoutes } from './routes'; +import { License } from './services'; +import { elasticsearchJsPlugin } from './client/elasticsearch_ccr'; +import { CrossClusterReplicationConfig } from './config'; +import { isEsError } from './lib/is_es_error'; -interface PluginDependencies { - indexManagement: IndexManagementPluginSetup; - __LEGACY: { - server: any; - ccrUIEnabled: boolean; - }; +interface CrossClusterReplicationContext { + client: IScopedClusterClient; } -export class CrossClusterReplicationServerPlugin implements Plugin { - // @ts-ignore - constructor(private readonly ctx: PluginInitializerContext) {} - setup({ http }: CoreSetup, { indexManagement, __LEGACY }: PluginDependencies) { - registerLicenseChecker(__LEGACY); +const ccrDataEnricher = async (indicesList: Index[], callWithRequest: APICaller) => { + if (!indicesList?.length) { + return indicesList; + } + const params = { + path: '/_all/_ccr/info', + method: 'GET', + }; + try { + const { follower_indices: followerIndices } = await callWithRequest( + 'transport.request', + params + ); + return indicesList.map(index => { + const isFollowerIndex = !!followerIndices.find( + (followerIndex: { follower_index: string }) => { + return followerIndex.follower_index === index.name; + } + ); + return { + ...index, + isFollowerIndex, + }; + }); + } catch (e) { + return indicesList; + } +}; + +export class CrossClusterReplicationServerPlugin implements Plugin { + private readonly config$: Observable; + private readonly license: License; + private readonly logger: Logger; + constructor(initializerContext: PluginInitializerContext) { + this.logger = initializerContext.logger.get(); + this.config$ = initializerContext.config.create(); + this.license = new License(); + } + + async setup( + { http, elasticsearch }: CoreSetup, + { licensing, indexManagement, security }: Dependencies + ): Promise { const router = http.createRouter(); - registerRoutes({ router, __LEGACY }); - if (__LEGACY.ccrUIEnabled && indexManagement && indexManagement.indexDataEnricher) { - indexManagement.indexDataEnricher.add(ccrDataEnricher); + const config = await this.config$.pipe(first()).toPromise(); + + this.license.setup( + { + pluginId: PLUGIN.ID, + minimumLicenseType: PLUGIN.minimumLicenseType, + defaultErrorMessage: i18n.translate('xpack.indexLifecycleMgmt.licenseCheckErrorMessage', { + defaultMessage: 'License check failed', + }), + }, + { + licensing, + logger: this.logger, + } + ); + + // Extend the elasticsearchJs client with additional endpoints. + const esClientConfig = { plugins: [elasticsearchJsPlugin] }; + const ccrEsClient = elasticsearch.createClient('crossClusterReplication', esClientConfig); + http.registerRouteHandlerContext('crossClusterReplication', (ctx, request) => { + return { + client: ccrEsClient.asScoped(request), + }; + }); + + registerApiRoutes({ + router, + license: this.license, + security, + lib: { + isEsError, + }, + }); + + if (config.ui.enabled) { + if (indexManagement.indexDataEnricher) { + indexManagement.indexDataEnricher.add(ccrDataEnricher); + } } } + start() {} + stop() {} } diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/auto_follow_pattern.test.js b/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/auto_follow_pattern.test.js index b2cd3b1809e2f..a11ed77afd7a4 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/auto_follow_pattern.test.js +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/auto_follow_pattern.test.js @@ -4,19 +4,11 @@ * 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 { 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(deserializeAutoFollowPattern(getAutoFollowPatternMock())); let routeRegistry; @@ -82,8 +74,7 @@ describe('[CCR API Routes] Auto Follow Pattern', () => { let routeHandler; beforeAll(() => { - isEsErrorFactory.mockReturnValue(() => false); - callWithRequestFactory.mockReturnValue(getNextResponseFromQueue); + // callWithRequestFactory.mockReturnValue(getNextResponseFromQueue); registerHandlers(); }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/follower_index.test.js b/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/follower_index.test.js index f4411d7ce0773..f08977c08b2f5 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/follower_index.test.js +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/follower_index.test.js @@ -10,17 +10,9 @@ import { 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'; 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({ ...getFollowerIndexInfoMock(), @@ -90,8 +82,7 @@ describe('[CCR API Routes] Follower Index', () => { let routeHandler; beforeAll(() => { - isEsErrorFactory.mockReturnValue(() => false); - callWithRequestFactory.mockReturnValue(getNextResponseFromQueue); + // callWithRequestFactory.mockReturnValue(getNextResponseFromQueue); registerHandlers(); }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/helpers.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/helpers.ts index 555fc0937c0ad..f287e095d31ba 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/helpers.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/helpers.ts @@ -4,8 +4,7 @@ * 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'; +import { RequestHandler, kibanaResponseFactory } from 'src/core/server'; export const callRoute = ( route: RequestHandler, diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern.ts deleted file mode 100644 index 96dbf9fa0da31..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern.ts +++ /dev/null @@ -1,301 +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 { 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/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/index.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/index.ts new file mode 100644 index 0000000000000..4cbdc7703a694 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/index.ts @@ -0,0 +1,24 @@ +/* + * 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 { RouteDependencies } from '../../../types'; +import { registerCreateRoute } from './register_create_route'; +import { registerDeleteRoute } from './register_delete_route'; +import { registerFetchRoute } from './register_fetch_route'; +import { registerGetRoute } from './register_get_route'; +import { registerPauseRoute } from './register_pause_route'; +import { registerResumeRoute } from './register_resume_route'; +import { registerUpdateRoute } from './register_update_route'; + +export function registerAutoFollowPatternRoutes(dependencies: RouteDependencies) { + registerCreateRoute(dependencies); + registerDeleteRoute(dependencies); + registerFetchRoute(dependencies); + registerGetRoute(dependencies); + registerPauseRoute(dependencies); + registerResumeRoute(dependencies); + registerUpdateRoute(dependencies); +} diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts new file mode 100644 index 0000000000000..8142c3ada3cc1 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts @@ -0,0 +1,82 @@ +/* + * 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 { + serializeAutoFollowPattern, + // @ts-ignore +} from '../../../../common/services/auto_follow_pattern_serialization'; +import { addBasePath } from '../../../services'; +import { RouteDependencies } from '../../../types'; + +/** + * Create an auto-follow pattern + */ +export const registerCreateRoute = ({ router, license, lib }: RouteDependencies) => { + const bodySchema = schema.object( + { + id: schema.string(), + }, + { unknowns: 'allow' } + ); + + router.post( + { + path: addBasePath('/auto_follow_patterns'), + validate: { + body: bodySchema, + }, + }, + license.guardApiRoute(async (context, request, response) => { + const { id, ...rest } = request.body as typeof bodySchema.type; + const body = serializeAutoFollowPattern(rest); + + /** + * First let's make sur that an auto-follow pattern with + * the same id does not exist. + */ + try { + await context.crossClusterReplication!.client.callAsCurrentUser('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) { + if (lib.isEsError(err)) { + return response.customError({ + statusCode: err.statusCode, + body: err, + }); + } + // Case: default + return response.internalError({ body: err }); + } + } + + try { + return response.ok({ + body: await context.crossClusterReplication!.client.callAsCurrentUser( + 'ccr.saveAutoFollowPattern', + { id, body } + ), + }); + } catch (err) { + if (lib.isEsError(err)) { + return response.customError({ + statusCode: err.statusCode, + body: err, + }); + } + // Case: default + return response.internalError({ body: err }); + } + }) + ); +}; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts new file mode 100644 index 0000000000000..f3fd7769fee96 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts @@ -0,0 +1,72 @@ +/* + * 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 { + deserializeAutoFollowPattern, + deserializeListAutoFollowPatterns, + serializeAutoFollowPattern, + // @ts-ignore +} from '../../../../common/services/auto_follow_pattern_serialization'; +import { addBasePath } from '../../../services'; +import { RouteDependencies } from '../../../types'; + +/** + * Delete an auto-follow pattern + */ +export const registerDeleteRoute = ({ router, license, lib }: RouteDependencies) => { + const paramsSchema = schema.object({ + id: schema.string(), + }); + + router.delete( + { + path: addBasePath('/auto_follow_patterns/{id}'), + validate: { + params: paramsSchema, + }, + }, + license.guardApiRoute(async (context, request, response) => { + const { id } = request.params as typeof paramsSchema.type; + const ids = id.split(','); + + const itemsDeleted: string[] = []; + const errors: Array<{ id: string; error: any }> = []; + + const formatError = (err: any) => { + if (lib.isEsError(err)) { + return response.customError({ + statusCode: err.statusCode, + body: err, + }); + } + // Case: default + return response.internalError({ body: err }); + }; + + await Promise.all( + ids.map(_id => + context + .crossClusterReplication!.client.callAsCurrentUser('ccr.deleteAutoFollowPattern', { + id: _id, + }) + .then(() => itemsDeleted.push(_id)) + .catch((err: any) => { + errors.push({ id: _id, error: formatError(err) }); + }) + ) + ); + + return response.ok({ + body: { + itemsDeleted, + errors, + }, + }); + }) + ); +}; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts new file mode 100644 index 0000000000000..bfc3ae8c2d8bc --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts @@ -0,0 +1,46 @@ +/* + * 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. + */ + +// @ts-ignore +import { + deserializeListAutoFollowPatterns, + // @ts-ignore +} from '../../../../common/services/auto_follow_pattern_serialization'; +import { addBasePath } from '../../../services'; +import { RouteDependencies } from '../../../types'; + +/** + * Get a list of all auto-follow patterns + */ +export const registerFetchRoute = ({ router, license, lib }: RouteDependencies) => { + router.get( + { + path: addBasePath('/auto_follow_patterns'), + validate: false, + }, + license.guardApiRoute(async (context, request, response) => { + try { + const result = await context.crossClusterReplication!.client.callAsCurrentUser( + 'ccr.autoFollowPatterns' + ); + return response.ok({ + body: { + patterns: deserializeListAutoFollowPatterns(result.patterns), + }, + }); + } catch (err) { + if (lib.isEsError(err)) { + return response.customError({ + statusCode: err.statusCode, + body: err, + }); + } + // Case: default + return response.internalError({ body: err }); + } + }) + ); +}; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts new file mode 100644 index 0000000000000..9175626167558 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts @@ -0,0 +1,56 @@ +/* + * 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 { + deserializeAutoFollowPattern, + // @ts-ignore +} from '../../../../common/services/auto_follow_pattern_serialization'; +import { addBasePath } from '../../../services'; +import { RouteDependencies } from '../../../types'; + +/** + * Get a single auto-follow pattern + */ +export const registerGetRoute = ({ router, license, lib }: RouteDependencies) => { + const paramsSchema = schema.object({ + id: schema.string(), + }); + + router.get( + { + path: addBasePath('/auto_follow_patterns/{id}'), + validate: { + params: paramsSchema, + }, + }, + license.guardApiRoute(async (context, request, response) => { + const { id } = request.params as typeof paramsSchema.type; + + try { + const result = await context.crossClusterReplication!.client.callAsCurrentUser( + 'ccr.autoFollowPattern', + { id } + ); + const autoFollowPattern = result.patterns[0]; + + return response.ok({ + body: deserializeAutoFollowPattern(autoFollowPattern), + }); + } catch (err) { + if (lib.isEsError(err)) { + return response.customError({ + statusCode: err.statusCode, + body: err, + }); + } + // Case: default + return response.internalError({ body: err }); + } + }) + ); +}; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts new file mode 100644 index 0000000000000..998895ab0b383 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts @@ -0,0 +1,65 @@ +/* + * 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 { addBasePath } from '../../../services'; +import { RouteDependencies } from '../../../types'; + +/** + * Pause auto-follow pattern(s) + */ +export const registerPauseRoute = ({ router, license, lib }: RouteDependencies) => { + const paramsSchema = schema.object({ + id: schema.string(), + }); + + router.post( + { + path: addBasePath('/auto_follow_patterns/{id}/pause'), + validate: { + params: paramsSchema, + }, + }, + license.guardApiRoute(async (context, request, response) => { + const { id } = request.params as typeof paramsSchema.type; + const ids = id.split(','); + + const itemsPaused: string[] = []; + const errors: Array<{ id: string; error: any }> = []; + + const formatError = (err: any) => { + if (lib.isEsError(err)) { + return response.customError({ + statusCode: err.statusCode, + body: err, + }); + } + // Case: default + return response.internalError({ body: err }); + }; + + await Promise.all( + ids.map(_id => + context + .crossClusterReplication!.client.callAsCurrentUser('ccr.pauseAutoFollowPattern', { + id: _id, + }) + .then(() => itemsPaused.push(_id)) + .catch(err => { + errors.push({ id: _id, error: formatError(err) }); + }) + ) + ); + + return response.ok({ + body: { + itemsPaused, + errors, + }, + }); + }) + ); +}; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts new file mode 100644 index 0000000000000..9f3e534ce0a2a --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts @@ -0,0 +1,65 @@ +/* + * 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 { addBasePath } from '../../../services'; +import { RouteDependencies } from '../../../types'; + +/** + * Resume auto-follow pattern(s) + */ +export const registerResumeRoute = ({ router, license, lib }: RouteDependencies) => { + const paramsSchema = schema.object({ + id: schema.string(), + }); + + router.post( + { + path: addBasePath('/auto_follow_patterns/{id}/resume'), + validate: { + params: paramsSchema, + }, + }, + license.guardApiRoute(async (context, request, response) => { + const { id } = request.params as typeof paramsSchema.type; + const ids = id.split(','); + + const itemsResumed: string[] = []; + const errors: Array<{ id: string; error: any }> = []; + + const formatError = (err: any) => { + if (lib.isEsError(err)) { + return response.customError({ + statusCode: err.statusCode, + body: err, + }); + } + // Case: default + return response.internalError({ body: err }); + }; + + await Promise.all( + ids.map((_id: string) => + context + .crossClusterReplication!.client.callAsCurrentUser('ccr.resumeAutoFollowPattern', { + id: _id, + }) + .then(() => itemsResumed.push(_id)) + .catch(err => { + errors.push({ id: _id, error: formatError(err) }); + }) + ) + ); + + return response.ok({ + body: { + itemsResumed, + errors, + }, + }); + }) + ); +}; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts new file mode 100644 index 0000000000000..4ab9b1640f511 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts @@ -0,0 +1,55 @@ +/* + * 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 { + serializeAutoFollowPattern, + // @ts-ignore +} from '../../../../common/services/auto_follow_pattern_serialization'; +import { addBasePath } from '../../../services'; +import { RouteDependencies } from '../../../types'; + +/** + * Update an auto-follow pattern + */ +export const registerUpdateRoute = ({ router, license, lib }: RouteDependencies) => { + const paramsSchema = schema.object({ + id: schema.string(), + }); + + router.put( + { + path: addBasePath('/auto_follow_patterns/{id}'), + validate: { + params: paramsSchema, + body: schema.object({}, { unknowns: 'allow' }), + }, + }, + license.guardApiRoute(async (context, request, response) => { + const { id } = request.params as typeof paramsSchema.type; + const body = serializeAutoFollowPattern(request.body); + + try { + return response.ok({ + body: await context.crossClusterReplication!.client.callAsCurrentUser( + 'ccr.saveAutoFollowPattern', + { id, body } + ), + }); + } catch (err) { + if (lib.isEsError(err)) { + return response.customError({ + statusCode: err.statusCode, + body: err, + }); + } + // Case: default + return response.internalError({ body: err }); + } + }) + ); +}; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/ccr.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/ccr.ts deleted file mode 100644 index 90e1a0a275688..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/ccr.ts +++ /dev/null @@ -1,112 +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 { 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/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/index.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/index.ts new file mode 100644 index 0000000000000..45c5729535e58 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/index.ts @@ -0,0 +1,14 @@ +/* + * 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 { RouteDependencies } from '../../../types'; +import { registerPermissionsRoute } from './register_permissions_route'; +import { registerStatsRoute } from './register_stats_route'; + +export function registerCrossClusterReplicationRoutes(dependencies: RouteDependencies) { + registerPermissionsRoute(dependencies); + registerStatsRoute(dependencies); +} diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_permissions_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_permissions_route.ts new file mode 100644 index 0000000000000..5c3dabc8784e8 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_permissions_route.ts @@ -0,0 +1,68 @@ +/* + * 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 { addBasePath } from '../../../services'; +import { RouteDependencies } from '../../../types'; + +/** + * Returns whether the user has CCR permissions + */ +export const registerPermissionsRoute = ({ router, license, lib, security }: RouteDependencies) => { + router.get( + { + path: addBasePath('/permissions'), + validate: false, + }, + license.guardApiRoute(async (context, request, response) => { + if (!security) { + // 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: [], + }, + }); + } + + try { + const { + has_all_requested: hasPermission, + cluster, + } = await context.crossClusterReplication!.client.callAsCurrentUser('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) { + if (lib.isEsError(err)) { + return response.customError({ + statusCode: err.statusCode, + body: err, + }); + } + // Case: default + return response.internalError({ body: err }); + } + }) + ); +}; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts new file mode 100644 index 0000000000000..0d9f4c0c9a451 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts @@ -0,0 +1,42 @@ +/* + * 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 { addBasePath } from '../../../services'; +// @ts-ignore +import { deserializeAutoFollowStats } from '../../../lib/ccr_stats_serialization'; +import { RouteDependencies } from '../../../types'; + +/** + * Returns Auto-follow stats + */ +export const registerStatsRoute = ({ router, license, lib }: RouteDependencies) => { + router.get( + { + path: addBasePath('/stats/auto_follow'), + validate: false, + }, + license.guardApiRoute(async (context, request, response) => { + try { + const { + auto_follow_stats: autoFollowStats, + } = await context.crossClusterReplication!.client.callAsCurrentUser('ccr.stats'); + + return response.ok({ + body: deserializeAutoFollowStats(autoFollowStats), + }); + } catch (err) { + if (lib.isEsError(err)) { + return response.customError({ + statusCode: err.statusCode, + body: err, + }); + } + // Case: default + return response.internalError({ body: err }); + } + }) + ); +}; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index.ts deleted file mode 100644 index 2ddcd5cdf06a6..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index.ts +++ /dev/null @@ -1,357 +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 { 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() }), - body: schema.object({ - maxReadRequestOperationCount: schema.maybe(schema.number()), - maxOutstandingReadRequests: schema.maybe(schema.number()), - maxReadRequestSize: schema.maybe(schema.string()), // byte value - maxWriteRequestOperationCount: schema.maybe(schema.number()), - maxWriteRequestSize: schema.maybe(schema.string()), // byte value - maxOutstandingWriteRequests: schema.maybe(schema.number()), - maxWriteBufferCount: schema.maybe(schema.number()), - maxWriteBufferSize: schema.maybe(schema.string()), // byte value - maxRetryDelay: schema.maybe(schema.string()), // time value - readPollTimeout: schema.maybe(schema.string()), // time value - }), - }, - }, - 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/plugins/cross_cluster_replication/server/routes/api/follower_index/index.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/index.ts new file mode 100644 index 0000000000000..f5d8c7a4f5bda --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/index.ts @@ -0,0 +1,24 @@ +/* + * 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 { RouteDependencies } from '../../../types'; +import { registerCreateRoute } from './register_create_route'; +import { registerFetchRoute } from './register_fetch_route'; +import { registerGetRoute } from './register_get_route'; +import { registerPauseRoute } from './register_pause_route'; +import { registerResumeRoute } from './register_resume_route'; +import { registerUnfollowRoute } from './register_unfollow_route'; +import { registerUpdateRoute } from './register_update_route'; + +export function registerFollowerIndexRoutes(dependencies: RouteDependencies) { + registerCreateRoute(dependencies); + registerFetchRoute(dependencies); + registerGetRoute(dependencies); + registerPauseRoute(dependencies); + registerResumeRoute(dependencies); + registerUnfollowRoute(dependencies); + registerUpdateRoute(dependencies); +} diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts new file mode 100644 index 0000000000000..edecaf74d8192 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts @@ -0,0 +1,58 @@ +/* + * 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 { + serializeFollowerIndex, + // @ts-ignore +} from '../../../../common/services/follower_index_serialization'; +import { addBasePath } from '../../../services'; +// @ts-ignore +import { removeEmptyFields } from '../../../../common/services/utils'; +import { RouteDependencies } from '../../../types'; + +/** + * Create a follower index + */ +export const registerCreateRoute = ({ router, license, lib }: RouteDependencies) => { + const bodySchema = schema.object( + { + name: schema.string(), + }, + { unknowns: 'allow' } + ); + + router.post( + { + path: addBasePath('/follower_indices'), + validate: { + body: bodySchema, + }, + }, + license.guardApiRoute(async (context, request, response) => { + const { name, ...rest } = request.body as typeof bodySchema.type; + const body = removeEmptyFields(serializeFollowerIndex(rest)); + + try { + return response.ok({ + body: await context.crossClusterReplication!.client.callAsCurrentUser( + 'ccr.saveFollowerIndex', + { name, body } + ), + }); + } catch (err) { + if (lib.isEsError(err)) { + return response.customError({ + statusCode: err.statusCode, + body: err, + }); + } + // Case: default + return response.internalError({ body: err }); + } + }) + ); +}; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts new file mode 100644 index 0000000000000..da68bc15a9c90 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts @@ -0,0 +1,65 @@ +/* + * 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 { + deserializeListFollowerIndices, + // @ts-ignore +} from '../../../../common/services/follower_index_serialization'; +import { addBasePath } from '../../../services'; +// @ts-ignore +import { RouteDependencies } from '../../../types'; + +/** + * Returns a list of all follower indices + */ +export const registerFetchRoute = ({ router, license, lib }: RouteDependencies) => { + router.get( + { + path: addBasePath('/follower_indices'), + validate: false, + }, + license.guardApiRoute(async (context, request, response) => { + try { + const { + follower_indices: followerIndices, + } = await context.crossClusterReplication!.client.callAsCurrentUser('ccr.info', { + id: '_all', + }); + + const { + follow_stats: { indices: followerIndicesStats }, + } = await context.crossClusterReplication!.client.callAsCurrentUser('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) { + if (lib.isEsError(err)) { + return response.customError({ + statusCode: err.statusCode, + body: err, + }); + } + // Case: default + return response.internalError({ body: err }); + } + }) + ); +}; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts new file mode 100644 index 0000000000000..fe2bea7351c87 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts @@ -0,0 +1,81 @@ +/* + * 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, + // @ts-ignore +} from '../../../../common/services/follower_index_serialization'; +import { addBasePath } from '../../../services'; +// @ts-ignore +import { RouteDependencies } from '../../../types'; + +/** + * Returns a single follower index pattern + */ +export const registerGetRoute = ({ router, license, lib }: RouteDependencies) => { + const paramsSchema = schema.object({ + id: schema.string(), + }); + + router.get( + { + path: addBasePath('/follower_indices/{id}'), + validate: { + params: paramsSchema, + }, + }, + license.guardApiRoute(async (context, request, response) => { + const { id } = request.params as typeof paramsSchema.type; + + try { + const { + follower_indices: followerIndices, + } = await context.crossClusterReplication!.client.callAsCurrentUser('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 context.crossClusterReplication!.client.callAsCurrentUser( + 'ccr.followerIndexStats', + { id } + ); + + return response.ok({ + body: deserializeFollowerIndex({ + ...followerIndexInfo, + ...(followerIndicesStats ? followerIndicesStats[0] : {}), + }), + }); + } + } catch (err) { + if (lib.isEsError(err)) { + return response.customError({ + statusCode: err.statusCode, + body: err, + }); + } + // Case: default + return response.internalError({ body: err }); + } + }) + ); +}; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts new file mode 100644 index 0000000000000..6204c1856e489 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts @@ -0,0 +1,63 @@ +/* + * 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 { addBasePath } from '../../../services'; +import { RouteDependencies } from '../../../types'; + +/** + * Pauses a follower index + */ +export const registerPauseRoute = ({ router, license, lib }: RouteDependencies) => { + const paramsSchema = schema.object({ id: schema.string() }); + + router.put( + { + path: addBasePath('/follower_indices/{id}/pause'), + validate: { + params: paramsSchema, + }, + }, + license.guardApiRoute(async (context, request, response) => { + const { id } = request.params as typeof paramsSchema.type; + const ids = id.split(','); + + const itemsPaused: string[] = []; + const errors: Array<{ id: string; error: any }> = []; + + const formatError = (err: any) => { + if (lib.isEsError(err)) { + return response.customError({ + statusCode: err.statusCode, + body: err, + }); + } + // Case: default + return response.internalError({ body: err }); + }; + + await Promise.all( + ids.map((_id: string) => + context + .crossClusterReplication!.client.callAsCurrentUser('ccr.pauseFollowerIndex', { + id: _id, + }) + .then(() => itemsPaused.push(_id)) + .catch(err => { + errors.push({ id: _id, error: formatError(err) }); + }) + ) + ); + + return response.ok({ + body: { + itemsPaused, + errors, + }, + }); + }) + ); +}; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts new file mode 100644 index 0000000000000..6637ecded5864 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts @@ -0,0 +1,63 @@ +/* + * 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 { addBasePath } from '../../../services'; +import { RouteDependencies } from '../../../types'; + +/** + * Resumes a follower index + */ +export const registerResumeRoute = ({ router, license, lib }: RouteDependencies) => { + const paramsSchema = schema.object({ id: schema.string() }); + + router.put( + { + path: addBasePath('/follower_indices/{id}/resume'), + validate: { + params: paramsSchema, + }, + }, + license.guardApiRoute(async (context, request, response) => { + const { id } = request.params as typeof paramsSchema.type; + const ids = id.split(','); + + const itemsResumed: string[] = []; + const errors: Array<{ id: string; error: any }> = []; + + const formatError = (err: any) => { + if (lib.isEsError(err)) { + return response.customError({ + statusCode: err.statusCode, + body: err, + }); + } + // Case: default + return response.internalError({ body: err }); + }; + + await Promise.all( + ids.map((_id: string) => + context + .crossClusterReplication!.client.callAsCurrentUser('ccr.resumeFollowerIndex', { + id: _id, + }) + .then(() => itemsResumed.push(_id)) + .catch(err => { + errors.push({ id: _id, error: formatError(err) }); + }) + ) + ); + + return response.ok({ + body: { + itemsResumed, + errors, + }, + }); + }) + ); +}; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts new file mode 100644 index 0000000000000..778839fc940f0 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts @@ -0,0 +1,94 @@ +/* + * 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 { addBasePath } from '../../../services'; +import { RouteDependencies } from '../../../types'; + +/** + * Unfollow follower index's leader index + */ +export const registerUnfollowRoute = ({ router, license, lib }: RouteDependencies) => { + const paramsSchema = schema.object({ id: schema.string() }); + + router.put( + { + path: addBasePath('/follower_indices/{id}/unfollow'), + validate: { + params: paramsSchema, + }, + }, + license.guardApiRoute(async (context, request, response) => { + const { id } = request.params as typeof paramsSchema.type; + const ids = id.split(','); + + const itemsUnfollowed: string[] = []; + const itemsNotOpen: string[] = []; + const errors: Array<{ id: string; error: any }> = []; + + const formatError = (err: any) => { + if (lib.isEsError(err)) { + return response.customError({ + statusCode: err.statusCode, + body: err, + }); + } + // Case: default + return response.internalError({ body: err }); + }; + + await Promise.all( + ids.map(async (_id: string) => { + try { + // Try to pause follower, let it fail silently since it may already be paused + try { + await context.crossClusterReplication!.client.callAsCurrentUser( + 'ccr.pauseFollowerIndex', + { id: _id } + ); + } catch (e) { + // Swallow errors + } + + // Close index + await context.crossClusterReplication!.client.callAsCurrentUser('indices.close', { + index: _id, + }); + + // Unfollow leader + await context.crossClusterReplication!.client.callAsCurrentUser( + '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 context.crossClusterReplication!.client.callAsCurrentUser('indices.open', { + index: _id, + }); + } catch (e) { + itemsNotOpen.push(_id); + } + + // Push success + itemsUnfollowed.push(_id); + } catch (err) { + errors.push({ id: _id, error: formatError(err) }); + } + }) + ); + + return response.ok({ + body: { + itemsUnfollowed, + itemsNotOpen, + errors, + }, + }); + }) + ); +}; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts new file mode 100644 index 0000000000000..241e515e184b7 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts @@ -0,0 +1,75 @@ +/* + * 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 { + serializeAdvancedSettings, + // @ts-ignore +} from '../../../../common/services/follower_index_serialization'; +// @ts-ignore +import { removeEmptyFields } from '../../../../common/services/utils'; +import { addBasePath } from '../../../services'; +import { RouteDependencies } from '../../../types'; + +/** + * Update a follower index + */ +export const registerUpdateRoute = ({ router, license, lib }: RouteDependencies) => { + const paramsSchema = schema.object({ id: schema.string() }); + + router.put( + { + path: addBasePath('/follower_indices/{id}'), + validate: { + params: paramsSchema, + }, + }, + license.guardApiRoute(async (context, request, response) => { + const { id } = request.params as typeof paramsSchema.type; + + // We need to first pause the follower and then resume it passing the advanced settings + try { + const { + follower_indices: followerIndices, + } = await context.crossClusterReplication!.client.callAsCurrentUser('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 context.crossClusterReplication!.client.callAsCurrentUser( + 'ccr.pauseFollowerIndex', + { + id, + } + ); + } + + // Resume follower + const body = removeEmptyFields(serializeAdvancedSettings(request.body)); + return response.ok({ + body: await context.crossClusterReplication!.client.callAsCurrentUser( + 'ccr.resumeFollowerIndex', + { id, body } + ), + }); + } catch (err) { + if (lib.isEsError(err)) { + return response.customError({ + statusCode: err.statusCode, + body: err, + }); + } + // Case: default + return response.internalError({ body: err }); + } + }) + ); +}; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/register_routes.ts b/x-pack/plugins/cross_cluster_replication/server/routes/index.ts similarity index 52% rename from x-pack/plugins/cross_cluster_replication/server/routes/register_routes.ts rename to x-pack/plugins/cross_cluster_replication/server/routes/index.ts index 7e59417550691..84abfb369e002 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/register_routes.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/index.ts @@ -4,13 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ +import { RouteDependencies } from '../types'; + import { registerAutoFollowPatternRoutes } from './api/auto_follow_pattern'; import { registerFollowerIndexRoutes } from './api/follower_index'; -import { registerCcrRoutes } from './api/ccr'; -import { RouteDependencies } from './types'; +import { registerCrossClusterReplicationRoutes } from './api/cross_cluster_replication'; -export function registerRoutes(deps: RouteDependencies) { - registerAutoFollowPatternRoutes(deps); - registerFollowerIndexRoutes(deps); - registerCcrRoutes(deps); +export function registerApiRoutes(dependencies: RouteDependencies) { + registerAutoFollowPatternRoutes(dependencies); + registerFollowerIndexRoutes(dependencies); + registerCrossClusterReplicationRoutes(dependencies); } diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/map_to_kibana_http_error.ts b/x-pack/plugins/cross_cluster_replication/server/routes/map_to_kibana_http_error.ts deleted file mode 100644 index 6a81bd26dc47d..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/routes/map_to_kibana_http_error.ts +++ /dev/null @@ -1,26 +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 { 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/plugins/cross_cluster_replication/server/routes/types.ts b/x-pack/plugins/cross_cluster_replication/server/routes/types.ts deleted file mode 100644 index 7f57c20c536e0..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/routes/types.ts +++ /dev/null @@ -1,13 +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 { IRouter } from 'src/core/server'; - -export interface RouteDependencies { - router: IRouter; - __LEGACY: { - server: any; - }; -} diff --git a/x-pack/plugins/cross_cluster_replication/common/constants/app.ts b/x-pack/plugins/cross_cluster_replication/server/services/add_base_path.ts similarity index 64% rename from x-pack/plugins/cross_cluster_replication/common/constants/app.ts rename to x-pack/plugins/cross_cluster_replication/server/services/add_base_path.ts index 4ce0a2f5644f3..3f3dd131df7c7 100644 --- a/x-pack/plugins/cross_cluster_replication/common/constants/app.ts +++ b/x-pack/plugins/cross_cluster_replication/server/services/add_base_path.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -export const APPS = { - CCR_APP: 'ccr', - REMOTE_CLUSTER_APP: 'remote_cluster', -}; +import { API_BASE_PATH } from '../../common/constants'; + +export const addBasePath = (uri: string): string => `${API_BASE_PATH}${uri}`; diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/error_wrappers/index.ts b/x-pack/plugins/cross_cluster_replication/server/services/index.ts similarity index 74% rename from x-pack/plugins/cross_cluster_replication/server/lib/error_wrappers/index.ts rename to x-pack/plugins/cross_cluster_replication/server/services/index.ts index 3756b0c74fb10..d7b544b290c39 100644 --- a/x-pack/plugins/cross_cluster_replication/server/lib/error_wrappers/index.ts +++ b/x-pack/plugins/cross_cluster_replication/server/services/index.ts @@ -4,4 +4,5 @@ * you may not use this file except in compliance with the Elastic License. */ -export { wrapEsError } from './wrap_es_error'; +export { License } from './license'; +export { addBasePath } from './add_base_path'; diff --git a/x-pack/plugins/cross_cluster_replication/server/services/license.ts b/x-pack/plugins/cross_cluster_replication/server/services/license.ts new file mode 100644 index 0000000000000..31d3654c51e3e --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/services/license.ts @@ -0,0 +1,82 @@ +/* + * 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 { Logger } from 'src/core/server'; +import { + KibanaRequest, + KibanaResponseFactory, + RequestHandler, + RequestHandlerContext, +} from 'kibana/server'; + +import { LicensingPluginSetup } from '../../../licensing/server'; +import { LicenseType } from '../../../licensing/common/types'; + +export interface LicenseStatus { + isValid: boolean; + message?: string; +} + +interface SetupSettings { + pluginId: string; + minimumLicenseType: LicenseType; + defaultErrorMessage: string; +} + +export class License { + private licenseStatus: LicenseStatus = { + isValid: false, + message: 'Invalid License', + }; + + setup( + { pluginId, minimumLicenseType, defaultErrorMessage }: SetupSettings, + { licensing, logger }: { licensing: LicensingPluginSetup; logger: Logger } + ) { + licensing.license$.subscribe(license => { + const { state, message } = license.check(pluginId, minimumLicenseType); + const hasRequiredLicense = state === 'valid'; + + if (hasRequiredLicense) { + this.licenseStatus = { isValid: true }; + } else { + this.licenseStatus = { + isValid: false, + message: message || defaultErrorMessage, + }; + if (message) { + logger.info(message); + } + } + }); + } + + guardApiRoute(handler: RequestHandler) { + const license = this; + + return function licenseCheck( + ctx: RequestHandlerContext, + request: KibanaRequest, + response: KibanaResponseFactory + ) { + const licenseStatus = license.getStatus(); + + if (!licenseStatus.isValid) { + return response.customError({ + body: { + message: licenseStatus.message || '', + }, + statusCode: 403, + }); + } + + return handler(ctx, request, response); + }; + } + + getStatus() { + return this.licenseStatus; + } +} diff --git a/x-pack/plugins/cross_cluster_replication/server/types.ts b/x-pack/plugins/cross_cluster_replication/server/types.ts new file mode 100644 index 0000000000000..871b44fe99180 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/types.ts @@ -0,0 +1,27 @@ +/* + * 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'; +import { LicensingPluginSetup } from '../../licensing/server'; +import { IndexManagementPluginSetup } from '../../index_management/server'; +import { SecurityPluginSetup } from '../../security/server'; +import { License } from './services'; +import { isEsError } from './lib/is_es_error'; + +export interface Dependencies { + licensing: LicensingPluginSetup; + indexManagement: IndexManagementPluginSetup; + security?: SecurityPluginSetup; +} + +export interface RouteDependencies { + router: IRouter; + license: License; + security?: SecurityPluginSetup; + lib: { + isEsError: typeof isEsError; + }; +} From ce4693b1a009665b9416ed2f8d82fca58536c6f6 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Wed, 15 Apr 2020 14:00:49 -0700 Subject: [PATCH 03/20] Update plugin paths in sasslint and eslint config files. --- .eslintrc.js | 2 +- .sass-lint.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index a2b8ae7622d0b..b3a1274d1cbeb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -96,7 +96,7 @@ module.exports = { }, }, { - files: ['x-pack/legacy/plugins/cross_cluster_replication/**/*.{js,ts,tsx}'], + files: ['x-pack/plugins/cross_cluster_replication/**/*.{js,ts,tsx}'], rules: { 'jsx-a11y/click-events-have-key-events': 'off', }, diff --git a/.sass-lint.yml b/.sass-lint.yml index 5c2c88a1dad5d..89735342a2d6f 100644 --- a/.sass-lint.yml +++ b/.sass-lint.yml @@ -9,6 +9,7 @@ files: - 'x-pack/legacy/plugins/canvas/**/*.s+(a|c)ss' - 'x-pack/plugins/triggers_actions_ui/**/*.s+(a|c)ss' - 'x-pack/plugins/lens/**/*.s+(a|c)ss' + - 'x-pack/plugins/cross_cluster_replication/**/*.s+(a|c)ss' - 'x-pack/legacy/plugins/maps/**/*.s+(a|c)ss' - 'x-pack/plugins/maps/**/*.s+(a|c)ss' ignore: From ed6673fe398999111697a7856862c3728bdb4ddc Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Tue, 7 Apr 2020 15:53:16 -0700 Subject: [PATCH 04/20] Convert common/services and server/lib to TypeScript. Update Jest tests. - Remove deserializeAutoFollowPattern behavior that returned an empty object if the pattern was undefined. --- .../follower_index_serialization.test.js.snap | 128 ------------ .../follower_index_serialization.test.ts.snap | 128 ++++++++++++ .../auto_follow_pattern_serialization.js | 41 ---- ...auto_follow_pattern_serialization.test.ts} | 16 +- .../auto_follow_pattern_serialization.ts | 38 ++++ ...s => follower_index_serialization.test.ts} | 122 ++++++++---- ...ion.js => follower_index_serialization.ts} | 27 ++- .../services/{utils.test.js => utils.test.ts} | 0 .../common/services/{utils.js => utils.ts} | 11 +- .../cross_cluster_replication/common/types.ts | 184 ++++++++++++++++++ .../public/app/services/breadcrumbs.ts | 4 +- .../public/extend_index_management.ts | 3 +- .../public/plugin.ts | 3 +- ...p => ccr_stats_serialization.test.ts.snap} | 0 ...est.js => ccr_stats_serialization.test.ts} | 0 ...lization.js => ccr_stats_serialization.ts} | 17 +- .../register_create_route.ts | 9 +- .../register_delete_route.ts | 8 +- .../register_fetch_route.ts | 6 +- .../auto_follow_pattern/register_get_route.ts | 7 +- .../register_update_route.ts | 9 +- .../register_stats_route.ts | 1 - .../follower_index/register_create_route.ts | 9 +- .../follower_index/register_fetch_route.ts | 6 +- .../api/follower_index/register_get_route.ts | 6 +- .../follower_index/register_update_route.ts | 11 +- 26 files changed, 505 insertions(+), 289 deletions(-) delete mode 100644 x-pack/plugins/cross_cluster_replication/common/services/__snapshots__/follower_index_serialization.test.js.snap create mode 100644 x-pack/plugins/cross_cluster_replication/common/services/__snapshots__/follower_index_serialization.test.ts.snap delete mode 100644 x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.js rename x-pack/plugins/cross_cluster_replication/common/services/{auto_follow_pattern_serialization.test.js => auto_follow_pattern_serialization.test.ts} (85%) create mode 100644 x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.ts rename x-pack/plugins/cross_cluster_replication/common/services/{follower_index_serialization.test.js => follower_index_serialization.test.ts} (55%) rename x-pack/plugins/cross_cluster_replication/common/services/{follower_index_serialization.js => follower_index_serialization.ts} (87%) rename x-pack/plugins/cross_cluster_replication/common/services/{utils.test.js => utils.test.ts} (100%) rename x-pack/plugins/cross_cluster_replication/common/services/{utils.js => utils.ts} (62%) create mode 100644 x-pack/plugins/cross_cluster_replication/common/types.ts rename x-pack/plugins/cross_cluster_replication/server/lib/__snapshots__/{ccr_stats_serialization.test.js.snap => ccr_stats_serialization.test.ts.snap} (100%) rename x-pack/plugins/cross_cluster_replication/server/lib/{ccr_stats_serialization.test.js => ccr_stats_serialization.test.ts} (100%) rename x-pack/plugins/cross_cluster_replication/server/lib/{ccr_stats_serialization.js => ccr_stats_serialization.ts} (79%) diff --git a/x-pack/plugins/cross_cluster_replication/common/services/__snapshots__/follower_index_serialization.test.js.snap b/x-pack/plugins/cross_cluster_replication/common/services/__snapshots__/follower_index_serialization.test.js.snap deleted file mode 100644 index d001459e8234d..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/common/services/__snapshots__/follower_index_serialization.test.js.snap +++ /dev/null @@ -1,128 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`[CCR] follower index serialization deserializeFollowerIndex() deserializes Elasticsearch follower index object 1`] = ` -Object { - "leaderIndex": undefined, - "maxOutstandingReadRequests": undefined, - "maxOutstandingWriteRequests": undefined, - "maxReadRequestOperationCount": undefined, - "maxReadRequestSize": undefined, - "maxRetryDelay": undefined, - "maxWriteBufferCount": undefined, - "maxWriteBufferSize": undefined, - "maxWriteRequestOperationCount": undefined, - "maxWriteRequestSize": undefined, - "name": undefined, - "readPollTimeout": undefined, - "remoteCluster": undefined, - "shards": Array [ - Object { - "bytesReadCount": undefined, - "failedReadRequestsCount": undefined, - "failedWriteRequestsCount": undefined, - "followerGlobalCheckpoint": undefined, - "followerMappingVersion": undefined, - "followerMaxSequenceNum": undefined, - "followerSettingsVersion": undefined, - "id": "shard 1", - "lastRequestedSequenceNum": undefined, - "leaderGlobalCheckpoint": undefined, - "leaderIndex": undefined, - "leaderMaxSequenceNum": undefined, - "operationsReadCount": undefined, - "operationsWrittenCount": undefined, - "outstandingReadRequestsCount": undefined, - "outstandingWriteRequestsCount": undefined, - "readExceptions": undefined, - "remoteCluster": undefined, - "successfulReadRequestCount": undefined, - "successfulWriteRequestsCount": undefined, - "timeSinceLastReadMs": undefined, - "totalReadRemoteExecTimeMs": undefined, - "totalReadTimeMs": undefined, - "totalWriteTimeMs": undefined, - "writeBufferOperationsCount": undefined, - "writeBufferSizeBytes": undefined, - }, - Object { - "bytesReadCount": undefined, - "failedReadRequestsCount": undefined, - "failedWriteRequestsCount": undefined, - "followerGlobalCheckpoint": undefined, - "followerMappingVersion": undefined, - "followerMaxSequenceNum": undefined, - "followerSettingsVersion": undefined, - "id": "shard 2", - "lastRequestedSequenceNum": undefined, - "leaderGlobalCheckpoint": undefined, - "leaderIndex": undefined, - "leaderMaxSequenceNum": undefined, - "operationsReadCount": undefined, - "operationsWrittenCount": undefined, - "outstandingReadRequestsCount": undefined, - "outstandingWriteRequestsCount": undefined, - "readExceptions": undefined, - "remoteCluster": undefined, - "successfulReadRequestCount": undefined, - "successfulWriteRequestsCount": undefined, - "timeSinceLastReadMs": undefined, - "totalReadRemoteExecTimeMs": undefined, - "totalReadTimeMs": undefined, - "totalWriteTimeMs": undefined, - "writeBufferOperationsCount": undefined, - "writeBufferSizeBytes": undefined, - }, - ], - "status": "active", -} -`; - -exports[`[CCR] follower index serialization deserializeShard() deserializes shard 1`] = ` -Object { - "bytesReadCount": "bytes read", - "failedReadRequestsCount": "failed read requests", - "failedWriteRequestsCount": "failed write requests", - "followerGlobalCheckpoint": "follower global checkpoint", - "followerMappingVersion": "follower mapping version", - "followerMaxSequenceNum": "follower max seq no", - "followerSettingsVersion": "follower settings version", - "id": "shard id", - "lastRequestedSequenceNum": "last requested seq no", - "leaderGlobalCheckpoint": "leader global checkpoint", - "leaderIndex": "leader index", - "leaderMaxSequenceNum": "leader max seq no", - "operationsReadCount": "operations read", - "operationsWrittenCount": "operations written", - "outstandingReadRequestsCount": "outstanding read requests", - "outstandingWriteRequestsCount": "outstanding write requests", - "readExceptions": Array [ - "read exception", - ], - "remoteCluster": "remote cluster", - "successfulReadRequestCount": "successful read requests", - "successfulWriteRequestsCount": "successful write requests", - "timeSinceLastReadMs": "time since last read millis", - "totalReadRemoteExecTimeMs": "total read remote exec time millis", - "totalReadTimeMs": "total read time millis", - "totalWriteTimeMs": "total write time millis", - "writeBufferOperationsCount": "write buffer operation count", - "writeBufferSizeBytes": "write buffer size in bytes", -} -`; - -exports[`[CCR] follower index serialization serializeFollowerIndex() serializes object to Elasticsearch follower index object 1`] = ` -Object { - "leader_index": "leader index", - "max_outstanding_read_requests": "foo", - "max_outstanding_write_requests": "foo", - "max_read_request_operation_count": "foo", - "max_read_request_size": "foo", - "max_retry_delay": "foo", - "max_write_buffer_count": "foo", - "max_write_buffer_size": "foo", - "max_write_request_operation_count": "foo", - "max_write_request_size": "foo", - "read_poll_timeout": "foo", - "remote_cluster": "remote cluster", -} -`; diff --git a/x-pack/plugins/cross_cluster_replication/common/services/__snapshots__/follower_index_serialization.test.ts.snap b/x-pack/plugins/cross_cluster_replication/common/services/__snapshots__/follower_index_serialization.test.ts.snap new file mode 100644 index 0000000000000..923162f934016 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/common/services/__snapshots__/follower_index_serialization.test.ts.snap @@ -0,0 +1,128 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`[CCR] follower index serialization deserializeFollowerIndex() deserializes Elasticsearch follower index object 1`] = ` +Object { + "leaderIndex": "leader 1", + "maxOutstandingReadRequests": 1, + "maxOutstandingWriteRequests": 1, + "maxReadRequestOperationCount": 1, + "maxReadRequestSize": 1, + "maxRetryDelay": 1, + "maxWriteBufferCount": 1, + "maxWriteBufferSize": 1, + "maxWriteRequestOperationCount": 1, + "maxWriteRequestSize": 1, + "name": "follower index 1", + "readPollTimeout": 1, + "remoteCluster": "cluster 1", + "shards": Array [ + Object { + "bytesReadCount": 1, + "failedReadRequestsCount": 1, + "failedWriteRequestsCount": 1, + "followerGlobalCheckpoint": 1, + "followerMappingVersion": 1, + "followerMaxSequenceNum": 1, + "followerSettingsVersion": 1, + "id": 1, + "lastRequestedSequenceNum": 1, + "leaderGlobalCheckpoint": 1, + "leaderIndex": "leader 1", + "leaderMaxSequenceNum": 1, + "operationsReadCount": 1, + "operationsWrittenCount": 1, + "outstandingReadRequestsCount": 1, + "outstandingWriteRequestsCount": 1, + "readExceptions": Array [], + "remoteCluster": "cluster 1", + "successfulReadRequestCount": 1, + "successfulWriteRequestsCount": 1, + "timeSinceLastReadMs": 1, + "totalReadRemoteExecTimeMs": 1, + "totalReadTimeMs": 1, + "totalWriteTimeMs": 1, + "writeBufferOperationsCount": 1, + "writeBufferSizeBytes": 1, + }, + Object { + "bytesReadCount": undefined, + "failedReadRequestsCount": undefined, + "failedWriteRequestsCount": undefined, + "followerGlobalCheckpoint": undefined, + "followerMappingVersion": undefined, + "followerMaxSequenceNum": undefined, + "followerSettingsVersion": undefined, + "id": "shard 2", + "lastRequestedSequenceNum": undefined, + "leaderGlobalCheckpoint": undefined, + "leaderIndex": "leader_index 2", + "leaderMaxSequenceNum": undefined, + "operationsReadCount": undefined, + "operationsWrittenCount": undefined, + "outstandingReadRequestsCount": undefined, + "outstandingWriteRequestsCount": undefined, + "readExceptions": undefined, + "remoteCluster": "remote_cluster 2", + "successfulReadRequestCount": undefined, + "successfulWriteRequestsCount": undefined, + "timeSinceLastReadMs": undefined, + "totalReadRemoteExecTimeMs": undefined, + "totalReadTimeMs": undefined, + "totalWriteTimeMs": undefined, + "writeBufferOperationsCount": undefined, + "writeBufferSizeBytes": undefined, + }, + ], + "status": "active", +} +`; + +exports[`[CCR] follower index serialization deserializeShard() deserializes shard 1`] = ` +Object { + "bytesReadCount": 1, + "failedReadRequestsCount": 1, + "failedWriteRequestsCount": 1, + "followerGlobalCheckpoint": 1, + "followerMappingVersion": 1, + "followerMaxSequenceNum": 1, + "followerSettingsVersion": 1, + "id": 1, + "lastRequestedSequenceNum": 1, + "leaderGlobalCheckpoint": 1, + "leaderIndex": "leader index", + "leaderMaxSequenceNum": 1, + "operationsReadCount": 1, + "operationsWrittenCount": 1, + "outstandingReadRequestsCount": 1, + "outstandingWriteRequestsCount": 1, + "readExceptions": Array [ + "read exception", + ], + "remoteCluster": "remote cluster", + "successfulReadRequestCount": 1, + "successfulWriteRequestsCount": 1, + "timeSinceLastReadMs": 1, + "totalReadRemoteExecTimeMs": 1, + "totalReadTimeMs": 1, + "totalWriteTimeMs": 1, + "writeBufferOperationsCount": 1, + "writeBufferSizeBytes": 1, +} +`; + +exports[`[CCR] follower index serialization serializeFollowerIndex() serializes object to Elasticsearch follower index object 1`] = ` +Object { + "leader_index": "leader index", + "max_outstanding_read_requests": 1, + "max_outstanding_write_requests": 1, + "max_read_request_operation_count": 1, + "max_read_request_size": 1, + "max_retry_delay": 1, + "max_write_buffer_count": 1, + "max_write_buffer_size": 1, + "max_write_request_operation_count": 1, + "max_write_request_size": 1, + "read_poll_timeout": 1, + "remote_cluster": "remote cluster", +} +`; diff --git a/x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.js b/x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.js deleted file mode 100644 index ae13c625a7d80..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export const deserializeAutoFollowPattern = ( - { - name, - pattern: { - active, - // eslint-disable-next-line camelcase - remote_cluster, - // eslint-disable-next-line camelcase - leader_index_patterns, - // eslint-disable-next-line camelcase - follow_index_pattern, - }, - } = { - pattern: {}, - } -) => ({ - name, - active, - remoteCluster: remote_cluster, - leaderIndexPatterns: leader_index_patterns, - followIndexPattern: follow_index_pattern, -}); - -export const deserializeListAutoFollowPatterns = autoFollowPatterns => - autoFollowPatterns.map(deserializeAutoFollowPattern); - -export const serializeAutoFollowPattern = ({ - remoteCluster, - leaderIndexPatterns, - followIndexPattern, -}) => ({ - remote_cluster: remoteCluster, - leader_index_patterns: leaderIndexPatterns, - follow_index_pattern: followIndexPattern, -}); diff --git a/x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.test.js b/x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.test.ts similarity index 85% rename from x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.test.js rename to x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.test.ts index eef87a6cc4c89..fe3e59f21ee23 100644 --- a/x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.test.js +++ b/x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.test.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { AutoFollowPattern, AutoFollowPatternFromEs } from '../types'; + import { deserializeAutoFollowPattern, deserializeListAutoFollowPatterns, @@ -12,13 +14,10 @@ import { describe('[CCR] auto-follow_serialization', () => { describe('deserializeAutoFollowPattern()', () => { - it('should return empty object if name or esObject are not provided', () => { - expect(deserializeAutoFollowPattern()).toEqual({}); - }); - it('should deserialize Elasticsearch object', () => { const expected = { name: 'some-name', + active: true, remoteCluster: 'foo', leaderIndexPatterns: ['foo-*'], followIndexPattern: 'bar', @@ -27,13 +26,14 @@ describe('[CCR] auto-follow_serialization', () => { const esObject = { name: 'some-name', pattern: { + active: true, remote_cluster: expected.remoteCluster, leader_index_patterns: expected.leaderIndexPatterns, follow_index_pattern: expected.followIndexPattern, }, }; - expect(deserializeAutoFollowPattern(esObject)).toEqual(expected); + expect(deserializeAutoFollowPattern(esObject as AutoFollowPatternFromEs)).toEqual(expected); }); }); @@ -78,7 +78,9 @@ describe('[CCR] auto-follow_serialization', () => { ], }; - expect(deserializeListAutoFollowPatterns(esObjects.patterns)).toEqual(expected); + expect( + deserializeListAutoFollowPatterns(esObjects.patterns as AutoFollowPatternFromEs[]) + ).toEqual(expected); }); }); @@ -96,7 +98,7 @@ describe('[CCR] auto-follow_serialization', () => { followIndexPattern: expected.follow_index_pattern, }; - expect(serializeAutoFollowPattern(object)).toEqual(expected); + expect(serializeAutoFollowPattern(object as AutoFollowPattern)).toEqual(expected); }); }); }); diff --git a/x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.ts b/x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.ts new file mode 100644 index 0000000000000..265af0ede1462 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/common/services/auto_follow_pattern_serialization.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 { AutoFollowPattern, AutoFollowPatternFromEs, AutoFollowPatternToEs } from '../types'; + +export const deserializeAutoFollowPattern = ( + autoFollowPattern: AutoFollowPatternFromEs +): AutoFollowPattern => { + const { + name, + pattern: { active, remote_cluster, leader_index_patterns, follow_index_pattern }, + } = autoFollowPattern; + + return { + name, + active, + remoteCluster: remote_cluster, + leaderIndexPatterns: leader_index_patterns, + followIndexPattern: follow_index_pattern, + }; +}; + +export const deserializeListAutoFollowPatterns = ( + autoFollowPatterns: AutoFollowPatternFromEs[] +): AutoFollowPattern[] => autoFollowPatterns.map(deserializeAutoFollowPattern); + +export const serializeAutoFollowPattern = ({ + remoteCluster, + leaderIndexPatterns, + followIndexPattern, +}: AutoFollowPattern): AutoFollowPatternToEs => ({ + remote_cluster: remoteCluster, + leader_index_patterns: leaderIndexPatterns, + follow_index_pattern: followIndexPattern, +}); diff --git a/x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.test.js b/x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.test.ts similarity index 55% rename from x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.test.js rename to x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.test.ts index e1df917d899ad..8562750f31970 100644 --- a/x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.test.js +++ b/x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.test.ts @@ -4,6 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { ShardFromEs, FollowerIndexFromEs, FollowerIndex } from '../types'; + import { deserializeShard, deserializeFollowerIndex, @@ -17,52 +19,96 @@ describe('[CCR] follower index serialization', () => { const serializedShard = { remote_cluster: 'remote cluster', leader_index: 'leader index', - shard_id: 'shard id', - leader_global_checkpoint: 'leader global checkpoint', - leader_max_seq_no: 'leader max seq no', - follower_global_checkpoint: 'follower global checkpoint', - follower_max_seq_no: 'follower max seq no', - last_requested_seq_no: 'last requested seq no', - outstanding_read_requests: 'outstanding read requests', - outstanding_write_requests: 'outstanding write requests', - write_buffer_operation_count: 'write buffer operation count', - write_buffer_size_in_bytes: 'write buffer size in bytes', - follower_mapping_version: 'follower mapping version', - follower_settings_version: 'follower settings version', - total_read_time_millis: 'total read time millis', - total_read_remote_exec_time_millis: 'total read remote exec time millis', - successful_read_requests: 'successful read requests', - failed_read_requests: 'failed read requests', - operations_read: 'operations read', - bytes_read: 'bytes read', - total_write_time_millis: 'total write time millis', - successful_write_requests: 'successful write requests', - failed_write_requests: 'failed write requests', - operations_written: 'operations written', + shard_id: 1, + leader_global_checkpoint: 1, + leader_max_seq_no: 1, + follower_global_checkpoint: 1, + follower_max_seq_no: 1, + last_requested_seq_no: 1, + outstanding_read_requests: 1, + outstanding_write_requests: 1, + write_buffer_operation_count: 1, + write_buffer_size_in_bytes: 1, + follower_mapping_version: 1, + follower_settings_version: 1, + total_read_time_millis: 1, + total_read_remote_exec_time_millis: 1, + successful_read_requests: 1, + failed_read_requests: 1, + operations_read: 1, + bytes_read: 1, + total_write_time_millis: 1, + successful_write_requests: 1, + failed_write_requests: 1, + operations_written: 1, read_exceptions: ['read exception'], - time_since_last_read_millis: 'time since last read millis', + time_since_last_read_millis: 1, }; - expect(deserializeShard(serializedShard)).toMatchSnapshot(); + expect(deserializeShard(serializedShard as ShardFromEs)).toMatchSnapshot(); }); }); describe('deserializeFollowerIndex()', () => { it('deserializes Elasticsearch follower index object', () => { const serializedFollowerIndex = { - index: 'follower index name', + follower_index: 'follower index 1', + remote_cluster: 'cluster 1', + leader_index: 'leader 1', status: 'active', + parameters: { + max_read_request_operation_count: 1, + max_outstanding_read_requests: 1, + max_read_request_size: 1, + max_write_request_operation_count: 1, + max_write_request_size: 1, + max_outstanding_write_requests: 1, + max_write_buffer_count: 1, + max_write_buffer_size: 1, + max_retry_delay: 1, + read_poll_timeout: 1, + }, shards: [ { - shard_id: 'shard 1', + remote_cluster: 'cluster 1', + leader_index: 'leader 1', + shard_id: 1, + leader_global_checkpoint: 1, + leader_max_seq_no: 1, + follower_global_checkpoint: 1, + follower_max_seq_no: 1, + last_requested_seq_no: 1, + outstanding_read_requests: 1, + outstanding_write_requests: 1, + write_buffer_operation_count: 1, + write_buffer_size_in_bytes: 1, + follower_mapping_version: 1, + follower_settings_version: 1, + total_read_time_millis: 1, + total_read_remote_exec_time_millis: 1, + successful_read_requests: 1, + failed_read_requests: 1, + operations_read: 1, + bytes_read: 1, + total_write_time_millis: 1, + successful_write_requests: 1, + failed_write_requests: 1, + operations_written: 1, + // This is an array of exception objects + read_exceptions: [], + time_since_last_read_millis: 1, }, { + remote_cluster: 'remote_cluster 2', + leader_index: 'leader_index 2', shard_id: 'shard 2', }, ], }; - expect(deserializeFollowerIndex(serializedFollowerIndex)).toMatchSnapshot(); + expect( + deserializeFollowerIndex(serializedFollowerIndex as FollowerIndexFromEs) + ).toMatchSnapshot(); }); }); @@ -157,19 +203,19 @@ describe('[CCR] follower index serialization', () => { const deserializedFollowerIndex = { remoteCluster: 'remote cluster', leaderIndex: 'leader index', - maxReadRequestOperationCount: 'foo', - maxOutstandingReadRequests: 'foo', - maxReadRequestSize: 'foo', - maxWriteRequestOperationCount: 'foo', - maxWriteRequestSize: 'foo', - maxOutstandingWriteRequests: 'foo', - maxWriteBufferCount: 'foo', - maxWriteBufferSize: 'foo', - maxRetryDelay: 'foo', - readPollTimeout: 'foo', + maxReadRequestOperationCount: 1, + maxOutstandingReadRequests: 1, + maxReadRequestSize: 1, + maxWriteRequestOperationCount: 1, + maxWriteRequestSize: 1, + maxOutstandingWriteRequests: 1, + maxWriteBufferCount: 1, + maxWriteBufferSize: 1, + maxRetryDelay: 1, + readPollTimeout: 1, }; - expect(serializeFollowerIndex(deserializedFollowerIndex)).toMatchSnapshot(); + expect(serializeFollowerIndex(deserializedFollowerIndex as FollowerIndex)).toMatchSnapshot(); }); }); }); diff --git a/x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.js b/x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.ts similarity index 87% rename from x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.js rename to x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.ts index c41fde8f7818d..df476a0b2db89 100644 --- a/x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.js +++ b/x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.ts @@ -4,7 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable camelcase */ +import { + ShardFromEs, + Shard, + FollowerIndexFromEs, + FollowerIndex, + FollowerIndexToEs, + FollowerIndexAdvancedSettings, + FollowerIndexAdvancedSettingsToEs, +} from '../types'; + export const deserializeShard = ({ remote_cluster, leader_index, @@ -32,7 +41,7 @@ export const deserializeShard = ({ operations_written, read_exceptions, time_since_last_read_millis, -}) => ({ +}: ShardFromEs): Shard => ({ id: shard_id, remoteCluster: remote_cluster, leaderIndex: leader_index, @@ -61,9 +70,7 @@ export const deserializeShard = ({ readExceptions: read_exceptions, timeSinceLastReadMs: time_since_last_read_millis, }); -/* eslint-enable camelcase */ -/* eslint-disable camelcase */ export const deserializeFollowerIndex = ({ follower_index, remote_cluster, @@ -82,7 +89,7 @@ export const deserializeFollowerIndex = ({ read_poll_timeout, } = {}, shards, -}) => ({ +}: FollowerIndexFromEs): FollowerIndex => ({ name: follower_index, remoteCluster: remote_cluster, leaderIndex: leader_index, @@ -99,10 +106,10 @@ export const deserializeFollowerIndex = ({ readPollTimeout: read_poll_timeout, shards: shards && shards.map(deserializeShard), }); -/* eslint-enable camelcase */ -export const deserializeListFollowerIndices = followerIndices => - followerIndices.map(deserializeFollowerIndex); +export const deserializeListFollowerIndices = ( + followerIndices: FollowerIndexFromEs[] +): FollowerIndex[] => followerIndices.map(deserializeFollowerIndex); export const serializeAdvancedSettings = ({ maxReadRequestOperationCount, @@ -115,7 +122,7 @@ export const serializeAdvancedSettings = ({ maxWriteBufferSize, maxRetryDelay, readPollTimeout, -}) => ({ +}: FollowerIndexAdvancedSettings): FollowerIndexAdvancedSettingsToEs => ({ max_read_request_operation_count: maxReadRequestOperationCount, max_outstanding_read_requests: maxOutstandingReadRequests, max_read_request_size: maxReadRequestSize, @@ -128,7 +135,7 @@ export const serializeAdvancedSettings = ({ read_poll_timeout: readPollTimeout, }); -export const serializeFollowerIndex = followerIndex => ({ +export const serializeFollowerIndex = (followerIndex: FollowerIndex): FollowerIndexToEs => ({ remote_cluster: followerIndex.remoteCluster, leader_index: followerIndex.leaderIndex, ...serializeAdvancedSettings(followerIndex), diff --git a/x-pack/plugins/cross_cluster_replication/common/services/utils.test.js b/x-pack/plugins/cross_cluster_replication/common/services/utils.test.ts similarity index 100% rename from x-pack/plugins/cross_cluster_replication/common/services/utils.test.js rename to x-pack/plugins/cross_cluster_replication/common/services/utils.test.ts diff --git a/x-pack/plugins/cross_cluster_replication/common/services/utils.js b/x-pack/plugins/cross_cluster_replication/common/services/utils.ts similarity index 62% rename from x-pack/plugins/cross_cluster_replication/common/services/utils.js rename to x-pack/plugins/cross_cluster_replication/common/services/utils.ts index 3d8c97f45327c..dda6732254cc3 100644 --- a/x-pack/plugins/cross_cluster_replication/common/services/utils.js +++ b/x-pack/plugins/cross_cluster_replication/common/services/utils.ts @@ -3,14 +3,14 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -export const arrify = val => (Array.isArray(val) ? val : [val]); +export const arrify = (val: any): any[] => (Array.isArray(val) ? val : [val]); /** * Utilty to add some latency in a Promise chain * * @param {number} time Time in millisecond to wait */ -export const wait = (time = 1000) => data => { +export const wait = (time = 1000) => (data: any): Promise => { return new Promise(resolve => { setTimeout(() => resolve(data), time); }); @@ -19,8 +19,11 @@ export const wait = (time = 1000) => data => { /** * Utility to remove empty fields ("") from a request body */ -export const removeEmptyFields = body => - Object.entries(body).reduce((acc, [key, value]) => { +export const removeEmptyFields = (body: Record): Record => + Object.entries(body).reduce((acc: Record, [key, value]: [string, any]): Record< + string, + any + > => { if (value !== '') { acc[key] = value; } diff --git a/x-pack/plugins/cross_cluster_replication/common/types.ts b/x-pack/plugins/cross_cluster_replication/common/types.ts new file mode 100644 index 0000000000000..5f3e15e0514b3 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/common/types.ts @@ -0,0 +1,184 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export interface AutoFollowPattern { + name: string; + active: boolean; + remoteCluster: string; + leaderIndexPatterns: string[]; + followIndexPattern: string; +} + +export interface AutoFollowPatternFromEs { + name: string; + pattern: { + active: boolean; + remote_cluster: string; + leader_index_patterns: string[]; + follow_index_pattern: string; + }; +} + +export interface AutoFollowPatternToEs { + remote_cluster: string; + leader_index_patterns: string[]; + follow_index_pattern: string; +} + +export interface ShardFromEs { + remote_cluster: string; + leader_index: string; + shard_id: number; + leader_global_checkpoint: number; + leader_max_seq_no: number; + follower_global_checkpoint: number; + follower_max_seq_no: number; + last_requested_seq_no: number; + outstanding_read_requests: number; + outstanding_write_requests: number; + write_buffer_operation_count: number; + write_buffer_size_in_bytes: number; + follower_mapping_version: number; + follower_settings_version: number; + total_read_time_millis: number; + total_read_remote_exec_time_millis: number; + successful_read_requests: number; + failed_read_requests: number; + operations_read: number; + bytes_read: number; + total_write_time_millis: number; + successful_write_requests: number; + failed_write_requests: number; + operations_written: number; + // This is an array of exception objects + read_exceptions: any[]; + time_since_last_read_millis: number; +} + +export interface Shard { + remoteCluster: string; + leaderIndex: string; + id: number; + leaderGlobalCheckpoint: number; + leaderMaxSequenceNum: number; + followerGlobalCheckpoint: number; + followerMaxSequenceNum: number; + lastRequestedSequenceNum: number; + outstandingReadRequestsCount: number; + outstandingWriteRequestsCount: number; + writeBufferOperationsCount: number; + writeBufferSizeBytes: number; + followerMappingVersion: number; + followerSettingsVersion: number; + totalReadTimeMs: number; + totalReadRemoteExecTimeMs: number; + successfulReadRequestCount: number; + failedReadRequestsCount: number; + operationsReadCount: number; + bytesReadCount: number; + totalWriteTimeMs: number; + successfulWriteRequestsCount: number; + failedWriteRequestsCount: number; + operationsWrittenCount: number; + // This is an array of exception objects + readExceptions: any[]; + timeSinceLastReadMs: number; +} + +export interface FollowerIndexFromEs { + follower_index: string; + remote_cluster: string; + leader_index: string; + status: string; + // Once https://github.com/elastic/elasticsearch/issues/54996 is resolved so that paused follower + // indices contain this information, we can removed this optional typing as well as the optional + // typing in FollowerIndexAdvancedSettings and FollowerIndexAdvancedSettingsToEs. + parameters?: FollowerIndexAdvancedSettingsToEs; + shards: ShardFromEs[]; +} + +export interface FollowerIndex extends FollowerIndexAdvancedSettings { + name: string; + remoteCluster: string; + leaderIndex: string; + status: string; + shards: Shard[]; +} + +export interface FollowerIndexToEs extends FollowerIndexAdvancedSettingsToEs { + remote_cluster: string; + leader_index: string; +} + +export interface FollowerIndexAdvancedSettings { + maxReadRequestOperationCount?: number; + maxOutstandingReadRequests?: number; + maxReadRequestSize?: number; + maxWriteRequestOperationCount?: number; + maxWriteRequestSize?: number; + maxOutstandingWriteRequests?: number; + maxWriteBufferCount?: number; + maxWriteBufferSize?: number; + maxRetryDelay?: number; + readPollTimeout?: number; +} + +export interface FollowerIndexAdvancedSettingsToEs { + max_read_request_operation_count?: number; + max_outstanding_read_requests?: number; + max_read_request_size?: number; + max_write_request_operation_count?: number; + max_write_request_size?: number; + max_outstanding_write_requests?: number; + max_write_buffer_count?: number; + max_write_buffer_size?: number; + max_retry_delay?: number; + read_poll_timeout?: number; +} + +export interface RecentAutoFollowError { + leaderIndex: string; + autoFollowException: { + type: string; + reason: string; + }; +} + +export interface RecentAutoFollowErrorFromEs { + leader_index: string; + auto_follow_exception: { + type: string; + reason: string; + }; +} + +export interface AutoFollowedCluster { + clusterName: string; + timeSinceLastCheckMillis: number; + lastSeenMetadataVersion: number; +} + +export interface AutoFollowedClusterFromEs { + cluster_name: string; + time_since_last_check_millis: number; + last_seen_metadata_version: number; +} + +export interface AutoFollowStats { + numberOfFailedFollowIndices: number; + numberOfFailedRemoteClusterStateRequests: number; + numberOfSuccessfulFollowIndices: number; + recentAutoFollowErrors: RecentAutoFollowError[]; + autoFollowedClusters: AutoFollowedCluster[]; +} + +export interface AutoFollowStatsFromEs { + number_of_failed_follow_indices: number; + number_of_failed_remote_cluster_state_requests: number; + number_of_successful_follow_indices: number; + recent_auto_follow_errors: RecentAutoFollowErrorFromEs[]; + auto_followed_clusters: AutoFollowedClusterFromEs[]; +} diff --git a/x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.ts b/x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.ts index 69b68ab01fc5d..4f082d742ac5c 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.ts +++ b/x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.ts @@ -6,9 +6,9 @@ import { i18n } from '@kbn/i18n'; import { ChromeBreadcrumb } from 'src/core/public'; -import { ManagementAppMountParams } from '../../../../../../../src/plugins/management/public'; +import { ManagementAppMountParams } from '../../../../../../src/plugins/management/public'; -import { BASE_PATH } from '../../../../common/constants'; +import { BASE_PATH } from '../../../common/constants'; let setBreadcrumbs: ManagementAppMountParams['setBreadcrumbs']; diff --git a/x-pack/plugins/cross_cluster_replication/public/extend_index_management.ts b/x-pack/plugins/cross_cluster_replication/public/extend_index_management.ts index 4ffe0db4e3c4e..7bf4c4744a55a 100644 --- a/x-pack/plugins/cross_cluster_replication/public/extend_index_management.ts +++ b/x-pack/plugins/cross_cluster_replication/public/extend_index_management.ts @@ -6,7 +6,8 @@ import { i18n } from '@kbn/i18n'; import { get } from 'lodash'; -import { IndexManagementPluginSetup } from '../../../../../plugins/index_management/public'; + +import { IndexManagementPluginSetup } from '../../index_management/public'; const propertyPath = 'isFollowerIndex'; diff --git a/x-pack/plugins/cross_cluster_replication/public/plugin.ts b/x-pack/plugins/cross_cluster_replication/public/plugin.ts index 46259c698b282..3ea995f1c31be 100644 --- a/x-pack/plugins/cross_cluster_replication/public/plugin.ts +++ b/x-pack/plugins/cross_cluster_replication/public/plugin.ts @@ -3,6 +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 { ChromeBreadcrumb, CoreSetup, @@ -11,7 +12,7 @@ import { DocLinksStart, } from 'src/core/public'; -import { IndexManagementPluginSetup } from '../../../../../plugins/index_management/public'; +import { IndexManagementPluginSetup } from '../../index_management/public'; // @ts-ignore; import { setHttpClient } from './app/services/api'; diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/__snapshots__/ccr_stats_serialization.test.js.snap b/x-pack/plugins/cross_cluster_replication/server/lib/__snapshots__/ccr_stats_serialization.test.ts.snap similarity index 100% rename from x-pack/plugins/cross_cluster_replication/server/lib/__snapshots__/ccr_stats_serialization.test.js.snap rename to x-pack/plugins/cross_cluster_replication/server/lib/__snapshots__/ccr_stats_serialization.test.ts.snap diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.test.js b/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.test.ts similarity index 100% rename from x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.test.js rename to x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.test.ts diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.js b/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.ts similarity index 79% rename from x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.js rename to x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.ts index e4d2f8d64d1bb..e972f6ddc20ec 100644 --- a/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.js +++ b/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.ts @@ -4,11 +4,19 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable camelcase */ +import { + RecentAutoFollowError, + RecentAutoFollowErrorFromEs, + AutoFollowedCluster, + AutoFollowedClusterFromEs, + AutoFollowStats, + AutoFollowStatsFromEs, +} from '../../common/types'; + export const deserializeRecentAutoFollowErrors = ({ leader_index, auto_follow_exception: { type, reason }, -}) => ({ +}: RecentAutoFollowErrorFromEs): RecentAutoFollowError => ({ leaderIndex: leader_index, autoFollowException: { type, @@ -20,7 +28,7 @@ export const deserializeAutoFollowedClusters = ({ cluster_name, time_since_last_check_millis, last_seen_metadata_version, -}) => ({ +}: AutoFollowedClusterFromEs): AutoFollowedCluster => ({ clusterName: cluster_name, timeSinceLastCheckMillis: time_since_last_check_millis, lastSeenMetadataVersion: last_seen_metadata_version, @@ -32,11 +40,10 @@ export const deserializeAutoFollowStats = ({ number_of_successful_follow_indices, recent_auto_follow_errors, auto_followed_clusters, -}) => ({ +}: AutoFollowStatsFromEs): AutoFollowStats => ({ numberOfFailedFollowIndices: number_of_failed_follow_indices, numberOfFailedRemoteClusterStateRequests: number_of_failed_remote_cluster_state_requests, numberOfSuccessfulFollowIndices: number_of_successful_follow_indices, recentAutoFollowErrors: recent_auto_follow_errors.map(deserializeRecentAutoFollowErrors), autoFollowedClusters: auto_followed_clusters.map(deserializeAutoFollowedClusters), }); -/* eslint-enable camelcase */ diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts index 8142c3ada3cc1..c169ec9d9a4e2 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts @@ -5,11 +5,8 @@ */ import { schema } from '@kbn/config-schema'; -// @ts-ignore -import { - serializeAutoFollowPattern, - // @ts-ignore -} from '../../../../common/services/auto_follow_pattern_serialization'; +import { serializeAutoFollowPattern } from '../../../../common/services/auto_follow_pattern_serialization'; +import { AutoFollowPattern } from '../../../../common/types'; import { addBasePath } from '../../../services'; import { RouteDependencies } from '../../../types'; @@ -33,7 +30,7 @@ export const registerCreateRoute = ({ router, license, lib }: RouteDependencies) }, license.guardApiRoute(async (context, request, response) => { const { id, ...rest } = request.body as typeof bodySchema.type; - const body = serializeAutoFollowPattern(rest); + const body = serializeAutoFollowPattern(rest as AutoFollowPattern); /** * First let's make sur that an auto-follow pattern with diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts index f3fd7769fee96..6a8b7ff1e6ef4 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts @@ -5,13 +5,7 @@ */ import { schema } from '@kbn/config-schema'; -// @ts-ignore -import { - deserializeAutoFollowPattern, - deserializeListAutoFollowPatterns, - serializeAutoFollowPattern, - // @ts-ignore -} from '../../../../common/services/auto_follow_pattern_serialization'; + import { addBasePath } from '../../../services'; import { RouteDependencies } from '../../../types'; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts index bfc3ae8c2d8bc..63ff2ea9b0a3e 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts @@ -4,11 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -// @ts-ignore -import { - deserializeListAutoFollowPatterns, - // @ts-ignore -} from '../../../../common/services/auto_follow_pattern_serialization'; +import { deserializeListAutoFollowPatterns } from '../../../../common/services/auto_follow_pattern_serialization'; import { addBasePath } from '../../../services'; import { RouteDependencies } from '../../../types'; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts index 9175626167558..d2d0e4990f682 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts @@ -5,11 +5,8 @@ */ import { schema } from '@kbn/config-schema'; -// @ts-ignore -import { - deserializeAutoFollowPattern, - // @ts-ignore -} from '../../../../common/services/auto_follow_pattern_serialization'; + +import { deserializeAutoFollowPattern } from '../../../../common/services/auto_follow_pattern_serialization'; import { addBasePath } from '../../../services'; import { RouteDependencies } from '../../../types'; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts index 4ab9b1640f511..0d00e01da9758 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts @@ -5,11 +5,8 @@ */ import { schema } from '@kbn/config-schema'; -// @ts-ignore -import { - serializeAutoFollowPattern, - // @ts-ignore -} from '../../../../common/services/auto_follow_pattern_serialization'; +import { serializeAutoFollowPattern } from '../../../../common/services/auto_follow_pattern_serialization'; +import { AutoFollowPattern } from '../../../../common/types'; import { addBasePath } from '../../../services'; import { RouteDependencies } from '../../../types'; @@ -31,7 +28,7 @@ export const registerUpdateRoute = ({ router, license, lib }: RouteDependencies) }, license.guardApiRoute(async (context, request, response) => { const { id } = request.params as typeof paramsSchema.type; - const body = serializeAutoFollowPattern(request.body); + const body = serializeAutoFollowPattern(request.body as AutoFollowPattern); try { return response.ok({ diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts index 0d9f4c0c9a451..776ed0bc11965 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts @@ -5,7 +5,6 @@ */ import { addBasePath } from '../../../services'; -// @ts-ignore import { deserializeAutoFollowStats } from '../../../lib/ccr_stats_serialization'; import { RouteDependencies } from '../../../types'; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts index edecaf74d8192..3d96bccf45d4a 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts @@ -5,12 +5,9 @@ */ import { schema } from '@kbn/config-schema'; -import { - serializeFollowerIndex, - // @ts-ignore -} from '../../../../common/services/follower_index_serialization'; +import { serializeFollowerIndex } from '../../../../common/services/follower_index_serialization'; +import { FollowerIndex } from '../../../../common/types'; import { addBasePath } from '../../../services'; -// @ts-ignore import { removeEmptyFields } from '../../../../common/services/utils'; import { RouteDependencies } from '../../../types'; @@ -34,7 +31,7 @@ export const registerCreateRoute = ({ router, license, lib }: RouteDependencies) }, license.guardApiRoute(async (context, request, response) => { const { name, ...rest } = request.body as typeof bodySchema.type; - const body = removeEmptyFields(serializeFollowerIndex(rest)); + const body = removeEmptyFields(serializeFollowerIndex(rest as FollowerIndex)); try { return response.ok({ diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts index da68bc15a9c90..518e805f2386d 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts @@ -4,12 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - deserializeListFollowerIndices, - // @ts-ignore -} from '../../../../common/services/follower_index_serialization'; +import { deserializeListFollowerIndices } from '../../../../common/services/follower_index_serialization'; import { addBasePath } from '../../../services'; -// @ts-ignore import { RouteDependencies } from '../../../types'; /** diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts index fe2bea7351c87..1e1a19234c801 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts @@ -5,12 +5,8 @@ */ import { schema } from '@kbn/config-schema'; -import { - deserializeFollowerIndex, - // @ts-ignore -} from '../../../../common/services/follower_index_serialization'; +import { deserializeFollowerIndex } from '../../../../common/services/follower_index_serialization'; import { addBasePath } from '../../../services'; -// @ts-ignore import { RouteDependencies } from '../../../types'; /** diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts index 241e515e184b7..1d964ed2a8c2a 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts @@ -5,11 +5,8 @@ */ import { schema } from '@kbn/config-schema'; -import { - serializeAdvancedSettings, - // @ts-ignore -} from '../../../../common/services/follower_index_serialization'; -// @ts-ignore +import { serializeAdvancedSettings } from '../../../../common/services/follower_index_serialization'; +import { FollowerIndexAdvancedSettings } from '../../../../common/types'; import { removeEmptyFields } from '../../../../common/services/utils'; import { addBasePath } from '../../../services'; import { RouteDependencies } from '../../../types'; @@ -53,7 +50,9 @@ export const registerUpdateRoute = ({ router, license, lib }: RouteDependencies) } // Resume follower - const body = removeEmptyFields(serializeAdvancedSettings(request.body)); + const body = removeEmptyFields( + serializeAdvancedSettings(request.body as FollowerIndexAdvancedSettings) + ); return response.ok({ body: await context.crossClusterReplication!.client.callAsCurrentUser( 'ccr.resumeFollowerIndex', From 343f9c0d4b9ce129d25904ad152cc3e70fc062ae Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Sun, 12 Apr 2020 15:52:46 -0700 Subject: [PATCH 05/20] Migrate public to NP. - Localize mocks with the component integration tests. --- .../auto_follow_pattern_add.test.js | 7 +- .../auto_follow_pattern_edit.test.js | 4 +- .../auto_follow_pattern_list.test.js | 7 +- .../follower_index_add.test.js | 7 +- .../follower_index_edit.test.js | 6 +- .../follower_indices_list.test.js | 6 +- .../auto_follow_pattern_add.helpers.js | 2 +- .../auto_follow_pattern_edit.helpers.js | 2 +- .../auto_follow_pattern_list.helpers.js | 2 +- .../helpers/follower_index_add.helpers.js | 2 +- .../helpers/follower_index_edit.helpers.js | 2 +- .../helpers/follower_index_list.helpers.js | 2 +- .../helpers/home.helpers.js | 4 +- .../__jest__/client_integration/home.test.js | 6 +- .../mocks}/breadcrumbs.mock.ts | 4 +- .../client_integration/mocks/index.ts | 8 ++ .../mocks/track_ui_metric.mock.ts | 13 ++ .../public/app/{app.js => app.tsx} | 40 +++---- .../auto_follow_pattern_action_menu.tsx | 2 +- .../components/auto_follow_pattern_form.js | 2 +- .../follower_index_form.js | 2 +- .../follower_index_resume_provider.js | 2 +- .../public/app/components/index.d.ts | 7 ++ .../components/remote_clusters_form_field.js | 2 +- .../public/app/constants/{api.js => api.ts} | 0 .../app/constants/{index.js => index.ts} | 0 .../constants/{sections.js => sections.ts} | 0 .../constants/{ui_metric.js => ui_metric.ts} | 0 .../public/app/{index.js => index.tsx} | 10 +- .../auto_follow_pattern_edit.js | 2 +- .../follower_index_edit.js | 2 +- .../auto_follow_pattern_list.js | 2 +- .../auto_follow_pattern_table.js | 6 +- .../components/context_menu/context_menu.js | 2 +- .../follower_indices_table.js | 6 +- .../follower_indices_list.js | 2 +- .../public/app/sections/home/home.js | 2 +- .../public/app/sections/index.d.ts | 11 ++ .../public/app/services/breadcrumbs.ts | 20 ++-- .../app/services/documentation_links.ts | 20 ++-- .../public/app/services/notifications.ts | 16 ++- .../{index.js => app/services/routing.d.ts} | 2 +- .../public/app/services/routing.js | 11 +- ...{track_ui_metric.js => track_ui_metric.ts} | 21 +++- .../app/store/actions/auto_follow_pattern.js | 18 +-- .../app/store/actions/follower_index.js | 20 ++-- .../public/app/store/index.d.ts | 7 ++ .../public/extend_index_management.ts | 29 ----- .../public/index.scss | 5 +- .../cross_cluster_replication/public/index.ts | 5 +- .../public/main.html | 3 - .../public/plugin.ts | 112 +++++++++++++----- .../public/register_routes.js | 94 --------------- .../cross_cluster_replication/public/types.ts | 23 ++++ .../application/services/notification.ts | 8 +- 55 files changed, 284 insertions(+), 316 deletions(-) rename x-pack/plugins/cross_cluster_replication/public/{app/services => __jest__/client_integration/mocks}/breadcrumbs.mock.ts (70%) create mode 100644 x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/mocks/index.ts create mode 100644 x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/mocks/track_ui_metric.mock.ts rename x-pack/plugins/cross_cluster_replication/public/app/{app.js => app.tsx} (90%) create mode 100644 x-pack/plugins/cross_cluster_replication/public/app/components/index.d.ts rename x-pack/plugins/cross_cluster_replication/public/app/constants/{api.js => api.ts} (100%) rename x-pack/plugins/cross_cluster_replication/public/app/constants/{index.js => index.ts} (100%) rename x-pack/plugins/cross_cluster_replication/public/app/constants/{sections.js => sections.ts} (100%) rename x-pack/plugins/cross_cluster_replication/public/app/constants/{ui_metric.js => ui_metric.ts} (100%) rename x-pack/plugins/cross_cluster_replication/public/app/{index.js => index.tsx} (65%) create mode 100644 x-pack/plugins/cross_cluster_replication/public/app/sections/index.d.ts rename x-pack/plugins/cross_cluster_replication/public/{index.js => app/services/routing.d.ts} (87%) rename x-pack/plugins/cross_cluster_replication/public/app/services/{track_ui_metric.js => track_ui_metric.ts} (50%) create mode 100644 x-pack/plugins/cross_cluster_replication/public/app/store/index.d.ts delete mode 100644 x-pack/plugins/cross_cluster_replication/public/extend_index_management.ts delete mode 100644 x-pack/plugins/cross_cluster_replication/public/main.html delete mode 100644 x-pack/plugins/cross_cluster_replication/public/register_routes.js create mode 100644 x-pack/plugins/cross_cluster_replication/public/types.ts diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_add.test.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_add.test.js index d2f8830e47d13..db1430d157183 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_add.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_add.test.js @@ -3,11 +3,10 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import '../../app/services/breadcrumbs.mock'; -import { setupEnvironment, pageHelpers, nextTick, getRandomString } from './helpers'; -import { indexPatterns } from '../../../../../../src/plugins/data/public'; -jest.mock('ui/new_platform'); +import { indexPatterns } from '../../../../../../src/plugins/data/public'; +import './mocks'; +import { setupEnvironment, pageHelpers, nextTick, getRandomString } from './helpers'; const { setup } = pageHelpers.autoFollowPatternAdd; diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_edit.test.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_edit.test.js index 760105beb7f8a..170bce7b82085 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_edit.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_edit.test.js @@ -4,13 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../app/services/breadcrumbs.mock'; import { AutoFollowPatternForm } from '../../app/components/auto_follow_pattern_form'; +import './mocks'; import { setupEnvironment, pageHelpers, nextTick } from './helpers'; import { AUTO_FOLLOW_PATTERN_EDIT } from './helpers/constants'; -jest.mock('ui/new_platform'); - const { setup } = pageHelpers.autoFollowPatternEdit; const { setup: setupAutoFollowPatternAdd } = pageHelpers.autoFollowPatternAdd; diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_list.test.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_list.test.js index 8a47b18214449..f70c700f06e1a 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_list.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_list.test.js @@ -4,12 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../app/services/breadcrumbs.mock'; -import { setupEnvironment, pageHelpers, nextTick, getRandomString } from './helpers'; - import { getAutoFollowPatternClientMock } from '../../../fixtures/auto_follow_pattern'; - -jest.mock('ui/new_platform'); +import './mocks'; +import { setupEnvironment, pageHelpers, nextTick, getRandomString } from './helpers'; const { setup } = pageHelpers.autoFollowPatternList; diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_index_add.test.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_index_add.test.js index 16e3726d7fede..4c99339e16952 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_index_add.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_index_add.test.js @@ -4,14 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../app/services/breadcrumbs.mock'; +import { indexPatterns } from '../../../../../../src/plugins/data/public'; +import './mocks'; import { setupEnvironment, pageHelpers, nextTick } from './helpers'; import { RemoteClustersFormField } from '../../app/components'; -import { indexPatterns } from '../../../../../../src/plugins/data/public'; - -jest.mock('ui/new_platform'); - const { setup } = pageHelpers.followerIndexAdd; const { setup: setupAutoFollowPatternAdd } = pageHelpers.autoFollowPatternAdd; diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_index_edit.test.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_index_edit.test.js index 4e54d8e9d7c40..f4bda2af653aa 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_index_edit.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_index_edit.test.js @@ -4,12 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../app/services/breadcrumbs.mock'; -import { setupEnvironment, pageHelpers, nextTick } from './helpers'; import { FollowerIndexForm } from '../../app/components/follower_index_form/follower_index_form'; +import './mocks'; import { FOLLOWER_INDEX_EDIT } from './helpers/constants'; - -jest.mock('ui/new_platform'); +import { setupEnvironment, pageHelpers, nextTick } from './helpers'; const { setup } = pageHelpers.followerIndexEdit; const { setup: setupFollowerIndexAdd } = pageHelpers.followerIndexAdd; diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js index 96e5b4fe1eb4b..c06a51bc94c7b 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js @@ -4,11 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { setupEnvironment, pageHelpers, nextTick, getRandomString } from './helpers'; - import { getFollowerIndexMock } from '../../../fixtures/follower_index'; - -jest.mock('ui/new_platform'); +import './mocks'; +import { setupEnvironment, pageHelpers, nextTick, getRandomString } from './helpers'; const { setup } = pageHelpers.followerIndexList; diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_add.helpers.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_add.helpers.js index 24d759b8e68c3..1cb4e7c7725df 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_add.helpers.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_add.helpers.js @@ -7,7 +7,7 @@ import { registerTestBed } from '../../../../../../test_utils'; import { AutoFollowPatternAdd } from '../../../app/sections/auto_follow_pattern_add'; import { ccrStore } from '../../../app/store'; -import routing from '../../../app/services/routing'; +import { routing } from '../../../app/services/routing'; const testBedConfig = { store: ccrStore, diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_edit.helpers.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_edit.helpers.js index 8b245227fed6c..9cad61893c409 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_edit.helpers.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_edit.helpers.js @@ -7,7 +7,7 @@ import { registerTestBed } from '../../../../../../test_utils'; import { AutoFollowPatternEdit } from '../../../app/sections/auto_follow_pattern_edit'; import { ccrStore } from '../../../app/store'; -import routing from '../../../app/services/routing'; +import { routing } from '../../../app/services/routing'; import { AUTO_FOLLOW_PATTERN_EDIT_NAME } from './constants'; diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_list.helpers.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_list.helpers.js index 7588ed1fd82b6..450feed49f9f2 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_list.helpers.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/auto_follow_pattern_list.helpers.js @@ -7,7 +7,7 @@ import { registerTestBed, findTestSubject } from '../../../../../../test_utils'; import { AutoFollowPatternList } from '../../../app/sections/home/auto_follow_pattern_list'; import { ccrStore } from '../../../app/store'; -import routing from '../../../app/services/routing'; +import { routing } from '../../../app/services/routing'; const testBedConfig = { store: ccrStore, diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_add.helpers.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_add.helpers.js index 82acd8b2156bd..856b09f3f3cba 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_add.helpers.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_add.helpers.js @@ -7,7 +7,7 @@ import { registerTestBed } from '../../../../../../test_utils'; import { FollowerIndexAdd } from '../../../app/sections/follower_index_add'; import { ccrStore } from '../../../app/store'; -import routing from '../../../app/services/routing'; +import { routing } from '../../../app/services/routing'; const testBedConfig = { store: ccrStore, diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_edit.helpers.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_edit.helpers.js index 45e21a6d32eab..893d01f151bc2 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_edit.helpers.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_edit.helpers.js @@ -7,7 +7,7 @@ import { registerTestBed } from '../../../../../../test_utils'; import { FollowerIndexEdit } from '../../../app/sections/follower_index_edit'; import { ccrStore } from '../../../app/store'; -import routing from '../../../app/services/routing'; +import { routing } from '../../../app/services/routing'; import { FOLLOWER_INDEX_EDIT_NAME } from './constants'; diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_list.helpers.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_list.helpers.js index 075b38fee1708..52f4267594cc1 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_list.helpers.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/follower_index_list.helpers.js @@ -7,7 +7,7 @@ import { registerTestBed, findTestSubject } from '../../../../../../test_utils'; import { FollowerIndicesList } from '../../../app/sections/home/follower_indices_list'; import { ccrStore } from '../../../app/store'; -import routing from '../../../app/services/routing'; +import { routing } from '../../../app/services/routing'; const testBedConfig = { store: ccrStore, diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/home.helpers.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/home.helpers.js index 3260f54e2cf20..56dfa765bfa4f 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/home.helpers.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/helpers/home.helpers.js @@ -5,10 +5,10 @@ */ import { registerTestBed } from '../../../../../../test_utils'; +import { BASE_PATH } from '../../../../common/constants'; import { CrossClusterReplicationHome } from '../../../app/sections/home/home'; import { ccrStore } from '../../../app/store'; -import routing from '../../../app/services/routing'; -import { BASE_PATH } from '../../../../../../legacy/common/constants'; +import { routing } from '../../../app/services/routing'; const testBedConfig = { store: ccrStore, diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/home.test.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/home.test.js index 855675a9e9c7a..18d8b4eb9dbe0 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/home.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/home.test.js @@ -4,11 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../app/services/breadcrumbs.mock'; +import './mocks'; import { setupEnvironment, pageHelpers, nextTick } from './helpers'; -jest.mock('ui/new_platform'); - const { setup } = pageHelpers.home; describe('', () => { @@ -36,7 +34,7 @@ describe('', () => { ({ exists, find, component } = setup()); }); - test('should set the correct an app title', () => { + test('should set the correct app title', () => { expect(exists('appTitle')).toBe(true); expect(find('appTitle').text()).toEqual('Cross-Cluster Replication'); }); diff --git a/x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.mock.ts b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/mocks/breadcrumbs.mock.ts similarity index 70% rename from x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.mock.ts rename to x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/mocks/breadcrumbs.mock.ts index b7c75108d4ef0..60a196254d408 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.mock.ts +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/mocks/breadcrumbs.mock.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -jest.mock('./breadcrumbs', () => ({ - ...jest.requireActual('./breadcrumbs'), +jest.mock('../../../app/services/breadcrumbs', () => ({ + ...jest.requireActual('../../../app/services/breadcrumbs'), setBreadcrumbs: jest.fn(), })); diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/mocks/index.ts b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/mocks/index.ts new file mode 100644 index 0000000000000..cff9c003f3e80 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/mocks/index.ts @@ -0,0 +1,8 @@ +/* + * 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 './breadcrumbs.mock'; +import './track_ui_metric.mock'; diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/mocks/track_ui_metric.mock.ts b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/mocks/track_ui_metric.mock.ts new file mode 100644 index 0000000000000..016e259343285 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/mocks/track_ui_metric.mock.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. + */ + +jest.mock('../../../app/services/track_ui_metric', () => ({ + ...jest.requireActual('../../../app/services/track_ui_metric'), + trackUiMetric: jest.fn(), + trackUserRequest: (request: Promise) => { + return request.then(response => response); + }, +})); diff --git a/x-pack/plugins/cross_cluster_replication/public/app/app.js b/x-pack/plugins/cross_cluster_replication/public/app/app.tsx similarity index 90% rename from x-pack/plugins/cross_cluster_replication/public/app/app.js rename to x-pack/plugins/cross_cluster_replication/public/app/app.tsx index bdf8ff0e90ab9..1a5da373cf37f 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/app.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/app.tsx @@ -5,8 +5,7 @@ */ import React, { Component, Fragment } from 'react'; -import PropTypes from 'prop-types'; -import { Route, Switch, Redirect, withRouter } from 'react-router-dom'; +import { Route, Switch, Redirect, withRouter, RouteComponentProps } from 'react-router-dom'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -23,9 +22,11 @@ import { import { BASE_PATH } from '../../common/constants'; import { getFatalErrors } from './services/notifications'; import { SectionError } from './components'; -import routing from './services/routing'; +import { routing } from './services/routing'; +// @ts-ignore import { loadPermissions } from './services/api'; +// @ts-ignore import { CrossClusterReplicationHome, AutoFollowPatternAdd, @@ -34,16 +35,24 @@ import { FollowerIndexEdit, } from './sections'; -class AppComponent extends Component { - static propTypes = { - history: PropTypes.shape({ - push: PropTypes.func.isRequired, - createHref: PropTypes.func.isRequired, - }).isRequired, +interface AppProps { + history: { + push: any; + createHref: any; }; + location: any; +} + +interface AppState { + isFetchingPermissions: boolean; + fetchPermissionError: any; + hasPermission: boolean; + missingClusterPrivileges: any[]; +} - constructor(...args) { - super(...args); +class AppComponent extends Component { + constructor(props: any) { + super(props); this.registerRouter(); this.state = { @@ -54,18 +63,10 @@ class AppComponent extends Component { }; } - UNSAFE_componentWillMount() { - routing.userHasLeftApp = false; - } - componentDidMount() { this.checkPermissions(); } - componentWillUnmount() { - routing.userHasLeftApp = true; - } - async checkPermissions() { this.setState({ isFetchingPermissions: true, @@ -163,7 +164,6 @@ class AppComponent extends Component { { +export const renderApp = (element: Element, I18nContext: I18nStart['Context']): UnmountCallback => { render( @@ -20,6 +22,8 @@ export const renderReact = async (elem, I18nContext) => { , - elem + element ); + + return () => unmountComponentAtNode(element); }; diff --git a/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js index 4cd3617abd989..387d7817a0357 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.js @@ -12,7 +12,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiPageContent, EuiSpacer } from '@elastic/eui'; import { listBreadcrumb, editBreadcrumb, setBreadcrumbs } from '../../services/breadcrumbs'; -import routing from '../../services/routing'; +import { routing } from '../../services/routing'; import { AutoFollowPatternForm, AutoFollowPatternPageTitle, diff --git a/x-pack/plugins/cross_cluster_replication/public/app/sections/follower_index_edit/follower_index_edit.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/follower_index_edit/follower_index_edit.js index 21493602c12a7..22f9a7338384b 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/sections/follower_index_edit/follower_index_edit.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/follower_index_edit/follower_index_edit.js @@ -20,7 +20,7 @@ import { } from '@elastic/eui'; import { setBreadcrumbs, listBreadcrumb, editBreadcrumb } from '../../services/breadcrumbs'; -import routing from '../../services/routing'; +import { routing } from '../../services/routing'; import { FollowerIndexForm, FollowerIndexPageTitle, diff --git a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.js index e9e14f57e814f..c8cf94842aa68 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/auto_follow_pattern_list.js @@ -17,7 +17,7 @@ import { EuiSpacer, } from '@elastic/eui'; -import routing from '../../../services/routing'; +import { routing } from '../../../services/routing'; import { extractQueryParams } from '../../../services/query_params'; import { trackUiMetric, METRIC_TYPE } from '../../../services/track_ui_metric'; import { API_STATUS, UIM_AUTO_FOLLOW_PATTERN_LIST_LOAD } from '../../../constants'; diff --git a/x-pack/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/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.js index 956a9f10d810b..eb90e59e99fee 100644 --- a/x-pack/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/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/auto_follow_pattern_table/auto_follow_pattern_table.js @@ -20,8 +20,8 @@ import { AutoFollowPatternDeleteProvider, AutoFollowPatternActionMenu, } from '../../../../../components'; -import routing from '../../../../../services/routing'; -import { trackUiMetric, METRIC_TYPE } from '../../../../../services/track_ui_metric'; +import { routing } from '../../../../../services/routing'; +import { trackUiMetric } from '../../../../../services/track_ui_metric'; export class AutoFollowPatternTable extends PureComponent { static propTypes = { @@ -86,7 +86,7 @@ export class AutoFollowPatternTable extends PureComponent { return ( { - trackUiMetric(METRIC_TYPE.CLICK, UIM_AUTO_FOLLOW_PATTERN_SHOW_DETAILS_CLICK); + trackUiMetric('click', UIM_AUTO_FOLLOW_PATTERN_SHOW_DETAILS_CLICK); selectAutoFollowPattern(name); }} data-test-subj="autoFollowPatternLink" diff --git a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/context_menu/context_menu.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/context_menu/context_menu.js index 0f6ef75522ff7..4a66f7b717bac 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/context_menu/context_menu.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/context_menu/context_menu.js @@ -15,7 +15,7 @@ import { EuiPopoverTitle, } from '@elastic/eui'; -import routing from '../../../../../services/routing'; +import { routing } from '../../../../../services/routing'; import { FollowerIndexPauseProvider, FollowerIndexResumeProvider, diff --git a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/follower_indices_table/follower_indices_table.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/follower_indices_table/follower_indices_table.js index 60feac5ec8c6e..67f42fb622bf8 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/follower_indices_table/follower_indices_table.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/components/follower_indices_table/follower_indices_table.js @@ -22,8 +22,8 @@ import { FollowerIndexResumeProvider, FollowerIndexUnfollowProvider, } from '../../../../../components'; -import routing from '../../../../../services/routing'; -import { trackUiMetric, METRIC_TYPE } from '../../../../../services/track_ui_metric'; +import { routing } from '../../../../../services/routing'; +import { trackUiMetric } from '../../../../../services/track_ui_metric'; import { ContextMenu } from '../context_menu'; export class FollowerIndicesTable extends PureComponent { @@ -171,7 +171,7 @@ export class FollowerIndicesTable extends PureComponent { return ( { - trackUiMetric(METRIC_TYPE.CLICK, UIM_FOLLOWER_INDEX_SHOW_DETAILS_CLICK); + trackUiMetric('click', UIM_FOLLOWER_INDEX_SHOW_DETAILS_CLICK); selectFollowerIndex(name); }} data-test-subj="followerIndexLink" diff --git a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/follower_indices_list.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/follower_indices_list.js index b7e04721f4748..7b843d08cefd3 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/follower_indices_list.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/follower_indices_list/follower_indices_list.js @@ -17,7 +17,7 @@ import { EuiSpacer, } from '@elastic/eui'; -import routing from '../../../services/routing'; +import { routing } from '../../../services/routing'; import { extractQueryParams } from '../../../services/query_params'; import { trackUiMetric, METRIC_TYPE } from '../../../services/track_ui_metric'; import { API_STATUS, UIM_FOLLOWER_INDEX_LIST_LOAD } from '../../../constants'; diff --git a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/home.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/home.js index a8babd1f3995f..bcd9dad114862 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/home.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/home.js @@ -12,7 +12,7 @@ import { EuiPageBody, EuiPageContent, EuiSpacer, EuiTab, EuiTabs, EuiTitle } fro import { BASE_PATH } from '../../../../common/constants'; import { setBreadcrumbs, listBreadcrumb } from '../../services/breadcrumbs'; -import routing from '../../services/routing'; +import { routing } from '../../services/routing'; import { AutoFollowPatternList } from './auto_follow_pattern_list'; import { FollowerIndicesList } from './follower_indices_list'; diff --git a/x-pack/plugins/cross_cluster_replication/public/app/sections/index.d.ts b/x-pack/plugins/cross_cluster_replication/public/app/sections/index.d.ts new file mode 100644 index 0000000000000..b7c1f495604be --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/index.d.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. + */ + +export declare const CrossClusterReplicationHome: any; +export declare const AutoFollowPatternAdd: any; +export declare const AutoFollowPatternEdit: any; +export declare const FollowerIndexAdd: any; +export declare const FollowerIndexEdit: any; diff --git a/x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.ts b/x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.ts index 4f082d742ac5c..cea6e66943a39 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.ts +++ b/x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.ts @@ -3,6 +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 { i18n } from '@kbn/i18n'; import { ChromeBreadcrumb } from 'src/core/public'; @@ -10,19 +11,12 @@ import { ManagementAppMountParams } from '../../../../../../src/plugins/manageme 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]); - }; +type SetBreadcrumbs = ManagementAppMountParams['setBreadcrumbs']; + +let setBreadcrumbs: (crumbs: ChromeBreadcrumb[]) => void; + +export const init = (_setBreadcrumbs: SetBreadcrumbs): void => { + setBreadcrumbs = _setBreadcrumbs; }; export const listBreadcrumb = { diff --git a/x-pack/plugins/cross_cluster_replication/public/app/services/documentation_links.ts b/x-pack/plugins/cross_cluster_replication/public/app/services/documentation_links.ts index f17926d2bee10..c8b00f6e246b5 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/services/documentation_links.ts +++ b/x-pack/plugins/cross_cluster_replication/public/app/services/documentation_links.ts @@ -4,19 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -let esBase: string; +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 init = (esBase: string) => { + _esBase = esBase; }; -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`; +export const getAutoFollowPatternUrl = (): string => `${_esBase}/ccr-put-auto-follow-pattern.html`; +export const getFollowerIndexUrl = (): string => `${_esBase}/ccr-put-follow.html`; +export const getByteUnitsUrl = (): string => `${_esBase}/common-options.html#byte-units`; +export const getTimeUnitsUrl = (): string => `${_esBase}/common-options.html#time-units`; diff --git a/x-pack/plugins/cross_cluster_replication/public/app/services/notifications.ts b/x-pack/plugins/cross_cluster_replication/public/app/services/notifications.ts index 5e1c3e9e99437..66fc9de00995c 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/services/notifications.ts +++ b/x-pack/plugins/cross_cluster_replication/public/app/services/notifications.ts @@ -3,18 +3,16 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { NotificationsSetup, IToasts, FatalErrorsSetup } from 'src/core/public'; -let _notifications: IToasts; +import { IToasts, FatalErrorsSetup } from 'src/core/public'; + +let _toasts: IToasts; let _fatalErrors: FatalErrorsSetup; -export const setNotifications = ( - notifications: NotificationsSetup, - fatalErrorsSetup: FatalErrorsSetup -) => { - _notifications = notifications.toasts; - _fatalErrors = fatalErrorsSetup; +export const init = (toasts: IToasts, fatalErrors: FatalErrorsSetup) => { + _toasts = toasts; + _fatalErrors = fatalErrors; }; -export const getNotifications = () => _notifications; +export const getToasts = () => _toasts; export const getFatalErrors = () => _fatalErrors; diff --git a/x-pack/plugins/cross_cluster_replication/public/index.js b/x-pack/plugins/cross_cluster_replication/public/app/services/routing.d.ts similarity index 87% rename from x-pack/plugins/cross_cluster_replication/public/index.js rename to x-pack/plugins/cross_cluster_replication/public/app/services/routing.d.ts index e92c44da34474..9e96ea12856f6 100644 --- a/x-pack/plugins/cross_cluster_replication/public/index.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/services/routing.d.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -import './register_routes'; +export declare const routing: any; diff --git a/x-pack/plugins/cross_cluster_replication/public/app/services/routing.js b/x-pack/plugins/cross_cluster_replication/public/app/services/routing.js index 487b1068794f9..124c61e1ba19e 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/services/routing.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/services/routing.js @@ -32,7 +32,6 @@ const appToBasePathMap = { }; class Routing { - _userHasLeftApp = false; _reactRouter = null; /** @@ -97,14 +96,6 @@ class Routing { set reactRouter(router) { this._reactRouter = router; } - - get userHasLeftApp() { - return this._userHasLeftApp; - } - - set userHasLeftApp(hasLeft) { - this._userHasLeftApp = hasLeft; - } } -export default new Routing(); +export const routing = new Routing(); diff --git a/x-pack/plugins/cross_cluster_replication/public/app/services/track_ui_metric.js b/x-pack/plugins/cross_cluster_replication/public/app/services/track_ui_metric.ts similarity index 50% rename from x-pack/plugins/cross_cluster_replication/public/app/services/track_ui_metric.js rename to x-pack/plugins/cross_cluster_replication/public/app/services/track_ui_metric.ts index d3effd1dd7e16..010155a2730ad 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/services/track_ui_metric.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/services/track_ui_metric.ts @@ -4,22 +4,31 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - createUiStatsReporter, - METRIC_TYPE, -} from '../../../../../../src/legacy/core_plugins/ui_metric/public'; +import { UsageCollectionSetup } from 'src/plugins/usage_collection/public'; +import { UiStatsMetricType, METRIC_TYPE } from '@kbn/analytics'; + import { UIM_APP_NAME } from '../constants'; -export const trackUiMetric = createUiStatsReporter(UIM_APP_NAME); export { METRIC_TYPE }; + +export let trackUiMetric: (metricType: UiStatsMetricType, eventName: string) => void; + +export function init(usageCollection: UsageCollectionSetup): void { + trackUiMetric = usageCollection.reportUiStats.bind(usageCollection, UIM_APP_NAME); +} + /** * Transparently return provided request Promise, while allowing us to track * a successful completion of the request. */ -export function trackUserRequest(request, actionType) { +export function trackUserRequest(request: Promise, actionType: string) { // Only track successful actions. return request.then(response => { + // It looks like we're using the wrong type here, added via + // https://github.com/elastic/kibana/pull/41113/files#diff-e65a0a6696a9d723969afd871cbd60cdR19 + // but we'll keep it for now to avoid discontinuity in our telemetry data. trackUiMetric(METRIC_TYPE.LOADED, actionType); + // We return the response immediately without waiting for the tracking request to resolve, // to avoid adding additional latency. return response; diff --git a/x-pack/plugins/cross_cluster_replication/public/app/store/actions/auto_follow_pattern.js b/x-pack/plugins/cross_cluster_replication/public/app/store/actions/auto_follow_pattern.js index b81cd30f3977a..52a22cb17d0a9 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/store/actions/auto_follow_pattern.js +++ b/x-pack/plugins/cross_cluster_replication/public/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 { getNotifications } from '../../services/notifications'; +import { getToasts } from '../../services/notifications'; import { SECTIONS, API_STATUS } from '../../constants'; import { loadAutoFollowPatterns as loadAutoFollowPatternsRequest, @@ -15,7 +15,7 @@ import { pauseAutoFollowPattern as pauseAutoFollowPatternRequest, resumeAutoFollowPattern as resumeAutoFollowPatternRequest, } from '../../services/api'; -import routing from '../../services/routing'; +import { routing } from '../../services/routing'; import * as t from '../action_types'; import { sendApiRequest } from './api'; import { getSelectedAutoFollowPatternId } from '../selectors'; @@ -75,7 +75,7 @@ export const saveAutoFollowPattern = (id, autoFollowPattern, isUpdating = false) } ); - getNotifications().addSuccess(successMessage); + getToasts().addSuccess(successMessage); routing.navigate(`/auto_follow_patterns`, undefined, { pattern: encodeURIComponent(id), }); @@ -111,7 +111,7 @@ export const deleteAutoFollowPattern = id => } ); - getNotifications().addDanger(errorMessage); + getToasts().addDanger(errorMessage); } if (response.itemsDeleted.length) { @@ -133,7 +133,7 @@ export const deleteAutoFollowPattern = id => } ); - getNotifications().addSuccess(successMessage); + getToasts().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 => } ); - getNotifications().addDanger(errorMessage); + getToasts().addDanger(errorMessage); } if (response.itemsPaused.length) { @@ -195,7 +195,7 @@ export const pauseAutoFollowPattern = id => } ); - getNotifications().addSuccess(successMessage); + getToasts().addSuccess(successMessage); } }, }); @@ -229,7 +229,7 @@ export const resumeAutoFollowPattern = id => } ); - getNotifications().addDanger(errorMessage); + getToasts().addDanger(errorMessage); } if (response.itemsResumed.length) { @@ -251,7 +251,7 @@ export const resumeAutoFollowPattern = id => } ); - getNotifications().addSuccess(successMessage); + getToasts().addSuccess(successMessage); } }, }); diff --git a/x-pack/plugins/cross_cluster_replication/public/app/store/actions/follower_index.js b/x-pack/plugins/cross_cluster_replication/public/app/store/actions/follower_index.js index ebdee067ced75..b6c0bb5ce401d 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/store/actions/follower_index.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/store/actions/follower_index.js @@ -5,8 +5,8 @@ */ import { i18n } from '@kbn/i18n'; -import routing from '../../services/routing'; -import { getNotifications } from '../../services/notifications'; +import { routing } from '../../services/routing'; +import { getToasts } from '../../services/notifications'; import { SECTIONS, API_STATUS } from '../../constants'; import { loadFollowerIndices as loadFollowerIndicesRequest, @@ -76,7 +76,7 @@ export const saveFollowerIndex = (name, followerIndex, isUpdating = false) => } ); - getNotifications().addSuccess(successMessage); + getToasts().addSuccess(successMessage); routing.navigate(`/follower_indices`, undefined, { name: encodeURIComponent(name), }); @@ -112,7 +112,7 @@ export const pauseFollowerIndex = id => } ); - getNotifications().addDanger(errorMessage); + getToasts().addDanger(errorMessage); } if (response.itemsPaused.length) { @@ -134,7 +134,7 @@ export const pauseFollowerIndex = id => } ); - getNotifications().addSuccess(successMessage); + getToasts().addSuccess(successMessage); // Refresh list dispatch(loadFollowerIndices(true)); @@ -171,7 +171,7 @@ export const resumeFollowerIndex = id => } ); - getNotifications().addDanger(errorMessage); + getToasts().addDanger(errorMessage); } if (response.itemsResumed.length) { @@ -193,7 +193,7 @@ export const resumeFollowerIndex = id => } ); - getNotifications().addSuccess(successMessage); + getToasts().addSuccess(successMessage); } // Refresh list @@ -230,7 +230,7 @@ export const unfollowLeaderIndex = id => } ); - getNotifications().addDanger(errorMessage); + getToasts().addDanger(errorMessage); } if (response.itemsUnfollowed.length) { @@ -252,7 +252,7 @@ export const unfollowLeaderIndex = id => } ); - getNotifications().addSuccess(successMessage); + getToasts().addSuccess(successMessage); } if (response.itemsNotOpen.length) { @@ -274,7 +274,7 @@ export const unfollowLeaderIndex = id => } ); - getNotifications().addWarning(warningMessage); + getToasts().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/plugins/cross_cluster_replication/public/app/store/index.d.ts b/x-pack/plugins/cross_cluster_replication/public/app/store/index.d.ts new file mode 100644 index 0000000000000..6d35dfeddfd46 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/public/app/store/index.d.ts @@ -0,0 +1,7 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +export declare const ccrStore: any; diff --git a/x-pack/plugins/cross_cluster_replication/public/extend_index_management.ts b/x-pack/plugins/cross_cluster_replication/public/extend_index_management.ts deleted file mode 100644 index 7bf4c4744a55a..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/public/extend_index_management.ts +++ /dev/null @@ -1,29 +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 { i18n } from '@kbn/i18n'; -import { get } from 'lodash'; - -import { IndexManagementPluginSetup } from '../../index_management/public'; - -const propertyPath = 'isFollowerIndex'; - -const followerBadgeExtension = { - matchIndex: (index: any) => { - return get(index, propertyPath); - }, - label: i18n.translate('xpack.crossClusterReplication.indexMgmtBadge.followerLabel', { - defaultMessage: 'Follower', - }), - color: 'default', - filterExpression: 'isFollowerIndex:true', -}; - -export const extendIndexManagement = (indexManagement?: IndexManagementPluginSetup) => { - if (indexManagement) { - indexManagement.extensionsService.addBadge(followerBadgeExtension); - } -}; diff --git a/x-pack/plugins/cross_cluster_replication/public/index.scss b/x-pack/plugins/cross_cluster_replication/public/index.scss index 31317e16e3e9f..8590c89708495 100644 --- a/x-pack/plugins/cross_cluster_replication/public/index.scss +++ b/x-pack/plugins/cross_cluster_replication/public/index.scss @@ -1,6 +1,3 @@ -// Import the EUI global scope so we can use EUI constants -@import 'src/legacy/ui/public/styles/_styling_constants'; - // Cross-Cluster Replication plugin styles // Prefix all styles with "ccr" to avoid conflicts. @@ -10,4 +7,4 @@ // ccrChart__legend--small // ccrChart__legend-isLoading -@import 'np_ready/app/app'; +@import 'app/app'; diff --git a/x-pack/plugins/cross_cluster_replication/public/index.ts b/x-pack/plugins/cross_cluster_replication/public/index.ts index 11aea6b7b5de4..e3e2d860e526d 100644 --- a/x-pack/plugins/cross_cluster_replication/public/index.ts +++ b/x-pack/plugins/cross_cluster_replication/public/index.ts @@ -6,6 +6,7 @@ import { PluginInitializerContext } from 'src/core/public'; -import { CrossClusterReplicationUIPlugin } from './plugin'; +import { CrossClusterReplicationPlugin } from './plugin'; -export const plugin = (ctx: PluginInitializerContext) => new CrossClusterReplicationUIPlugin(ctx); +export const plugin = (initializerContext: PluginInitializerContext) => + new CrossClusterReplicationPlugin(initializerContext); diff --git a/x-pack/plugins/cross_cluster_replication/public/main.html b/x-pack/plugins/cross_cluster_replication/public/main.html deleted file mode 100644 index 2129f26267827..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/public/main.html +++ /dev/null @@ -1,3 +0,0 @@ - -
-
diff --git a/x-pack/plugins/cross_cluster_replication/public/plugin.ts b/x-pack/plugins/cross_cluster_replication/public/plugin.ts index 3ea995f1c31be..05124eed8ec3d 100644 --- a/x-pack/plugins/cross_cluster_replication/public/plugin.ts +++ b/x-pack/plugins/cross_cluster_replication/public/plugin.ts @@ -4,42 +4,92 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - ChromeBreadcrumb, - CoreSetup, - Plugin, - PluginInitializerContext, - DocLinksStart, -} from 'src/core/public'; +import { i18n } from '@kbn/i18n'; +import { get } from 'lodash'; +import { first } from 'rxjs/operators'; +import { CoreSetup, Plugin, PluginInitializerContext } from 'src/core/public'; -import { IndexManagementPluginSetup } from '../../index_management/public'; +import { PLUGIN } from '../common/constants'; +import { init as initBreadcrumbs } from './app/services/breadcrumbs'; +import { init as initDocumentation } from './app/services/documentation_links'; +import { init as initUiMetric } from './app/services/track_ui_metric'; +import { init as initNotification } from './app/services/notifications'; +import { PluginDependencies, ClientConfigType } from './types'; // @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: IndexManagementPluginSetup; - __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); +export class CrossClusterReplicationPlugin implements Plugin { + constructor(private readonly initializerContext: PluginInitializerContext) {} + + public setup(coreSetup: CoreSetup, plugins: PluginDependencies) { + plugins.licensing.license$ + .pipe(first()) + .toPromise() + .then(license => { + const isLicenseOk = license.isAvailable && license.isActive; + + const { + ui: { enabled: isCcrUiEnabled }, + } = this.initializerContext.config.get(); + + if (isLicenseOk && isCcrUiEnabled) { + const { + http, + notifications: { toasts }, + fatalErrors, + getStartServices, + } = coreSetup; + + const { usageCollection, management, indexManagement } = plugins; + + // Initialize services even if the app isn't mounted, because they're used by index management extensions. + setHttpClient(http); + initUiMetric(usageCollection); + initNotification(toasts, fatalErrors); + + management.sections.getSection('elasticsearch')!.registerApp({ + id: PLUGIN.ID, + title: PLUGIN.TITLE, + order: 4, + mount: async ({ element, setBreadcrumbs }) => { + const [coreStart] = await getStartServices(); + const { + i18n: { Context: I18nContext }, + docLinks: { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }, + } = coreStart; + + // Initialize additional services. + initBreadcrumbs(setBreadcrumbs); + initDocumentation( + `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/` + ); + + const { renderApp } = await import('./app'); + return renderApp(element, I18nContext); + }, + }); + + if (indexManagement) { + const propertyPath = 'isFollowerIndex'; + + const followerBadgeExtension = { + matchIndex: (index: any) => { + return get(index, propertyPath); + }, + label: i18n.translate('xpack.crossClusterReplication.indexMgmtBadge.followerLabel', { + defaultMessage: 'Follower', + }), + color: 'default', + filterExpression: 'isFollowerIndex:true', + }; + + indexManagement.extensionsService.addBadge(followerBadgeExtension); + } + } + }); } - start() {} + public start() {} + public stop() {} } diff --git a/x-pack/plugins/cross_cluster_replication/public/register_routes.js b/x-pack/plugins/cross_cluster_replication/public/register_routes.js deleted file mode 100644 index 055cfd229183b..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/public/register_routes.js +++ /dev/null @@ -1,94 +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 { unmountComponentAtNode } from 'react-dom'; -import chrome from 'ui/chrome'; -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 { plugin } from './index'; - -/** - * TODO: When this file is deleted, use the management section for rendering - */ -import { renderReact } from './app'; - -const isAvailable = xpackInfo.get('features.crossClusterReplication.isAvailable'); -const isActive = xpackInfo.get('features.crossClusterReplication.isActive'); -const isLicenseOK = isAvailable && isActive; -const isCcrUiEnabled = chrome.getInjected('ccrUiEnabled'); - -if (isLicenseOK && isCcrUiEnabled) { - const esSection = management.getSection('elasticsearch'); - - esSection.register('ccr', { - visible: true, - display: i18n.translate('xpack.crossClusterReplication.appTitle', { - defaultMessage: 'Cross-Cluster Replication', - }), - order: 4, - url: `#${BASE_PATH}`, - }); - - let elem; - - 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) { - // 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(); - - $scope.$$postDigest(() => { - elem = document.getElementById(CCR_REACT_ROOT); - renderReact(elem, npStart.core.i18n.Context); - - // Angular Lifecycle - const appRoute = $route.current; - const stopListeningForLocationChange = $scope.$on('$locationChangeSuccess', () => { - const currentRoute = $route.current; - const isNavigationInApp = currentRoute.$$route.template === appRoute.$$route.template; - - // When we navigate within CCR, prevent Angular from re-matching the route and rebuild the app - if (isNavigationInApp) { - $route.current = appRoute; - } else { - // Any clean up when User leaves the CCR - } - - $scope.$on('$destroy', () => { - stopListeningForLocationChange && stopListeningForLocationChange(); - unmountReactApp(); - }); - }); - }); - } - }, - }); -} diff --git a/x-pack/plugins/cross_cluster_replication/public/types.ts b/x-pack/plugins/cross_cluster_replication/public/types.ts new file mode 100644 index 0000000000000..8645541cdbd84 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/public/types.ts @@ -0,0 +1,23 @@ +/* + * 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 { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public'; +import { ManagementSetup } from '../../../../src/plugins/management/public'; +import { IndexManagementPluginSetup } from '../../index_management/public'; +import { LicensingPluginSetup } from '../../licensing/public'; + +export interface PluginDependencies { + usageCollection: UsageCollectionSetup; + management: ManagementSetup; + indexManagement: IndexManagementPluginSetup; + licensing: LicensingPluginSetup; +} + +export interface ClientConfigType { + ui: { + enabled: boolean; + }; +} diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/notification.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/notification.ts index 7d24bc31006b4..aa3ac9ea75c22 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/notification.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/services/notification.ts @@ -4,10 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -export let toasts: any; -export let fatalErrors: any; +import { IToasts, FatalErrorsSetup } from 'src/core/public'; -export function init(_toasts: any, _fatalErrors: any): void { +export let toasts: IToasts; +export let fatalErrors: FatalErrorsSetup; + +export function init(_toasts: IToasts, _fatalErrors: FatalErrorsSetup): void { toasts = _toasts; fatalErrors = _fatalErrors; } From f6adfafc9819eea73aef4e4825c1ddc71a8716e5 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Mon, 13 Apr 2020 21:48:23 -0700 Subject: [PATCH 06/20] Update API unit tests to use NP mocks. - Break up test files. - Use inline mocked ES response instead of fixture files. - Move remaining fixture files into client integration tests directory. - Fix type errors and update service unit tests. --- .../follower_index_serialization.test.ts.snap | 20 +- .../follower_index_serialization.test.ts | 63 ++-- .../cross_cluster_replication/common/types.ts | 20 +- .../fixtures/auto_follow_pattern.js | 49 --- .../fixtures/es_errors.js | 45 --- .../fixtures/follower_index.js | 216 ------------ .../fixtures/index.js | 16 - .../auto_follow_pattern_list.test.js | 6 +- .../fixtures/auto_follow_pattern.ts | 28 ++ .../fixtures/follower_index.ts | 70 ++++ .../follower_indices_list.test.js | 2 +- .../api/__jest__/auto_follow_pattern.test.js | 321 ------------------ .../api/__jest__/follower_index.test.js | 303 ----------------- .../server/routes/api/__jest__/helpers.ts | 36 -- .../register_create_route.test.ts | 84 +++++ .../register_create_route.ts | 2 +- .../register_delete_route.test.ts | 101 ++++++ .../register_fetch_route.test.ts | 75 ++++ .../register_get_route.test.ts | 73 ++++ .../register_pause_route.test.ts | 100 ++++++ .../register_resume_route.test.ts | 100 ++++++ .../register_update_route.test.ts | 70 ++++ .../register_create_route.test.ts | 60 ++++ .../register_fetch_route.test.ts | 166 +++++++++ .../follower_index/register_get_route.test.ts | 165 +++++++++ .../register_pause_route.test.ts | 100 ++++++ .../register_resume_route.test.ts | 100 ++++++ .../register_unfollow_route.test.ts | 123 +++++++ .../auto_follow_pattern.js | 1 - .../follower_indices.js | 2 +- 30 files changed, 1474 insertions(+), 1043 deletions(-) delete mode 100644 x-pack/plugins/cross_cluster_replication/fixtures/auto_follow_pattern.js delete mode 100644 x-pack/plugins/cross_cluster_replication/fixtures/es_errors.js delete mode 100644 x-pack/plugins/cross_cluster_replication/fixtures/follower_index.js delete mode 100644 x-pack/plugins/cross_cluster_replication/fixtures/index.js create mode 100644 x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/fixtures/auto_follow_pattern.ts create mode 100644 x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/fixtures/follower_index.ts delete mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/auto_follow_pattern.test.js delete mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/follower_index.test.js delete mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/helpers.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.test.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.test.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.test.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.test.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.test.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.test.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.test.ts create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.test.ts diff --git a/x-pack/plugins/cross_cluster_replication/common/services/__snapshots__/follower_index_serialization.test.ts.snap b/x-pack/plugins/cross_cluster_replication/common/services/__snapshots__/follower_index_serialization.test.ts.snap index 923162f934016..c20556fe1434d 100644 --- a/x-pack/plugins/cross_cluster_replication/common/services/__snapshots__/follower_index_serialization.test.ts.snap +++ b/x-pack/plugins/cross_cluster_replication/common/services/__snapshots__/follower_index_serialization.test.ts.snap @@ -6,14 +6,14 @@ Object { "maxOutstandingReadRequests": 1, "maxOutstandingWriteRequests": 1, "maxReadRequestOperationCount": 1, - "maxReadRequestSize": 1, - "maxRetryDelay": 1, + "maxReadRequestSize": "1b", + "maxRetryDelay": "1s", "maxWriteBufferCount": 1, - "maxWriteBufferSize": 1, + "maxWriteBufferSize": "1b", "maxWriteRequestOperationCount": 1, - "maxWriteRequestSize": 1, + "maxWriteRequestSize": "1b", "name": "follower index 1", - "readPollTimeout": 1, + "readPollTimeout": "1s", "remoteCluster": "cluster 1", "shards": Array [ Object { @@ -116,13 +116,13 @@ Object { "max_outstanding_read_requests": 1, "max_outstanding_write_requests": 1, "max_read_request_operation_count": 1, - "max_read_request_size": 1, - "max_retry_delay": 1, + "max_read_request_size": "1b", + "max_retry_delay": "1s", "max_write_buffer_count": 1, - "max_write_buffer_size": 1, + "max_write_buffer_size": "1b", "max_write_request_operation_count": 1, - "max_write_request_size": 1, - "read_poll_timeout": 1, + "max_write_request_size": "1b", + "read_poll_timeout": "1s", "remote_cluster": "remote cluster", } `; diff --git a/x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.test.ts b/x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.test.ts index 8562750f31970..bfe3e1b3443e6 100644 --- a/x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.test.ts +++ b/x-pack/plugins/cross_cluster_replication/common/services/follower_index_serialization.test.ts @@ -59,14 +59,14 @@ describe('[CCR] follower index serialization', () => { parameters: { max_read_request_operation_count: 1, max_outstanding_read_requests: 1, - max_read_request_size: 1, + max_read_request_size: '1b', max_write_request_operation_count: 1, - max_write_request_size: 1, + max_write_request_size: '1b', max_outstanding_write_requests: 1, max_write_buffer_count: 1, - max_write_buffer_size: 1, - max_retry_delay: 1, - read_poll_timeout: 1, + max_write_buffer_size: '1b', + max_retry_delay: '1s', + read_poll_timeout: '1s', }, shards: [ { @@ -123,14 +123,14 @@ describe('[CCR] follower index serialization', () => { parameters: { max_read_request_operation_count: 1, max_outstanding_read_requests: 1, - max_read_request_size: 1, + max_read_request_size: '1b', max_write_request_operation_count: 1, - max_write_request_size: 1, + max_write_request_size: '1b', max_outstanding_write_requests: 1, max_write_buffer_count: 1, - max_write_buffer_size: 1, - max_retry_delay: 1, - read_poll_timeout: 1, + max_write_buffer_size: '1b', + max_retry_delay: '1s', + read_poll_timeout: '1s', }, shards: [], }, @@ -142,14 +142,14 @@ describe('[CCR] follower index serialization', () => { parameters: { max_read_request_operation_count: 2, max_outstanding_read_requests: 2, - max_read_request_size: 2, + max_read_request_size: '2b', max_write_request_operation_count: 2, - max_write_request_size: 2, + max_write_request_size: '2b', max_outstanding_write_requests: 2, max_write_buffer_count: 2, - max_write_buffer_size: 2, - max_retry_delay: 2, - read_poll_timeout: 2, + max_write_buffer_size: '2b', + max_retry_delay: '2s', + read_poll_timeout: '2s', }, shards: [], }, @@ -163,14 +163,14 @@ describe('[CCR] follower index serialization', () => { status: 'active', maxReadRequestOperationCount: 1, maxOutstandingReadRequests: 1, - maxReadRequestSize: 1, + maxReadRequestSize: '1b', maxWriteRequestOperationCount: 1, - maxWriteRequestSize: 1, + maxWriteRequestSize: '1b', maxOutstandingWriteRequests: 1, maxWriteBufferCount: 1, - maxWriteBufferSize: 1, - maxRetryDelay: 1, - readPollTimeout: 1, + maxWriteBufferSize: '1b', + maxRetryDelay: '1s', + readPollTimeout: '1s', shards: [], }, { @@ -180,14 +180,14 @@ describe('[CCR] follower index serialization', () => { status: 'paused', maxReadRequestOperationCount: 2, maxOutstandingReadRequests: 2, - maxReadRequestSize: 2, + maxReadRequestSize: '2b', maxWriteRequestOperationCount: 2, - maxWriteRequestSize: 2, + maxWriteRequestSize: '2b', maxOutstandingWriteRequests: 2, maxWriteBufferCount: 2, - maxWriteBufferSize: 2, - maxRetryDelay: 2, - readPollTimeout: 2, + maxWriteBufferSize: '2b', + maxRetryDelay: '2s', + readPollTimeout: '2s', shards: [], }, ]; @@ -201,18 +201,21 @@ describe('[CCR] follower index serialization', () => { describe('serializeFollowerIndex()', () => { it('serializes object to Elasticsearch follower index object', () => { const deserializedFollowerIndex = { + name: 'test', + status: 'active', + shards: [], remoteCluster: 'remote cluster', leaderIndex: 'leader index', maxReadRequestOperationCount: 1, maxOutstandingReadRequests: 1, - maxReadRequestSize: 1, + maxReadRequestSize: '1b', maxWriteRequestOperationCount: 1, - maxWriteRequestSize: 1, + maxWriteRequestSize: '1b', maxOutstandingWriteRequests: 1, maxWriteBufferCount: 1, - maxWriteBufferSize: 1, - maxRetryDelay: 1, - readPollTimeout: 1, + maxWriteBufferSize: '1b', + maxRetryDelay: '1s', + readPollTimeout: '1s', }; expect(serializeFollowerIndex(deserializedFollowerIndex as FollowerIndex)).toMatchSnapshot(); diff --git a/x-pack/plugins/cross_cluster_replication/common/types.ts b/x-pack/plugins/cross_cluster_replication/common/types.ts index 5f3e15e0514b3..0cfaf729c9f39 100644 --- a/x-pack/plugins/cross_cluster_replication/common/types.ts +++ b/x-pack/plugins/cross_cluster_replication/common/types.ts @@ -116,27 +116,27 @@ export interface FollowerIndexToEs extends FollowerIndexAdvancedSettingsToEs { export interface FollowerIndexAdvancedSettings { maxReadRequestOperationCount?: number; maxOutstandingReadRequests?: number; - maxReadRequestSize?: number; + maxReadRequestSize?: string; // byte value maxWriteRequestOperationCount?: number; - maxWriteRequestSize?: number; + maxWriteRequestSize?: string; // byte value maxOutstandingWriteRequests?: number; maxWriteBufferCount?: number; - maxWriteBufferSize?: number; - maxRetryDelay?: number; - readPollTimeout?: number; + maxWriteBufferSize?: string; // byte value + maxRetryDelay?: string; // time value + readPollTimeout?: string; // time value } export interface FollowerIndexAdvancedSettingsToEs { max_read_request_operation_count?: number; max_outstanding_read_requests?: number; - max_read_request_size?: number; + max_read_request_size?: string; // byte value max_write_request_operation_count?: number; - max_write_request_size?: number; + max_write_request_size?: string; // byte value max_outstanding_write_requests?: number; max_write_buffer_count?: number; - max_write_buffer_size?: number; - max_retry_delay?: number; - read_poll_timeout?: number; + max_write_buffer_size?: string; // byte value + max_retry_delay?: string; // time value + read_poll_timeout?: string; // time value } export interface RecentAutoFollowError { diff --git a/x-pack/plugins/cross_cluster_replication/fixtures/auto_follow_pattern.js b/x-pack/plugins/cross_cluster_replication/fixtures/auto_follow_pattern.js deleted file mode 100644 index a5e9a636b4c04..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/fixtures/auto_follow_pattern.js +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { getRandomString } from '../../../test_utils'; - -export const getAutoFollowPatternMock = ( - name = getRandomString(), - remoteCluster = getRandomString(), - leaderIndexPatterns = [getRandomString()], - followIndexPattern = getRandomString() -) => ({ - name, - pattern: { - remote_cluster: remoteCluster, - leader_index_patterns: leaderIndexPatterns, - follow_index_pattern: followIndexPattern, - }, -}); - -export const getAutoFollowPatternListMock = (total = 3) => { - const list = { - patterns: [], - }; - - let i = total; - while (i--) { - list.patterns.push(getAutoFollowPatternMock()); - } - - return list; -}; - -// ----------------- -// Client test mock -// ----------------- -export const getAutoFollowPatternClientMock = ({ - name = getRandomString(), - remoteCluster = getRandomString(), - leaderIndexPatterns = [`${getRandomString()}-*`], - followIndexPattern = getRandomString(), -}) => ({ - name, - remoteCluster, - leaderIndexPatterns, - followIndexPattern, -}); diff --git a/x-pack/plugins/cross_cluster_replication/fixtures/es_errors.js b/x-pack/plugins/cross_cluster_replication/fixtures/es_errors.js deleted file mode 100644 index a042375e82715..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/fixtures/es_errors.js +++ /dev/null @@ -1,45 +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. - */ - -/** - * Errors mocks to throw during development to help visualizing - * the different flows in the UI - * - * TODO: Consult the ES team and make sure the error shapes are correct - * for each statusCode. - */ - -const error400 = new Error('Something went wrong'); -error400.statusCode = 400; -error400.response = ` - { - "error": { - "root_cause": [ - { - "type": "x_content_parse_exception", - "reason": "[2:3] [put_auto_follow_pattern_request] unknown field [remote_clusterxxxxx], parser not found" - } - ], - "type": "x_content_parse_exception", - "reason": "[2:3] [put_auto_follow_pattern_request] unknown field [remote_clusterxxxxx], parser not found" - }, - "status": 400 -}`; - -const error403 = new Error('Unauthorized'); -error403.statusCode = 403; -error403.response = ` - { - "acknowledged": true, - "trial_was_started": false, - "error_message": "Operation failed: Trial was already activated." - } -`; - -export const esErrors = { - 400: error400, - 403: error403, -}; diff --git a/x-pack/plugins/cross_cluster_replication/fixtures/follower_index.js b/x-pack/plugins/cross_cluster_replication/fixtures/follower_index.js deleted file mode 100644 index d02689beef657..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/fixtures/follower_index.js +++ /dev/null @@ -1,216 +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. - */ - -const Chance = require('chance'); // eslint-disable-line import/no-extraneous-dependencies -const chance = new Chance(); -import { getRandomString } from '../../../test_utils'; - -const serializeShard = ({ - id, - remoteCluster, - leaderIndex, - leaderGlobalCheckpoint, - leaderMaxSequenceNum, - followerGlobalCheckpoint, - followerMaxSequenceNum, - lastRequestedSequenceNum, - outstandingReadRequestsCount, - outstandingWriteRequestsCount, - writeBufferOperationsCount, - writeBufferSizeBytes, - followerMappingVersion, - followerSettingsVersion, - totalReadTimeMs, - totalReadRemoteExecTimeMs, - successfulReadRequestCount, - failedReadRequestsCount, - operationsReadCount, - bytesReadCount, - totalWriteTimeMs, - successfulWriteRequestsCount, - failedWriteRequestsCount, - operationsWrittenCount, - readExceptions, - timeSinceLastReadMs, -}) => ({ - shard_id: id, - remote_cluster: remoteCluster, - leader_index: leaderIndex, - leader_global_checkpoint: leaderGlobalCheckpoint, - leader_max_seq_no: leaderMaxSequenceNum, - follower_global_checkpoint: followerGlobalCheckpoint, - follower_max_seq_no: followerMaxSequenceNum, - last_requested_seq_no: lastRequestedSequenceNum, - outstanding_read_requests: outstandingReadRequestsCount, - outstanding_write_requests: outstandingWriteRequestsCount, - write_buffer_operation_count: writeBufferOperationsCount, - write_buffer_size_in_bytes: writeBufferSizeBytes, - follower_mapping_version: followerMappingVersion, - follower_settings_version: followerSettingsVersion, - total_read_time_millis: totalReadTimeMs, - total_read_remote_exec_time_millis: totalReadRemoteExecTimeMs, - successful_read_requests: successfulReadRequestCount, - failed_read_requests: failedReadRequestsCount, - operations_read: operationsReadCount, - bytes_read: bytesReadCount, - total_write_time_millis: totalWriteTimeMs, - successful_write_requests: successfulWriteRequestsCount, - failed_write_requests: failedWriteRequestsCount, - operations_written: operationsWrittenCount, - read_exceptions: readExceptions, - time_since_last_read_millis: timeSinceLastReadMs, -}); - -export const getFollowerIndexStatsMock = ( - name = chance.string(), - shards = [ - { - id: chance.string(), - remoteCluster: chance.string(), - leaderIndex: chance.string(), - leaderGlobalCheckpoint: chance.integer(), - leaderMaxSequenceNum: chance.integer(), - followerGlobalCheckpoint: chance.integer(), - followerMaxSequenceNum: chance.integer(), - lastRequestedSequenceNum: chance.integer(), - outstandingReadRequestsCount: chance.integer(), - outstandingWriteRequestsCount: chance.integer(), - writeBufferOperationsCount: chance.integer(), - writeBufferSizeBytes: chance.integer(), - followerMappingVersion: chance.integer(), - followerSettingsVersion: chance.integer(), - totalReadTimeMs: chance.integer(), - totalReadRemoteExecTimeMs: chance.integer(), - successfulReadRequestCount: chance.integer(), - failedReadRequestsCount: chance.integer(), - operationsReadCount: chance.integer(), - bytesReadCount: chance.integer(), - totalWriteTimeMs: chance.integer(), - successfulWriteRequestsCount: chance.integer(), - failedWriteRequestsCount: chance.integer(), - operationsWrittenCount: chance.integer(), - readExceptions: [chance.string()], - timeSinceLastReadMs: chance.integer(), - }, - ] -) => ({ - index: name, - shards: shards.map(serializeShard), -}); - -export const getFollowerIndexListStatsMock = (total = 3, names) => { - const list = { - follow_stats: { - indices: [], - }, - }; - - for (let i = 0; i < total; i++) { - list.follow_stats.indices.push(getFollowerIndexStatsMock(names[i])); - } - - return list; -}; - -export const getFollowerIndexInfoMock = ( - name = chance.string(), - status = chance.string(), - parameters = { - maxReadRequestOperationCount: chance.string(), - maxOutstandingReadRequests: chance.string(), - maxReadRequestSize: chance.string(), - maxWriteRequestOperationCount: chance.string(), - maxWriteRequestSize: chance.string(), - maxOutstandingWriteRequests: chance.string(), - maxWriteBufferCount: chance.string(), - maxWriteBufferSize: chance.string(), - maxRetryDelay: chance.string(), - readPollTimeout: chance.string(), - } -) => { - return { - follower_index: name, - status, - max_read_request_operation_count: parameters.maxReadRequestOperationCount, - max_outstanding_read_requests: parameters.maxOutstandingReadRequests, - max_read_request_size: parameters.maxReadRequestSize, - max_write_request_operation_count: parameters.maxWriteRequestOperationCount, - max_write_request_size: parameters.maxWriteRequestSize, - max_outstanding_write_requests: parameters.maxOutstandingWriteRequests, - max_write_buffer_count: parameters.maxWriteBufferCount, - max_write_buffer_size: parameters.maxWriteBufferSize, - max_retry_delay: parameters.maxRetryDelay, - read_poll_timeout: parameters.readPollTimeout, - }; -}; - -export const getFollowerIndexListInfoMock = (total = 3) => { - const list = { - follower_indices: [], - }; - - for (let i = 0; i < total; i++) { - list.follower_indices.push(getFollowerIndexInfoMock()); - } - - return list; -}; - -// ----------------- -// Client test mock -// ----------------- - -export const getFollowerIndexMock = ({ - name = getRandomString(), - remoteCluster = getRandomString(), - leaderIndex = getRandomString(), - status = 'Active', -} = {}) => ({ - name, - remoteCluster, - leaderIndex, - status, - maxReadRequestOperationCount: chance.integer(), - maxOutstandingReadRequests: chance.integer(), - maxReadRequestSize: getRandomString({ length: 5 }), - maxWriteRequestOperationCount: chance.integer(), - maxWriteRequestSize: '9223372036854775807b', - maxOutstandingWriteRequests: chance.integer(), - maxWriteBufferCount: chance.integer(), - maxWriteBufferSize: getRandomString({ length: 5 }), - maxRetryDelay: getRandomString({ length: 5 }), - readPollTimeout: getRandomString({ length: 5 }), - shards: [ - { - id: 0, - remoteCluster: remoteCluster, - leaderIndex: leaderIndex, - leaderGlobalCheckpoint: chance.integer(), - leaderMaxSequenceNum: chance.integer(), - followerGlobalCheckpoint: chance.integer(), - followerMaxSequenceNum: chance.integer(), - lastRequestedSequenceNum: chance.integer(), - outstandingReadRequestsCount: chance.integer(), - outstandingWriteRequestsCount: chance.integer(), - writeBufferOperationsCount: chance.integer(), - writeBufferSizeBytes: chance.integer(), - followerMappingVersion: chance.integer(), - followerSettingsVersion: chance.integer(), - totalReadTimeMs: chance.integer(), - totalReadRemoteExecTimeMs: chance.integer(), - successfulReadRequestCount: chance.integer(), - failedReadRequestsCount: chance.integer(), - operationsReadCount: chance.integer(), - bytesReadCount: chance.integer(), - totalWriteTimeMs: chance.integer(), - successfulWriteRequestsCount: chance.integer(), - failedWriteRequestsCount: chance.integer(), - operationsWrittenCount: chance.integer(), - readExceptions: [], - timeSinceLastReadMs: chance.integer(), - }, - ], -}); diff --git a/x-pack/plugins/cross_cluster_replication/fixtures/index.js b/x-pack/plugins/cross_cluster_replication/fixtures/index.js deleted file mode 100644 index ccfdf8b19f3ee..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/fixtures/index.js +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -export { getAutoFollowPatternMock, getAutoFollowPatternListMock } from './auto_follow_pattern'; - -export { esErrors } from './es_errors'; - -export { - getFollowerIndexStatsMock, - getFollowerIndexListStatsMock, - getFollowerIndexInfoMock, - getFollowerIndexListInfoMock, -} from './follower_index'; diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_list.test.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_list.test.js index f70c700f06e1a..5941b8ef71a19 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_list.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_list.test.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { getAutoFollowPatternClientMock } from '../../../fixtures/auto_follow_pattern'; +import { getAutoFollowPatternMock } from './fixtures/auto_follow_pattern'; import './mocks'; import { setupEnvironment, pageHelpers, nextTick, getRandomString } from './helpers'; @@ -76,11 +76,11 @@ describe('', () => { const testPrefix = 'prefix_'; const testSuffix = '_suffix'; - const autoFollowPattern1 = getAutoFollowPatternClientMock({ + const autoFollowPattern1 = getAutoFollowPatternMock({ name: `a${getRandomString()}`, followIndexPattern: `${testPrefix}{{leader_index}}${testSuffix}`, }); - const autoFollowPattern2 = getAutoFollowPatternClientMock({ + const autoFollowPattern2 = getAutoFollowPatternMock({ name: `b${getRandomString()}`, followIndexPattern: '{{leader_index}}', // no prefix nor suffix }); diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/fixtures/auto_follow_pattern.ts b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/fixtures/auto_follow_pattern.ts new file mode 100644 index 0000000000000..e6444c37e8590 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/fixtures/auto_follow_pattern.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getRandomString } from '../../../../../../test_utils'; +import { AutoFollowPattern } from '../../../../common/types'; + +export const getAutoFollowPatternMock = ({ + name = getRandomString(), + active = false, + remoteCluster = getRandomString(), + leaderIndexPatterns = [`${getRandomString()}-*`], + followIndexPattern = getRandomString(), +}: { + name: string; + active: boolean; + remoteCluster: string; + leaderIndexPatterns: string[]; + followIndexPattern: string; +}): AutoFollowPattern => ({ + name, + active, + remoteCluster, + leaderIndexPatterns, + followIndexPattern, +}); diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/fixtures/follower_index.ts b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/fixtures/follower_index.ts new file mode 100644 index 0000000000000..ff051d470531b --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/fixtures/follower_index.ts @@ -0,0 +1,70 @@ +/* + * 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 { getRandomString } from '../../../../../../test_utils'; +import { FollowerIndex } from '../../../../common/types'; + +const Chance = require('chance'); // eslint-disable-line import/no-extraneous-dependencies, @typescript-eslint/no-var-requires +const chance = new Chance(); + +interface FollowerIndexMock { + name: string; + remoteCluster: string; + leaderIndex: string; + status: string; +} + +export const getFollowerIndexMock = ({ + name = getRandomString(), + remoteCluster = getRandomString(), + leaderIndex = getRandomString(), + status = 'Active', +}: FollowerIndexMock): FollowerIndex => ({ + name, + remoteCluster, + leaderIndex, + status, + maxReadRequestOperationCount: chance.integer(), + maxOutstandingReadRequests: chance.integer(), + maxReadRequestSize: getRandomString({ length: 5 }), + maxWriteRequestOperationCount: chance.integer(), + maxWriteRequestSize: '9223372036854775807b', + maxOutstandingWriteRequests: chance.integer(), + maxWriteBufferCount: chance.integer(), + maxWriteBufferSize: getRandomString({ length: 5 }), + maxRetryDelay: getRandomString({ length: 5 }), + readPollTimeout: getRandomString({ length: 5 }), + shards: [ + { + id: 0, + remoteCluster, + leaderIndex, + leaderGlobalCheckpoint: chance.integer(), + leaderMaxSequenceNum: chance.integer(), + followerGlobalCheckpoint: chance.integer(), + followerMaxSequenceNum: chance.integer(), + lastRequestedSequenceNum: chance.integer(), + outstandingReadRequestsCount: chance.integer(), + outstandingWriteRequestsCount: chance.integer(), + writeBufferOperationsCount: chance.integer(), + writeBufferSizeBytes: chance.integer(), + followerMappingVersion: chance.integer(), + followerSettingsVersion: chance.integer(), + totalReadTimeMs: chance.integer(), + totalReadRemoteExecTimeMs: chance.integer(), + successfulReadRequestCount: chance.integer(), + failedReadRequestsCount: chance.integer(), + operationsReadCount: chance.integer(), + bytesReadCount: chance.integer(), + totalWriteTimeMs: chance.integer(), + successfulWriteRequestsCount: chance.integer(), + failedWriteRequestsCount: chance.integer(), + operationsWrittenCount: chance.integer(), + readExceptions: [], + timeSinceLastReadMs: chance.integer(), + }, + ], +}); diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js index c06a51bc94c7b..f98a1dafbbcbf 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { getFollowerIndexMock } from '../../../fixtures/follower_index'; +import { getFollowerIndexMock } from './fixtures/follower_index'; import './mocks'; import { setupEnvironment, pageHelpers, nextTick, getRandomString } from './helpers'; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/auto_follow_pattern.test.js b/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/auto_follow_pattern.test.js deleted file mode 100644 index a11ed77afd7a4..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/auto_follow_pattern.test.js +++ /dev/null @@ -1,321 +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 { deserializeAutoFollowPattern } from '../../../../common/services/auto_follow_pattern_serialization'; -import { getAutoFollowPatternMock, getAutoFollowPatternListMock } from '../../../../fixtures'; -import { registerAutoFollowPatternRoutes } from '../auto_follow_pattern'; - -import { createRouter, callRoute } from './helpers'; - -const DESERIALIZED_KEYS = Object.keys(deserializeAutoFollowPattern(getAutoFollowPatternMock())); - -let routeRegistry; - -/** - * Helper to extract all the different server route handler so we can easily call them in our tests. - * - * Important: This method registers the handlers in the order that they appear in the file, so - * if a "server.route()" call is moved or deleted, then the HANDLER_INDEX_TO_ACTION must be updated here. - */ -const registerHandlers = () => { - const HANDLER_INDEX_TO_ACTION = { - 0: 'list', - 1: 'create', - 2: 'update', - 3: 'get', - 4: 'delete', - 5: 'pause', - 6: 'resume', - }; - - routeRegistry = createRouter(HANDLER_INDEX_TO_ACTION); - - registerAutoFollowPatternRoutes({ - __LEGACY: {}, - router: routeRegistry.router, - }); -}; - -/** - * Queue to save request response and errors - * It allows us to fake multiple responses from the - * callWithRequestFactory() when the request handler call it - * multiple times. - */ -let requestResponseQueue = []; - -/** - * Helper to mock the response from the call to Elasticsearch - * - * @param {*} err The mock error to throw - * @param {*} response The response to return - */ -const setHttpRequestResponse = (error, response) => { - requestResponseQueue.push({ error, response }); -}; - -const resetHttpRequestResponses = () => (requestResponseQueue = []); - -const getNextResponseFromQueue = () => { - if (!requestResponseQueue.length) { - return null; - } - - const next = requestResponseQueue.shift(); - if (next.error) { - return Promise.reject(next.error); - } - return Promise.resolve(next.response); -}; - -describe('[CCR API Routes] Auto Follow Pattern', () => { - let routeHandler; - - beforeAll(() => { - // callWithRequestFactory.mockReturnValue(getNextResponseFromQueue); - registerHandlers(); - }); - - describe('list()', () => { - beforeEach(() => { - routeHandler = routeRegistry.getRoutes().list; - }); - - it('should deserialize the response from Elasticsearch', async () => { - const totalResult = 2; - setHttpRequestResponse(null, getAutoFollowPatternListMock(totalResult)); - - const { - options: { body: response }, - } = await callRoute(routeHandler); - const autoFollowPattern = response.patterns[0]; - - expect(response.patterns.length).toEqual(totalResult); - expect(Object.keys(autoFollowPattern)).toEqual(DESERIALIZED_KEYS); - }); - }); - - describe('create()', () => { - beforeEach(() => { - resetHttpRequestResponses(); - 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 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 () => { - const error = new Error('Resource not found.'); - error.statusCode = 404; - setHttpRequestResponse(error); - setHttpRequestResponse(null, { acknowledge: true }); - - const { - options: { body: response }, - } = await callRoute( - routeHandler, - {}, - { - body: { - id: 'some-id', - foo: 'bar', - }, - } - ); - - expect(response).toEqual({ acknowledge: true }); - }); - }); - - describe('update()', () => { - beforeEach(() => { - routeHandler = routeRegistry.getRoutes().update; - }); - - it('should serialize the payload before sending it to Elasticsearch', async () => { - callWithRequestFactory.mockReturnValueOnce((_, payload) => payload); - - const request = { - params: { id: 'foo' }, - body: { - remoteCluster: 'bar1', - leaderIndexPatterns: ['bar2'], - followIndexPattern: 'bar3', - }, - }; - - const response = await callRoute(routeHandler, {}, request); - - expect(response.options.body).toEqual({ - id: 'foo', - body: { - remote_cluster: 'bar1', - leader_index_patterns: ['bar2'], - follow_index_pattern: 'bar3', - }, - }); - }); - }); - - describe('get()', () => { - beforeEach(() => { - routeHandler = routeRegistry.getRoutes().get; - }); - - it('should return a single resource even though ES return an array with 1 item', async () => { - const autoFollowPattern = getAutoFollowPatternMock(); - const esResponse = { patterns: [autoFollowPattern] }; - - setHttpRequestResponse(null, esResponse); - - const response = await callRoute(routeHandler, {}, { params: { id: 1 } }); - expect(Object.keys(response.options.body)).toEqual(DESERIALIZED_KEYS); - }); - }); - - describe('delete()', () => { - beforeEach(() => { - resetHttpRequestResponses(); - routeHandler = routeRegistry.getRoutes().delete; - }); - - it('should delete a single item', async () => { - setHttpRequestResponse(null, { acknowledge: true }); - - const { - options: { body: response }, - } = await callRoute(routeHandler, {}, { params: { id: 'a' } }); - - expect(response.itemsDeleted).toEqual(['a']); - expect(response.errors).toEqual([]); - }); - - it('should accept a list of ids to delete', async () => { - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - - const response = await callRoute(routeHandler, {}, { params: { id: 'a,b,c' } }); - - expect(response.options.body.itemsDeleted).toEqual(['a', 'b', 'c']); - }); - - it('should catch error and return them in array', async () => { - const error = new Error('something went wrong'); - error.response = '{ "error": {} }'; - - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(error); - - const { - options: { body: response }, - } = await callRoute(routeHandler, {}, { params: { id: 'a,b' } }); - - expect(response.itemsDeleted).toEqual(['a']); - expect(response.errors[0].id).toEqual('b'); - }); - }); - - describe('pause()', () => { - beforeEach(() => { - resetHttpRequestResponses(); - routeHandler = routeRegistry.getRoutes().pause; - }); - - it('accept a single item', async () => { - setHttpRequestResponse(null, { acknowledge: true }); - - const { - options: { body: response }, - } = await callRoute(routeHandler, {}, { params: { id: 'a' } }); - - expect(response.itemsPaused).toEqual(['a']); - expect(response.errors).toEqual([]); - }); - - it('should accept a list of items to pause', async () => { - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - - const response = await callRoute(routeHandler, {}, { params: { id: 'a,b,c' } }); - - expect(response.options.body.itemsPaused).toEqual(['a', 'b', 'c']); - }); - - it('should catch error and return them in array', async () => { - const error = new Error('something went wrong'); - error.response = '{ "error": {} }'; - - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(error); - - const { - options: { body: response }, - } = await callRoute(routeHandler, {}, { params: { id: 'a,b' } }); - - expect(response.itemsPaused).toEqual(['a']); - expect(response.errors[0].id).toEqual('b'); - }); - }); - - describe('resume()', () => { - beforeEach(() => { - resetHttpRequestResponses(); - routeHandler = routeRegistry.getRoutes().resume; - }); - - it('accept a single item', async () => { - setHttpRequestResponse(null, { acknowledge: true }); - - const { - options: { body: response }, - } = await callRoute(routeHandler, {}, { params: { id: 'a' } }); - - expect(response.itemsResumed).toEqual(['a']); - expect(response.errors).toEqual([]); - }); - - it('should accept a list of items to pause', async () => { - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - - const response = await callRoute(routeHandler, {}, { params: { id: 'a,b,c' } }); - - expect(response.options.body.itemsResumed).toEqual(['a', 'b', 'c']); - }); - - it('should catch error and return them in array', async () => { - const error = new Error('something went wrong'); - error.response = '{ "error": {} }'; - - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(error); - - 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/plugins/cross_cluster_replication/server/routes/api/__jest__/follower_index.test.js b/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/follower_index.test.js deleted file mode 100644 index f08977c08b2f5..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/follower_index.test.js +++ /dev/null @@ -1,303 +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 { deserializeFollowerIndex } from '../../../../common/services/follower_index_serialization'; -import { - getFollowerIndexStatsMock, - getFollowerIndexListStatsMock, - getFollowerIndexInfoMock, - getFollowerIndexListInfoMock, -} from '../../../../fixtures'; -import { registerFollowerIndexRoutes } from '../follower_index'; -import { createRouter, callRoute } from './helpers'; - -const DESERIALIZED_KEYS = Object.keys( - deserializeFollowerIndex({ - ...getFollowerIndexInfoMock(), - ...getFollowerIndexStatsMock(), - }) -); - -let routeRegistry; - -/** - * Helper to extract all the different server route handler so we can easily call them in our tests. - * - * Important: This method registers the handlers in the order that they appear in the file, so - * if a 'server.route()' call is moved or deleted, then the HANDLER_INDEX_TO_ACTION must be updated here. - */ -const registerHandlers = () => { - const HANDLER_INDEX_TO_ACTION = { - 0: 'list', - 1: 'get', - 2: 'create', - 3: 'edit', - 4: 'pause', - 5: 'resume', - 6: 'unfollow', - }; - - routeRegistry = createRouter(HANDLER_INDEX_TO_ACTION); - registerFollowerIndexRoutes({ - __LEGACY: {}, - router: routeRegistry.router, - }); -}; - -/** - * Queue to save request response and errors - * It allows us to fake multiple responses from the - * callWithRequestFactory() when the request handler call it - * multiple times. - */ -let requestResponseQueue = []; - -/** - * Helper to mock the response from the call to Elasticsearch - * - * @param {*} err The mock error to throw - * @param {*} response The response to return - */ -const setHttpRequestResponse = (error, response) => { - requestResponseQueue.push({ error, response }); -}; - -const resetHttpRequestResponses = () => (requestResponseQueue = []); - -const getNextResponseFromQueue = () => { - if (!requestResponseQueue.length) { - return null; - } - - const next = requestResponseQueue.shift(); - if (next.error) { - return Promise.reject(next.error); - } - return Promise.resolve(next.response); -}; - -describe('[CCR API Routes] Follower Index', () => { - let routeHandler; - - beforeAll(() => { - // callWithRequestFactory.mockReturnValue(getNextResponseFromQueue); - registerHandlers(); - }); - - describe('list()', () => { - beforeEach(() => { - routeHandler = routeRegistry.getRoutes().list; - }); - - it('deserializes the response from Elasticsearch', async () => { - const totalResult = 2; - const infoResult = getFollowerIndexListInfoMock(totalResult); - const statsResult = getFollowerIndexListStatsMock( - totalResult, - infoResult.follower_indices.map(index => index.follower_index) - ); - setHttpRequestResponse(null, infoResult); - setHttpRequestResponse(null, statsResult); - - const { - options: { body: response }, - } = await callRoute(routeHandler); - const followerIndex = response.indices[0]; - - expect(response.indices.length).toEqual(totalResult); - expect(Object.keys(followerIndex)).toEqual(DESERIALIZED_KEYS); - }); - }); - - describe('get()', () => { - beforeEach(() => { - routeHandler = routeRegistry.getRoutes().get; - }); - - it('should return a single resource even though ES return an array with 1 item', async () => { - const mockId = 'test1'; - const followerIndexInfo = getFollowerIndexInfoMock(mockId); - const followerIndexStats = getFollowerIndexStatsMock(mockId); - - setHttpRequestResponse(null, { follower_indices: [followerIndexInfo] }); - setHttpRequestResponse(null, { indices: [followerIndexStats] }); - - const { - options: { body: response }, - } = await callRoute(routeHandler, {}, { params: { id: mockId } }); - expect(Object.keys(response)).toEqual(DESERIALIZED_KEYS); - }); - }); - - describe('create()', () => { - beforeEach(() => { - resetHttpRequestResponses(); - routeHandler = routeRegistry.getRoutes().create; - }); - - it('should return 200 status when follower index is created', async () => { - setHttpRequestResponse(null, { acknowledge: true }); - - const response = await callRoute( - routeHandler, - {}, - { - body: { - name: 'follower_index', - remoteCluster: 'remote_cluster', - leaderIndex: 'leader_index', - }, - } - ); - - expect(response.options.body).toEqual({ acknowledge: true }); - }); - }); - - describe('pause()', () => { - beforeEach(() => { - resetHttpRequestResponses(); - routeHandler = routeRegistry.getRoutes().pause; - }); - - it('should pause a single item', async () => { - setHttpRequestResponse(null, { acknowledge: true }); - - const { - options: { body: response }, - } = await callRoute(routeHandler, {}, { params: { id: '1' } }); - - expect(response.itemsPaused).toEqual(['1']); - expect(response.errors).toEqual([]); - }); - - it('should accept a list of ids to pause', async () => { - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - - const response = await callRoute(routeHandler, {}, { params: { id: '1,2,3' } }); - - expect(response.options.body.itemsPaused).toEqual(['1', '2', '3']); - }); - - it('should catch error and return them in array', async () => { - const error = new Error('something went wrong'); - error.response = '{ "error": {} }'; - - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(error); - - const { - options: { body: response }, - } = await callRoute(routeHandler, {}, { params: { id: '1,2' } }); - - expect(response.itemsPaused).toEqual(['1']); - expect(response.errors[0].id).toEqual('2'); - }); - }); - - describe('resume()', () => { - beforeEach(() => { - resetHttpRequestResponses(); - routeHandler = routeRegistry.getRoutes().resume; - }); - - it('should resume a single item', async () => { - setHttpRequestResponse(null, { acknowledge: true }); - - const { - options: { body: response }, - } = await callRoute(routeHandler, {}, { params: { id: '1' } }); - - expect(response.itemsResumed).toEqual(['1']); - expect(response.errors).toEqual([]); - }); - - it('should accept a list of ids to resume', async () => { - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - - const response = await callRoute(routeHandler, {}, { params: { id: '1,2,3' } }); - - expect(response.options.body.itemsResumed).toEqual(['1', '2', '3']); - }); - - it('should catch error and return them in array', async () => { - const error = new Error('something went wrong'); - error.response = '{ "error": {} }'; - - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(error); - - const { - options: { body: response }, - } = await callRoute(routeHandler, {}, { params: { id: '1,2' } }); - - expect(response.itemsResumed).toEqual(['1']); - expect(response.errors[0].id).toEqual('2'); - }); - }); - - describe('unfollow()', () => { - beforeEach(() => { - resetHttpRequestResponses(); - routeHandler = routeRegistry.getRoutes().unfollow; - }); - - it('should unfollow await single item', async () => { - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - - const { - options: { body: response }, - } = await callRoute(routeHandler, {}, { params: { id: '1' } }); - - expect(response.itemsUnfollowed).toEqual(['1']); - expect(response.errors).toEqual([]); - }); - - it('should accept a list of ids to unfollow', async () => { - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - - const response = await callRoute(routeHandler, {}, { params: { id: '1,2,3' } }); - - expect(response.options.body.itemsUnfollowed).toEqual(['1', '2', '3']); - }); - - it('should catch error and return them in array', async () => { - const error = new Error('something went wrong'); - error.response = '{ "error": {} }'; - - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(null, { acknowledge: true }); - setHttpRequestResponse(error); - - 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/plugins/cross_cluster_replication/server/routes/api/__jest__/helpers.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/helpers.ts deleted file mode 100644 index f287e095d31ba..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/__jest__/helpers.ts +++ /dev/null @@ -1,36 +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 { RequestHandler, 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/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.test.ts new file mode 100644 index 0000000000000..329a156cc18aa --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.test.ts @@ -0,0 +1,84 @@ +/* + * 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 { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; +import { + IRouter, + kibanaResponseFactory, + RequestHandler, + RequestHandlerContext, +} from 'src/core/server'; + +import { isEsError } from '../../../lib/is_es_error'; +import { License } from '../../../services'; +import { registerCreateRoute } from './register_create_route'; + +const httpService = httpServiceMock.createSetupContract(); + +describe('[CCR API] Create auto-follow pattern', () => { + let routeHandler: RequestHandler; + + beforeEach(() => { + const router = httpService.createRouter('') as jest.Mocked; + + registerCreateRoute({ + router, + license: { + guardApiRoute: (route: any) => route, + } as License, + lib: { + isEsError, + }, + }); + + routeHandler = router.post.mock.calls[0][1]; + }); + + it('should throw a 409 conflict error if id already exists', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + // Fail the uniqueness check. + callAsCurrentUser: jest.fn().mockResolvedValueOnce(true), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + body: { + id: 'some-id', + foo: 'bar', + }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.status).toEqual(409); + }); + + it('should return 200 status when the id does not exist', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest + .fn() + // Pass the uniqueness check. + .mockRejectedValueOnce({ statusCode: 404 }) + .mockResolvedValueOnce(true), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + body: { + id: 'some-id', + foo: 'bar', + }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.status).toEqual(200); + }); +}); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts index c169ec9d9a4e2..555b28199e3f4 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts @@ -33,7 +33,7 @@ export const registerCreateRoute = ({ router, license, lib }: RouteDependencies) const body = serializeAutoFollowPattern(rest as AutoFollowPattern); /** - * First let's make sur that an auto-follow pattern with + * First let's make sure that an auto-follow pattern with * the same id does not exist. */ try { diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.test.ts new file mode 100644 index 0000000000000..f28e805ababd6 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.test.ts @@ -0,0 +1,101 @@ +/* + * 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 { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; +import { + IRouter, + kibanaResponseFactory, + RequestHandler, + RequestHandlerContext, +} from 'src/core/server'; + +import { isEsError } from '../../../lib/is_es_error'; +import { License } from '../../../services'; +import { registerDeleteRoute } from './register_delete_route'; + +const httpService = httpServiceMock.createSetupContract(); + +describe('[CCR API] Delete auto-follow pattern(s)', () => { + let routeHandler: RequestHandler; + + beforeEach(() => { + const router = httpService.createRouter('') as jest.Mocked; + + registerDeleteRoute({ + router, + license: { + guardApiRoute: (route: any) => route, + } as License, + lib: { + isEsError, + }, + }); + + routeHandler = router.delete.mock.calls[0][1]; + }); + + it('deletes a single item', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest.fn().mockResolvedValueOnce({ acknowledge: true }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'a' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload.itemsDeleted).toEqual(['a']); + expect(response.payload.errors).toEqual([]); + }); + + it('deletes multiple items', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'a,b,c' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload.itemsDeleted).toEqual(['a', 'b', 'c']); + expect(response.payload.errors).toEqual([]); + }); + + it('returns partial errors', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockRejectedValueOnce({ response: { error: {} } }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'a,b' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + + expect(response.payload.itemsDeleted).toEqual(['a']); + expect(response.payload.errors[0].id).toEqual('b'); + }); +}); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts new file mode 100644 index 0000000000000..9f84be5f50821 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts @@ -0,0 +1,75 @@ +/* + * 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 { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; +import { + IRouter, + kibanaResponseFactory, + RequestHandler, + RequestHandlerContext, +} from 'src/core/server'; + +import { isEsError } from '../../../lib/is_es_error'; +import { License } from '../../../services'; +import { registerFetchRoute } from './register_fetch_route'; + +const httpService = httpServiceMock.createSetupContract(); + +describe('[CCR API] Fetch all auto-follow patterns', () => { + let routeHandler: RequestHandler; + + beforeEach(() => { + const router = httpService.createRouter('') as jest.Mocked; + + registerFetchRoute({ + router, + license: { + guardApiRoute: (route: any) => route, + } as License, + lib: { + isEsError, + }, + }); + + routeHandler = router.get.mock.calls[0][1]; + }); + + it('deserializes the response from Elasticsearch', async () => { + const ccrAutoFollowPatternResponseMock = { + patterns: [ + { + name: 'autoFollowPattern', + pattern: { + active: true, + remote_cluster: 'remoteCluster', + leader_index_patterns: ['leader*'], + follow_index_pattern: 'follow', + }, + }, + ], + }; + + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest.fn().mockResolvedValueOnce(ccrAutoFollowPatternResponseMock), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest(); + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload.patterns).toEqual([ + { + active: true, + followIndexPattern: 'follow', + leaderIndexPatterns: ['leader*'], + name: 'autoFollowPattern', + remoteCluster: 'remoteCluster', + }, + ]); + }); +}); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts new file mode 100644 index 0000000000000..ae124a81df851 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts @@ -0,0 +1,73 @@ +/* + * 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 { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; +import { + IRouter, + kibanaResponseFactory, + RequestHandler, + RequestHandlerContext, +} from 'src/core/server'; + +import { isEsError } from '../../../lib/is_es_error'; +import { License } from '../../../services'; +import { registerGetRoute } from './register_get_route'; + +const httpService = httpServiceMock.createSetupContract(); + +describe('[CCR API] Get one auto-follow pattern', () => { + let routeHandler: RequestHandler; + + beforeEach(() => { + const router = httpService.createRouter('') as jest.Mocked; + + registerGetRoute({ + router, + license: { + guardApiRoute: (route: any) => route, + } as License, + lib: { + isEsError, + }, + }); + + routeHandler = router.get.mock.calls[0][1]; + }); + + it('should return a single resource even though ES returns an array with 1 item', async () => { + const ccrAutoFollowPatternResponseMock = { + patterns: [ + { + name: 'autoFollowPattern', + pattern: { + active: true, + remote_cluster: 'remoteCluster', + leader_index_patterns: ['leader*'], + follow_index_pattern: 'follow', + }, + }, + ], + }; + + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest.fn().mockResolvedValueOnce(ccrAutoFollowPatternResponseMock), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest(); + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload).toEqual({ + active: true, + followIndexPattern: 'follow', + leaderIndexPatterns: ['leader*'], + name: 'autoFollowPattern', + remoteCluster: 'remoteCluster', + }); + }); +}); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.test.ts new file mode 100644 index 0000000000000..193c54b886ba0 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.test.ts @@ -0,0 +1,100 @@ +/* + * 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 { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; +import { + IRouter, + kibanaResponseFactory, + RequestHandler, + RequestHandlerContext, +} from 'src/core/server'; + +import { isEsError } from '../../../lib/is_es_error'; +import { License } from '../../../services'; +import { registerPauseRoute } from './register_pause_route'; + +const httpService = httpServiceMock.createSetupContract(); + +describe('[CCR API] Pause auto-follow pattern(s)', () => { + let routeHandler: RequestHandler; + + beforeEach(() => { + const router = httpService.createRouter('') as jest.Mocked; + + registerPauseRoute({ + router, + license: { + guardApiRoute: (route: any) => route, + } as License, + lib: { + isEsError, + }, + }); + + routeHandler = router.post.mock.calls[0][1]; + }); + + it('pauses a single item', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest.fn().mockResolvedValueOnce({ acknowledge: true }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'a' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload.itemsPaused).toEqual(['a']); + expect(response.payload.errors).toEqual([]); + }); + + it('pauses multiple items', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'a,b,c' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload.itemsPaused).toEqual(['a', 'b', 'c']); + expect(response.payload.errors).toEqual([]); + }); + + it('returns partial errors', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockRejectedValueOnce({ response: { error: {} } }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'a,b' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload.itemsPaused).toEqual(['a']); + expect(response.payload.errors[0].id).toEqual('b'); + }); +}); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.test.ts new file mode 100644 index 0000000000000..f90c40d83a0cc --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.test.ts @@ -0,0 +1,100 @@ +/* + * 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 { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; +import { + IRouter, + kibanaResponseFactory, + RequestHandler, + RequestHandlerContext, +} from 'src/core/server'; + +import { isEsError } from '../../../lib/is_es_error'; +import { License } from '../../../services'; +import { registerResumeRoute } from './register_resume_route'; + +const httpService = httpServiceMock.createSetupContract(); + +describe('[CCR API] Resume auto-follow pattern(s)', () => { + let routeHandler: RequestHandler; + + beforeEach(() => { + const router = httpService.createRouter('') as jest.Mocked; + + registerResumeRoute({ + router, + license: { + guardApiRoute: (route: any) => route, + } as License, + lib: { + isEsError, + }, + }); + + routeHandler = router.post.mock.calls[0][1]; + }); + + it('resumes a single item', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest.fn().mockResolvedValueOnce({ acknowledge: true }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'a' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload.itemsResumed).toEqual(['a']); + expect(response.payload.errors).toEqual([]); + }); + + it('resumes multiple items', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'a,b,c' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload.itemsResumed).toEqual(['a', 'b', 'c']); + expect(response.payload.errors).toEqual([]); + }); + + it('returns partial errors', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockRejectedValueOnce({ response: { error: {} } }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'a,b' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload.itemsResumed).toEqual(['a']); + expect(response.payload.errors[0].id).toEqual('b'); + }); +}); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts new file mode 100644 index 0000000000000..0fb78f2dc070d --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts @@ -0,0 +1,70 @@ +/* + * 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 { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; +import { + IRouter, + kibanaResponseFactory, + RequestHandler, + RequestHandlerContext, +} from 'src/core/server'; + +import { isEsError } from '../../../lib/is_es_error'; +import { License } from '../../../services'; +import { registerUpdateRoute } from './register_update_route'; + +const httpService = httpServiceMock.createSetupContract(); + +describe('[CCR API] Update auto-follow pattern', () => { + let routeHandler: RequestHandler; + + beforeEach(() => { + const router = httpService.createRouter('') as jest.Mocked; + + registerUpdateRoute({ + router, + license: { + guardApiRoute: (route: any) => route, + } as License, + lib: { + isEsError, + }, + }); + + routeHandler = router.put.mock.calls[0][1]; + }); + + it('should serialize the payload before sending it to Elasticsearch', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + // Just echo back what we send so we can inspect it. + callAsCurrentUser: jest.fn().mockImplementation((endpoint, payload) => payload), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'foo' }, + body: { + remoteCluster: 'bar1', + leaderIndexPatterns: ['bar2'], + followIndexPattern: 'bar3', + }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + + expect(response.payload).toEqual({ + id: 'foo', + body: { + remote_cluster: 'bar1', + leader_index_patterns: ['bar2'], + follow_index_pattern: 'bar3', + }, + }); + }); +}); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.test.ts new file mode 100644 index 0000000000000..5424ad4996dbd --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.test.ts @@ -0,0 +1,60 @@ +/* + * 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 { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; +import { + IRouter, + kibanaResponseFactory, + RequestHandler, + RequestHandlerContext, +} from 'src/core/server'; + +import { isEsError } from '../../../lib/is_es_error'; +import { License } from '../../../services'; +import { registerCreateRoute } from './register_create_route'; + +const httpService = httpServiceMock.createSetupContract(); + +describe('[CCR API] Create follower index', () => { + let routeHandler: RequestHandler; + + beforeEach(() => { + const router = httpService.createRouter('') as jest.Mocked; + + registerCreateRoute({ + router, + license: { + guardApiRoute: (route: any) => route, + } as License, + lib: { + isEsError, + }, + }); + + routeHandler = router.post.mock.calls[0][1]; + }); + + it('should return 200 status when follower index is created', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest.fn().mockResolvedValueOnce({ acknowledge: true }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + body: { + name: 'follower_index', + remoteCluster: 'remote_cluster', + leaderIndex: 'leader_index', + }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.status).toEqual(200); + }); +}); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts new file mode 100644 index 0000000000000..2bddf2b65842a --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts @@ -0,0 +1,166 @@ +/* + * 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 { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; +import { + IRouter, + kibanaResponseFactory, + RequestHandler, + RequestHandlerContext, +} from 'src/core/server'; + +import { isEsError } from '../../../lib/is_es_error'; +import { License } from '../../../services'; +import { registerFetchRoute } from './register_fetch_route'; + +const httpService = httpServiceMock.createSetupContract(); + +describe('[CCR API] Fetch all follower indices', () => { + let routeHandler: RequestHandler; + + beforeEach(() => { + const router = httpService.createRouter('') as jest.Mocked; + + registerFetchRoute({ + router, + license: { + guardApiRoute: (route: any) => route, + } as License, + lib: { + isEsError, + }, + }); + + routeHandler = router.get.mock.calls[0][1]; + }); + + it('deserializes the response from Elasticsearch', async () => { + const ccrInfoMockResponse = { + follower_indices: [ + { + follower_index: 'followerIndexName', + remote_cluster: 'remoteCluster', + leader_index: 'leaderIndex', + status: 'active', + parameters: { + max_read_request_operation_count: 1, + max_outstanding_read_requests: 1, + max_read_request_size: '1b', + max_write_request_operation_count: 1, + max_write_request_size: '1b', + max_outstanding_write_requests: 1, + max_write_buffer_count: 1, + max_write_buffer_size: '1b', + max_retry_delay: '1s', + read_poll_timeout: '1s', + }, + }, + ], + }; + + // These stats correlate to the above follower indices. + const ccrStatsMockResponse = { + follow_stats: { + indices: [ + { + index: 'followerIndexName', + shards: [ + { + shard_id: 1, + leader_index: 'leaderIndex', + leader_global_checkpoint: 1, + leader_max_seq_no: 1, + follower_global_checkpoint: 1, + follower_max_seq_no: 1, + last_requested_seq_no: 1, + outstanding_read_requests: 1, + outstanding_write_requests: 1, + write_buffer_operation_count: 1, + write_buffer_size_in_bytes: 1, + follower_mapping_version: 1, + follower_settings_version: 1, + total_read_time_millis: 1, + total_read_remote_exec_time_millis: 1, + successful_read_requests: 1, + failed_read_requests: 1, + operations_read: 1, + bytes_read: 1, + total_write_time_millis: 1, + successful_write_requests: 1, + failed_write_requests: 1, + operations_written: 1, + read_exceptions: 1, + time_since_last_read_millis: 1, + }, + ], + }, + ], + }, + }; + + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce(ccrInfoMockResponse) + .mockResolvedValueOnce(ccrStatsMockResponse), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest(); + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + + expect(response.payload.indices).toEqual([ + { + name: 'followerIndexName', + remoteCluster: 'remoteCluster', + leaderIndex: 'leaderIndex', + status: 'active', + maxReadRequestOperationCount: 1, + maxOutstandingReadRequests: 1, + maxReadRequestSize: '1b', + maxWriteRequestOperationCount: 1, + maxWriteRequestSize: '1b', + maxOutstandingWriteRequests: 1, + maxWriteBufferCount: 1, + maxWriteBufferSize: '1b', + maxRetryDelay: '1s', + readPollTimeout: '1s', + shards: [ + { + id: 1, + leaderIndex: 'leaderIndex', + leaderGlobalCheckpoint: 1, + leaderMaxSequenceNum: 1, + followerGlobalCheckpoint: 1, + followerMaxSequenceNum: 1, + lastRequestedSequenceNum: 1, + outstandingReadRequestsCount: 1, + outstandingWriteRequestsCount: 1, + writeBufferOperationsCount: 1, + writeBufferSizeBytes: 1, + followerMappingVersion: 1, + followerSettingsVersion: 1, + totalReadTimeMs: 1, + totalReadRemoteExecTimeMs: 1, + successfulReadRequestCount: 1, + failedReadRequestsCount: 1, + operationsReadCount: 1, + bytesReadCount: 1, + totalWriteTimeMs: 1, + successfulWriteRequestsCount: 1, + failedWriteRequestsCount: 1, + operationsWrittenCount: 1, + readExceptions: 1, + timeSinceLastReadMs: 1, + }, + ], + }, + ]); + }); +}); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts new file mode 100644 index 0000000000000..4aeb8e1d5520d --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts @@ -0,0 +1,165 @@ +/* + * 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 { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; +import { + IRouter, + kibanaResponseFactory, + RequestHandler, + RequestHandlerContext, +} from 'src/core/server'; + +import { isEsError } from '../../../lib/is_es_error'; +import { License } from '../../../services'; +import { registerGetRoute } from './register_get_route'; + +const httpService = httpServiceMock.createSetupContract(); + +describe('[CCR API] Get one follower index', () => { + let routeHandler: RequestHandler; + + beforeEach(() => { + const router = httpService.createRouter('') as jest.Mocked; + + registerGetRoute({ + router, + license: { + guardApiRoute: (route: any) => route, + } as License, + lib: { + isEsError, + }, + }); + + routeHandler = router.get.mock.calls[0][1]; + }); + + it('should return a single resource even though ES returns an array with 1 item', async () => { + const ccrInfoMockResponse = { + follower_indices: [ + { + follower_index: 'followerIndexName', + remote_cluster: 'remoteCluster', + leader_index: 'leaderIndex', + status: 'active', + parameters: { + max_read_request_operation_count: 1, + max_outstanding_read_requests: 1, + max_read_request_size: '1b', + max_write_request_operation_count: 1, + max_write_request_size: '1b', + max_outstanding_write_requests: 1, + max_write_buffer_count: 1, + max_write_buffer_size: '1b', + max_retry_delay: '1s', + read_poll_timeout: '1s', + }, + }, + ], + }; + + // These stats correlate to the above follower indices. + const ccrFollowerIndexStatsMockResponse = { + indices: [ + { + index: 'followerIndexName', + shards: [ + { + shard_id: 1, + leader_index: 'leaderIndex', + leader_global_checkpoint: 1, + leader_max_seq_no: 1, + follower_global_checkpoint: 1, + follower_max_seq_no: 1, + last_requested_seq_no: 1, + outstanding_read_requests: 1, + outstanding_write_requests: 1, + write_buffer_operation_count: 1, + write_buffer_size_in_bytes: 1, + follower_mapping_version: 1, + follower_settings_version: 1, + total_read_time_millis: 1, + total_read_remote_exec_time_millis: 1, + successful_read_requests: 1, + failed_read_requests: 1, + operations_read: 1, + bytes_read: 1, + total_write_time_millis: 1, + successful_write_requests: 1, + failed_write_requests: 1, + operations_written: 1, + read_exceptions: 1, + time_since_last_read_millis: 1, + }, + ], + }, + ], + }; + + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce(ccrInfoMockResponse) + .mockResolvedValueOnce(ccrFollowerIndexStatsMockResponse), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'doesnt_matter' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + + expect(response.payload).toEqual({ + name: 'followerIndexName', + remoteCluster: 'remoteCluster', + leaderIndex: 'leaderIndex', + status: 'active', + maxReadRequestOperationCount: 1, + maxOutstandingReadRequests: 1, + maxReadRequestSize: '1b', + maxWriteRequestOperationCount: 1, + maxWriteRequestSize: '1b', + maxOutstandingWriteRequests: 1, + maxWriteBufferCount: 1, + maxWriteBufferSize: '1b', + maxRetryDelay: '1s', + readPollTimeout: '1s', + shards: [ + { + id: 1, + leaderIndex: 'leaderIndex', + leaderGlobalCheckpoint: 1, + leaderMaxSequenceNum: 1, + followerGlobalCheckpoint: 1, + followerMaxSequenceNum: 1, + lastRequestedSequenceNum: 1, + outstandingReadRequestsCount: 1, + outstandingWriteRequestsCount: 1, + writeBufferOperationsCount: 1, + writeBufferSizeBytes: 1, + followerMappingVersion: 1, + followerSettingsVersion: 1, + totalReadTimeMs: 1, + totalReadRemoteExecTimeMs: 1, + successfulReadRequestCount: 1, + failedReadRequestsCount: 1, + operationsReadCount: 1, + bytesReadCount: 1, + totalWriteTimeMs: 1, + successfulWriteRequestsCount: 1, + failedWriteRequestsCount: 1, + operationsWrittenCount: 1, + readExceptions: 1, + timeSinceLastReadMs: 1, + }, + ], + }); + }); +}); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.test.ts new file mode 100644 index 0000000000000..fa86b30254e8c --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.test.ts @@ -0,0 +1,100 @@ +/* + * 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 { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; +import { + IRouter, + kibanaResponseFactory, + RequestHandler, + RequestHandlerContext, +} from 'src/core/server'; + +import { isEsError } from '../../../lib/is_es_error'; +import { License } from '../../../services'; +import { registerPauseRoute } from './register_pause_route'; + +const httpService = httpServiceMock.createSetupContract(); + +describe('[CCR API] Pause follower index/indices', () => { + let routeHandler: RequestHandler; + + beforeEach(() => { + const router = httpService.createRouter('') as jest.Mocked; + + registerPauseRoute({ + router, + license: { + guardApiRoute: (route: any) => route, + } as License, + lib: { + isEsError, + }, + }); + + routeHandler = router.put.mock.calls[0][1]; + }); + + it('pauses a single item', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest.fn().mockResolvedValueOnce({ acknowledge: true }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'a' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload.itemsPaused).toEqual(['a']); + expect(response.payload.errors).toEqual([]); + }); + + it('pauses multiple items', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'a,b,c' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload.itemsPaused).toEqual(['a', 'b', 'c']); + expect(response.payload.errors).toEqual([]); + }); + + it('returns partial errors', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockRejectedValueOnce({ response: { error: {} } }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'a,b' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload.itemsPaused).toEqual(['a']); + expect(response.payload.errors[0].id).toEqual('b'); + }); +}); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.test.ts new file mode 100644 index 0000000000000..6e1d802033c87 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.test.ts @@ -0,0 +1,100 @@ +/* + * 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 { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; +import { + IRouter, + kibanaResponseFactory, + RequestHandler, + RequestHandlerContext, +} from 'src/core/server'; + +import { isEsError } from '../../../lib/is_es_error'; +import { License } from '../../../services'; +import { registerResumeRoute } from './register_resume_route'; + +const httpService = httpServiceMock.createSetupContract(); + +describe('[CCR API] Resume follower index/indices', () => { + let routeHandler: RequestHandler; + + beforeEach(() => { + const router = httpService.createRouter('') as jest.Mocked; + + registerResumeRoute({ + router, + license: { + guardApiRoute: (route: any) => route, + } as License, + lib: { + isEsError, + }, + }); + + routeHandler = router.put.mock.calls[0][1]; + }); + + it('resumes a single item', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest.fn().mockResolvedValueOnce({ acknowledge: true }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'a' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload.itemsResumed).toEqual(['a']); + expect(response.payload.errors).toEqual([]); + }); + + it('resumes multiple items', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'a,b,c' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload.itemsResumed).toEqual(['a', 'b', 'c']); + expect(response.payload.errors).toEqual([]); + }); + + it('returns partial errors', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockRejectedValueOnce({ response: { error: {} } }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'a,b' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload.itemsResumed).toEqual(['a']); + expect(response.payload.errors[0].id).toEqual('b'); + }); +}); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.test.ts new file mode 100644 index 0000000000000..51b2c291d7a0e --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.test.ts @@ -0,0 +1,123 @@ +/* + * 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 { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; +import { + IRouter, + kibanaResponseFactory, + RequestHandler, + RequestHandlerContext, +} from 'src/core/server'; + +import { isEsError } from '../../../lib/is_es_error'; +import { License } from '../../../services'; +import { registerUnfollowRoute } from './register_unfollow_route'; + +const httpService = httpServiceMock.createSetupContract(); + +describe('[CCR API] Unfollow follower index/indices', () => { + let routeHandler: RequestHandler; + + beforeEach(() => { + const router = httpService.createRouter('') as jest.Mocked; + + registerUnfollowRoute({ + router, + license: { + guardApiRoute: (route: any) => route, + } as License, + lib: { + isEsError, + }, + }); + + routeHandler = router.put.mock.calls[0][1]; + }); + + it('unfollows a single item', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'a' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload.itemsUnfollowed).toEqual(['a']); + expect(response.payload.errors).toEqual([]); + }); + + it('unfollows multiple items', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest + .fn() + // a + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + // b + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + // c + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'a,b,c' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload.itemsUnfollowed).toEqual(['a', 'b', 'c']); + expect(response.payload.errors).toEqual([]); + }); + + it('returns partial errors', async () => { + const mockRouteContext = ({ + crossClusterReplication: { + client: { + callAsCurrentUser: jest + .fn() + // a + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + // b + .mockResolvedValueOnce({ acknowledge: true }) + .mockRejectedValueOnce({ response: { error: {} } }), + }, + }, + } as unknown) as RequestHandlerContext; + + const request = httpServerMock.createKibanaRequest({ + params: { id: 'a,b' }, + }); + + const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + expect(response.payload.itemsUnfollowed).toEqual(['a']); + expect(response.payload.errors[0].id).toEqual('b'); + }); +}); 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 3efb4d6600f7f..f424570737541 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 @@ -52,7 +52,6 @@ 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); }); 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 eabf474120f2b..ea94390ec25be 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 @@ -6,7 +6,7 @@ import expect from '@kbn/expect'; -import { FOLLOWER_INDEX_ADVANCED_SETTINGS } from '../../../../../legacy/plugins/cross_cluster_replication/common/constants'; +import { FOLLOWER_INDEX_ADVANCED_SETTINGS } from '../../../../../plugins/cross_cluster_replication/common/constants'; import { getFollowerIndexPayload } from './fixtures'; import { registerHelpers as registerElasticSearchHelpers, getRandomString } from './lib'; import { registerHelpers as registerRemoteClustersHelpers } from './remote_clusters.helpers'; From 265248290b1c2128486d7b60c53cee8c0765ac0d Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Tue, 14 Apr 2020 17:56:20 -0700 Subject: [PATCH 07/20] Fix shape of ES errors returned by the API. --- .../server/lib/format_es_error.ts | 78 +++++++++++++++++++ .../server/plugin.ts | 2 + .../register_create_route.test.ts | 2 + .../register_create_route.ts | 20 +++-- .../register_delete_route.test.ts | 2 + .../register_delete_route.ts | 13 ++-- .../register_fetch_route.test.ts | 2 + .../register_fetch_route.ts | 13 ++-- .../register_get_route.test.ts | 2 + .../auto_follow_pattern/register_get_route.ts | 13 ++-- .../register_pause_route.test.ts | 2 + .../register_pause_route.ts | 13 ++-- .../register_resume_route.test.ts | 2 + .../register_resume_route.ts | 13 ++-- .../register_update_route.test.ts | 2 + .../register_update_route.ts | 13 ++-- .../register_permissions_route.ts | 14 ++-- .../register_stats_route.ts | 13 ++-- .../register_create_route.test.ts | 2 + .../follower_index/register_create_route.ts | 13 ++-- .../register_fetch_route.test.ts | 2 + .../follower_index/register_fetch_route.ts | 13 ++-- .../follower_index/register_get_route.test.ts | 2 + .../api/follower_index/register_get_route.ts | 13 ++-- .../register_pause_route.test.ts | 2 + .../follower_index/register_pause_route.ts | 13 ++-- .../register_resume_route.test.ts | 2 + .../follower_index/register_resume_route.ts | 13 ++-- .../register_unfollow_route.test.ts | 2 + .../follower_index/register_unfollow_route.ts | 13 ++-- .../follower_index/register_update_route.ts | 13 ++-- .../cross_cluster_replication/server/types.ts | 2 + .../follower_indices.js | 6 +- 33 files changed, 227 insertions(+), 103 deletions(-) create mode 100644 x-pack/plugins/cross_cluster_replication/server/lib/format_es_error.ts diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/format_es_error.ts b/x-pack/plugins/cross_cluster_replication/server/lib/format_es_error.ts new file mode 100644 index 0000000000000..9dde027cd6949 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/lib/format_es_error.ts @@ -0,0 +1,78 @@ +/* + * 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. + */ + +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 @typescript-eslint/camelcase + if (caused_by) { + return extractCausedByChain(caused_by, accumulator); + } + + return accumulator; +} + +/** + * Wraps an error thrown by the ES JS client into a Boom error response and returns it + * + * @param err Object Error thrown by ES JS client + * @param statusCodeToMessageMap Object Optional map of HTTP status codes => error messages + */ +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 @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]) { + // 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; + + 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 { message, statusCode }; +} + +export function formatEsError(err: any): any { + const { statusCode, message, body } = wrapEsError(err); + return { + statusCode, + body: { + message, + attributes: { + cause: body?.cause, + }, + }, + }; +} diff --git a/x-pack/plugins/cross_cluster_replication/server/plugin.ts b/x-pack/plugins/cross_cluster_replication/server/plugin.ts index 83776a191770b..5d4676a6b7234 100644 --- a/x-pack/plugins/cross_cluster_replication/server/plugin.ts +++ b/x-pack/plugins/cross_cluster_replication/server/plugin.ts @@ -30,6 +30,7 @@ import { License } from './services'; import { elasticsearchJsPlugin } from './client/elasticsearch_ccr'; import { CrossClusterReplicationConfig } from './config'; import { isEsError } from './lib/is_es_error'; +import { formatEsError } from './lib/format_es_error'; interface CrossClusterReplicationContext { client: IScopedClusterClient; @@ -111,6 +112,7 @@ export class CrossClusterReplicationServerPlugin implements Plugin { } as License, lib: { isEsError, + formatEsError, }, }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts index 555b28199e3f4..91159315f51f9 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts @@ -13,7 +13,11 @@ import { RouteDependencies } from '../../../types'; /** * Create an auto-follow pattern */ -export const registerCreateRoute = ({ router, license, lib }: RouteDependencies) => { +export const registerCreateRoute = ({ + router, + license, + lib: { isEsError, formatEsError }, +}: RouteDependencies) => { const bodySchema = schema.object( { id: schema.string(), @@ -46,11 +50,8 @@ export const registerCreateRoute = ({ router, license, lib }: RouteDependencies) }); } catch (err) { if (err.statusCode !== 404) { - if (lib.isEsError(err)) { - return response.customError({ - statusCode: err.statusCode, - body: err, - }); + if (isEsError(err)) { + return response.customError(formatEsError(err)); } // Case: default return response.internalError({ body: err }); @@ -65,11 +66,8 @@ export const registerCreateRoute = ({ router, license, lib }: RouteDependencies) ), }); } catch (err) { - if (lib.isEsError(err)) { - return response.customError({ - statusCode: err.statusCode, - body: err, - }); + if (isEsError(err)) { + return response.customError(formatEsError(err)); } // Case: default return response.internalError({ body: err }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.test.ts index f28e805ababd6..9bd8a247563af 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.test.ts @@ -13,6 +13,7 @@ import { } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; +import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; import { registerDeleteRoute } from './register_delete_route'; @@ -31,6 +32,7 @@ describe('[CCR API] Delete auto-follow pattern(s)', () => { } as License, lib: { isEsError, + formatEsError, }, }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts index 6a8b7ff1e6ef4..5f7f476660eaa 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts @@ -12,7 +12,11 @@ import { RouteDependencies } from '../../../types'; /** * Delete an auto-follow pattern */ -export const registerDeleteRoute = ({ router, license, lib }: RouteDependencies) => { +export const registerDeleteRoute = ({ + router, + license, + lib: { isEsError, formatEsError }, +}: RouteDependencies) => { const paramsSchema = schema.object({ id: schema.string(), }); @@ -32,11 +36,8 @@ export const registerDeleteRoute = ({ router, license, lib }: RouteDependencies) const errors: Array<{ id: string; error: any }> = []; const formatError = (err: any) => { - if (lib.isEsError(err)) { - return response.customError({ - statusCode: err.statusCode, - body: err, - }); + if (isEsError(err)) { + return response.customError(formatEsError(err)); } // Case: default return response.internalError({ body: err }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts index 9f84be5f50821..a7632a5d66317 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts @@ -13,6 +13,7 @@ import { } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; +import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; import { registerFetchRoute } from './register_fetch_route'; @@ -31,6 +32,7 @@ describe('[CCR API] Fetch all auto-follow patterns', () => { } as License, lib: { isEsError, + formatEsError, }, }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts index 63ff2ea9b0a3e..70d8ae4d51e3b 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.ts @@ -11,7 +11,11 @@ import { RouteDependencies } from '../../../types'; /** * Get a list of all auto-follow patterns */ -export const registerFetchRoute = ({ router, license, lib }: RouteDependencies) => { +export const registerFetchRoute = ({ + router, + license, + lib: { isEsError, formatEsError }, +}: RouteDependencies) => { router.get( { path: addBasePath('/auto_follow_patterns'), @@ -28,11 +32,8 @@ export const registerFetchRoute = ({ router, license, lib }: RouteDependencies) }, }); } catch (err) { - if (lib.isEsError(err)) { - return response.customError({ - statusCode: err.statusCode, - body: err, - }); + if (isEsError(err)) { + return response.customError(formatEsError(err)); } // Case: default return response.internalError({ body: err }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts index ae124a81df851..4510478cea6db 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts @@ -13,6 +13,7 @@ import { } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; +import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; import { registerGetRoute } from './register_get_route'; @@ -31,6 +32,7 @@ describe('[CCR API] Get one auto-follow pattern', () => { } as License, lib: { isEsError, + formatEsError, }, }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts index d2d0e4990f682..3321ee8c9e6f8 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts @@ -13,7 +13,11 @@ import { RouteDependencies } from '../../../types'; /** * Get a single auto-follow pattern */ -export const registerGetRoute = ({ router, license, lib }: RouteDependencies) => { +export const registerGetRoute = ({ + router, + license, + lib: { isEsError, formatEsError }, +}: RouteDependencies) => { const paramsSchema = schema.object({ id: schema.string(), }); @@ -39,11 +43,8 @@ export const registerGetRoute = ({ router, license, lib }: RouteDependencies) => body: deserializeAutoFollowPattern(autoFollowPattern), }); } catch (err) { - if (lib.isEsError(err)) { - return response.customError({ - statusCode: err.statusCode, - body: err, - }); + if (isEsError(err)) { + return response.customError(formatEsError(err)); } // Case: default return response.internalError({ body: err }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.test.ts index 193c54b886ba0..3bb0fe32220ba 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.test.ts @@ -13,6 +13,7 @@ import { } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; +import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; import { registerPauseRoute } from './register_pause_route'; @@ -31,6 +32,7 @@ describe('[CCR API] Pause auto-follow pattern(s)', () => { } as License, lib: { isEsError, + formatEsError, }, }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts index 998895ab0b383..6c3333b1b7b2e 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts @@ -11,7 +11,11 @@ import { RouteDependencies } from '../../../types'; /** * Pause auto-follow pattern(s) */ -export const registerPauseRoute = ({ router, license, lib }: RouteDependencies) => { +export const registerPauseRoute = ({ + router, + license, + lib: { isEsError, formatEsError }, +}: RouteDependencies) => { const paramsSchema = schema.object({ id: schema.string(), }); @@ -31,11 +35,8 @@ export const registerPauseRoute = ({ router, license, lib }: RouteDependencies) const errors: Array<{ id: string; error: any }> = []; const formatError = (err: any) => { - if (lib.isEsError(err)) { - return response.customError({ - statusCode: err.statusCode, - body: err, - }); + if (isEsError(err)) { + return response.customError(formatEsError(err)); } // Case: default return response.internalError({ body: err }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.test.ts index f90c40d83a0cc..00a244ac5ec9c 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.test.ts @@ -13,6 +13,7 @@ import { } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; +import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; import { registerResumeRoute } from './register_resume_route'; @@ -31,6 +32,7 @@ describe('[CCR API] Resume auto-follow pattern(s)', () => { } as License, lib: { isEsError, + formatEsError, }, }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts index 9f3e534ce0a2a..9c966d4bf86ee 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts @@ -11,7 +11,11 @@ import { RouteDependencies } from '../../../types'; /** * Resume auto-follow pattern(s) */ -export const registerResumeRoute = ({ router, license, lib }: RouteDependencies) => { +export const registerResumeRoute = ({ + router, + license, + lib: { isEsError, formatEsError }, +}: RouteDependencies) => { const paramsSchema = schema.object({ id: schema.string(), }); @@ -31,11 +35,8 @@ export const registerResumeRoute = ({ router, license, lib }: RouteDependencies) const errors: Array<{ id: string; error: any }> = []; const formatError = (err: any) => { - if (lib.isEsError(err)) { - return response.customError({ - statusCode: err.statusCode, - body: err, - }); + if (isEsError(err)) { + return response.customError(formatEsError(err)); } // Case: default return response.internalError({ body: err }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts index 0fb78f2dc070d..09f27751f2b97 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts @@ -13,6 +13,7 @@ import { } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; +import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; import { registerUpdateRoute } from './register_update_route'; @@ -31,6 +32,7 @@ describe('[CCR API] Update auto-follow pattern', () => { } as License, lib: { isEsError, + formatEsError, }, }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts index 0d00e01da9758..a99aee2aecc9f 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts @@ -13,7 +13,11 @@ import { RouteDependencies } from '../../../types'; /** * Update an auto-follow pattern */ -export const registerUpdateRoute = ({ router, license, lib }: RouteDependencies) => { +export const registerUpdateRoute = ({ + router, + license, + lib: { isEsError, formatEsError }, +}: RouteDependencies) => { const paramsSchema = schema.object({ id: schema.string(), }); @@ -38,11 +42,8 @@ export const registerUpdateRoute = ({ router, license, lib }: RouteDependencies) ), }); } catch (err) { - if (lib.isEsError(err)) { - return response.customError({ - statusCode: err.statusCode, - body: err, - }); + if (isEsError(err)) { + return response.customError(formatEsError(err)); } // Case: default return response.internalError({ body: err }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_permissions_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_permissions_route.ts index 5c3dabc8784e8..1ec89cf9dbfcb 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_permissions_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_permissions_route.ts @@ -10,7 +10,12 @@ import { RouteDependencies } from '../../../types'; /** * Returns whether the user has CCR permissions */ -export const registerPermissionsRoute = ({ router, license, lib, security }: RouteDependencies) => { +export const registerPermissionsRoute = ({ + router, + license, + lib: { isEsError, formatEsError }, + security, +}: RouteDependencies) => { router.get( { path: addBasePath('/permissions'), @@ -54,11 +59,8 @@ export const registerPermissionsRoute = ({ router, license, lib, security }: Rou }, }); } catch (err) { - if (lib.isEsError(err)) { - return response.customError({ - statusCode: err.statusCode, - body: err, - }); + if (isEsError(err)) { + return response.customError(formatEsError(err)); } // Case: default return response.internalError({ body: err }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts index 776ed0bc11965..d4288cf7303e2 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/cross_cluster_replication/register_stats_route.ts @@ -11,7 +11,11 @@ import { RouteDependencies } from '../../../types'; /** * Returns Auto-follow stats */ -export const registerStatsRoute = ({ router, license, lib }: RouteDependencies) => { +export const registerStatsRoute = ({ + router, + license, + lib: { isEsError, formatEsError }, +}: RouteDependencies) => { router.get( { path: addBasePath('/stats/auto_follow'), @@ -27,11 +31,8 @@ export const registerStatsRoute = ({ router, license, lib }: RouteDependencies) body: deserializeAutoFollowStats(autoFollowStats), }); } catch (err) { - if (lib.isEsError(err)) { - return response.customError({ - statusCode: err.statusCode, - body: err, - }); + if (isEsError(err)) { + return response.customError(formatEsError(err)); } // Case: default return response.internalError({ body: err }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.test.ts index 5424ad4996dbd..feb71a8e94f0f 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.test.ts @@ -13,6 +13,7 @@ import { } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; +import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; import { registerCreateRoute } from './register_create_route'; @@ -31,6 +32,7 @@ describe('[CCR API] Create follower index', () => { } as License, lib: { isEsError, + formatEsError, }, }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts index 3d96bccf45d4a..346bc98c1e952 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts @@ -14,7 +14,11 @@ import { RouteDependencies } from '../../../types'; /** * Create a follower index */ -export const registerCreateRoute = ({ router, license, lib }: RouteDependencies) => { +export const registerCreateRoute = ({ + router, + license, + lib: { isEsError, formatEsError }, +}: RouteDependencies) => { const bodySchema = schema.object( { name: schema.string(), @@ -41,11 +45,8 @@ export const registerCreateRoute = ({ router, license, lib }: RouteDependencies) ), }); } catch (err) { - if (lib.isEsError(err)) { - return response.customError({ - statusCode: err.statusCode, - body: err, - }); + if (isEsError(err)) { + return response.customError(formatEsError(err)); } // Case: default return response.internalError({ body: err }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts index 2bddf2b65842a..d452db8c969d5 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts @@ -13,6 +13,7 @@ import { } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; +import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; import { registerFetchRoute } from './register_fetch_route'; @@ -31,6 +32,7 @@ describe('[CCR API] Fetch all follower indices', () => { } as License, lib: { isEsError, + formatEsError, }, }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts index 518e805f2386d..a78901ce174e4 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.ts @@ -11,7 +11,11 @@ import { RouteDependencies } from '../../../types'; /** * Returns a list of all follower indices */ -export const registerFetchRoute = ({ router, license, lib }: RouteDependencies) => { +export const registerFetchRoute = ({ + router, + license, + lib: { isEsError, formatEsError }, +}: RouteDependencies) => { router.get( { path: addBasePath('/follower_indices'), @@ -47,11 +51,8 @@ export const registerFetchRoute = ({ router, license, lib }: RouteDependencies) }, }); } catch (err) { - if (lib.isEsError(err)) { - return response.customError({ - statusCode: err.statusCode, - body: err, - }); + if (isEsError(err)) { + return response.customError(formatEsError(err)); } // Case: default return response.internalError({ body: err }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts index 4aeb8e1d5520d..9489011939bbf 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts @@ -13,6 +13,7 @@ import { } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; +import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; import { registerGetRoute } from './register_get_route'; @@ -31,6 +32,7 @@ describe('[CCR API] Get one follower index', () => { } as License, lib: { isEsError, + formatEsError, }, }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts index 1e1a19234c801..77394fb705c9a 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts @@ -12,7 +12,11 @@ import { RouteDependencies } from '../../../types'; /** * Returns a single follower index pattern */ -export const registerGetRoute = ({ router, license, lib }: RouteDependencies) => { +export const registerGetRoute = ({ + router, + license, + lib: { isEsError, formatEsError }, +}: RouteDependencies) => { const paramsSchema = schema.object({ id: schema.string(), }); @@ -63,11 +67,8 @@ export const registerGetRoute = ({ router, license, lib }: RouteDependencies) => }); } } catch (err) { - if (lib.isEsError(err)) { - return response.customError({ - statusCode: err.statusCode, - body: err, - }); + if (isEsError(err)) { + return response.customError(formatEsError(err)); } // Case: default return response.internalError({ body: err }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.test.ts index fa86b30254e8c..3f1727a35e2b2 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.test.ts @@ -13,6 +13,7 @@ import { } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; +import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; import { registerPauseRoute } from './register_pause_route'; @@ -31,6 +32,7 @@ describe('[CCR API] Pause follower index/indices', () => { } as License, lib: { isEsError, + formatEsError, }, }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts index 6204c1856e489..8beffebed6c21 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts @@ -11,7 +11,11 @@ import { RouteDependencies } from '../../../types'; /** * Pauses a follower index */ -export const registerPauseRoute = ({ router, license, lib }: RouteDependencies) => { +export const registerPauseRoute = ({ + router, + license, + lib: { isEsError, formatEsError }, +}: RouteDependencies) => { const paramsSchema = schema.object({ id: schema.string() }); router.put( @@ -29,11 +33,8 @@ export const registerPauseRoute = ({ router, license, lib }: RouteDependencies) const errors: Array<{ id: string; error: any }> = []; const formatError = (err: any) => { - if (lib.isEsError(err)) { - return response.customError({ - statusCode: err.statusCode, - body: err, - }); + if (isEsError(err)) { + return response.customError(formatEsError(err)); } // Case: default return response.internalError({ body: err }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.test.ts index 6e1d802033c87..e21a105cbeb74 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.test.ts @@ -13,6 +13,7 @@ import { } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; +import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; import { registerResumeRoute } from './register_resume_route'; @@ -31,6 +32,7 @@ describe('[CCR API] Resume follower index/indices', () => { } as License, lib: { isEsError, + formatEsError, }, }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts index 6637ecded5864..2624a68001baf 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts @@ -11,7 +11,11 @@ import { RouteDependencies } from '../../../types'; /** * Resumes a follower index */ -export const registerResumeRoute = ({ router, license, lib }: RouteDependencies) => { +export const registerResumeRoute = ({ + router, + license, + lib: { isEsError, formatEsError }, +}: RouteDependencies) => { const paramsSchema = schema.object({ id: schema.string() }); router.put( @@ -29,11 +33,8 @@ export const registerResumeRoute = ({ router, license, lib }: RouteDependencies) const errors: Array<{ id: string; error: any }> = []; const formatError = (err: any) => { - if (lib.isEsError(err)) { - return response.customError({ - statusCode: err.statusCode, - body: err, - }); + if (isEsError(err)) { + return response.customError(formatEsError(err)); } // Case: default return response.internalError({ body: err }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.test.ts index 51b2c291d7a0e..3d2377f881252 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.test.ts @@ -13,6 +13,7 @@ import { } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; +import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; import { registerUnfollowRoute } from './register_unfollow_route'; @@ -31,6 +32,7 @@ describe('[CCR API] Unfollow follower index/indices', () => { } as License, lib: { isEsError, + formatEsError, }, }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts index 778839fc940f0..cde7697d7274d 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts @@ -11,7 +11,11 @@ import { RouteDependencies } from '../../../types'; /** * Unfollow follower index's leader index */ -export const registerUnfollowRoute = ({ router, license, lib }: RouteDependencies) => { +export const registerUnfollowRoute = ({ + router, + license, + lib: { isEsError, formatEsError }, +}: RouteDependencies) => { const paramsSchema = schema.object({ id: schema.string() }); router.put( @@ -30,11 +34,8 @@ export const registerUnfollowRoute = ({ router, license, lib }: RouteDependencie const errors: Array<{ id: string; error: any }> = []; const formatError = (err: any) => { - if (lib.isEsError(err)) { - return response.customError({ - statusCode: err.statusCode, - body: err, - }); + if (isEsError(err)) { + return response.customError(formatEsError(err)); } // Case: default return response.internalError({ body: err }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts index 1d964ed2a8c2a..da33a6e2b8061 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts @@ -14,7 +14,11 @@ import { RouteDependencies } from '../../../types'; /** * Update a follower index */ -export const registerUpdateRoute = ({ router, license, lib }: RouteDependencies) => { +export const registerUpdateRoute = ({ + router, + license, + lib: { isEsError, formatEsError }, +}: RouteDependencies) => { const paramsSchema = schema.object({ id: schema.string() }); router.put( @@ -60,11 +64,8 @@ export const registerUpdateRoute = ({ router, license, lib }: RouteDependencies) ), }); } catch (err) { - if (lib.isEsError(err)) { - return response.customError({ - statusCode: err.statusCode, - body: err, - }); + if (isEsError(err)) { + return response.customError(formatEsError(err)); } // Case: default return response.internalError({ body: err }); diff --git a/x-pack/plugins/cross_cluster_replication/server/types.ts b/x-pack/plugins/cross_cluster_replication/server/types.ts index 871b44fe99180..92a2d661e6be1 100644 --- a/x-pack/plugins/cross_cluster_replication/server/types.ts +++ b/x-pack/plugins/cross_cluster_replication/server/types.ts @@ -10,6 +10,7 @@ import { IndexManagementPluginSetup } from '../../index_management/server'; import { SecurityPluginSetup } from '../../security/server'; import { License } from './services'; import { isEsError } from './lib/is_es_error'; +import { formatEsError } from './lib/format_es_error'; export interface Dependencies { licensing: LicensingPluginSetup; @@ -23,5 +24,6 @@ export interface RouteDependencies { security?: SecurityPluginSetup; lib: { isEsError: typeof isEsError; + formatEsError: typeof formatEsError; }; } 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 ea94390ec25be..d03b1f83fb404 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 @@ -57,7 +57,8 @@ export default function({ getService }) { expect(body.attributes.cause[0]).to.contain('no such index'); }); - it('should create a follower index that follows an existing remote index', async () => { + // NOTE: If this test fails locally it's probably because you have another cluster running. + it('should create a follower index that follows an existing leader index', async () => { // First let's create an index to follow const leaderIndex = await createIndex(); @@ -65,7 +66,7 @@ export default function({ getService }) { const { body } = await createFollowerIndex(undefined, payload).expect(200); // There is a race condition in which Elasticsearch can respond without acknowledging, - // i.e. `body .follow_index_shards_acked` is sometimes true and sometimes false. + // i.e. `body.follow_index_shards_acked` is sometimes true and sometimes false. // By only asserting that `follow_index_created` is true, we eliminate this flakiness. expect(body.follow_index_created).to.eql(true); }); @@ -79,6 +80,7 @@ export default function({ getService }) { expect(body.attributes.cause[0]).to.contain('no such index'); }); + // NOTE: If this test fails locally it's probably because you have another cluster running. it('should return a follower index that was created', async () => { const leaderIndex = await createIndex(); From a38fc93b40da4d15e7bbc543b94dbabf7b706e75 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Wed, 15 Apr 2020 17:23:51 -0700 Subject: [PATCH 08/20] Make API route validation more strict. Incorporate bugfix from #63653. - Fix route validation errors and API request. --- .../auto_follow_pattern_edit.container.js | 19 +++++++++++++++-- .../app/store/actions/follower_index.js | 1 + .../register_create_route.ts | 12 +++++------ .../register_update_route.ts | 9 +++++++- .../follower_index/register_create_route.ts | 21 +++++++++++++------ .../follower_index/register_update_route.ts | 20 +++++++++++++++++- 6 files changed, 66 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.container.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.container.js index 2c90456076f85..be470edc07537 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.container.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/auto_follow_pattern_edit/auto_follow_pattern_edit.container.js @@ -39,8 +39,23 @@ const mapStateToProps = state => ({ const mapDispatchToProps = dispatch => ({ getAutoFollowPattern: id => dispatch(getAutoFollowPattern(id)), selectAutoFollowPattern: id => dispatch(selectEditAutoFollowPattern(id)), - saveAutoFollowPattern: (id, autoFollowPattern) => - dispatch(saveAutoFollowPattern(id, autoFollowPattern, true)), + saveAutoFollowPattern: (id, autoFollowPattern) => { + // Strip out errors. + const { active, remoteCluster, leaderIndexPatterns, followIndexPattern } = autoFollowPattern; + + dispatch( + saveAutoFollowPattern( + id, + { + active, + remoteCluster, + leaderIndexPatterns, + followIndexPattern, + }, + true + ) + ); + }, clearApiError: () => { dispatch(clearApiError(`${scope}-get`)); dispatch(clearApiError(`${scope}-save`)); diff --git a/x-pack/plugins/cross_cluster_replication/public/app/store/actions/follower_index.js b/x-pack/plugins/cross_cluster_replication/public/app/store/actions/follower_index.js index b6c0bb5ce401d..d081e0444eb58 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/store/actions/follower_index.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/store/actions/follower_index.js @@ -149,6 +149,7 @@ export const resumeFollowerIndex = id => scope, handler: async () => resumeFollowerIndexRequest(id), onSuccess(response, dispatch) { + console.log('response', response); /** * We can have 1 or more follower index resume operation * that can fail or succeed. We will show 1 toast notification for each. diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts index 91159315f51f9..bf8294496f05b 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts @@ -18,12 +18,12 @@ export const registerCreateRoute = ({ license, lib: { isEsError, formatEsError }, }: RouteDependencies) => { - const bodySchema = schema.object( - { - id: schema.string(), - }, - { unknowns: 'allow' } - ); + const bodySchema = schema.object({ + id: schema.string(), + remoteCluster: schema.string(), + leaderIndexPatterns: schema.arrayOf(schema.string()), + followIndexPattern: schema.string(), + }); router.post( { diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts index a99aee2aecc9f..cefc67e6af14b 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts @@ -22,12 +22,19 @@ export const registerUpdateRoute = ({ id: schema.string(), }); + const bodySchema = schema.object({ + active: schema.boolean(), + remoteCluster: schema.string(), + leaderIndexPatterns: schema.arrayOf(schema.string()), + followIndexPattern: schema.string(), + }); + router.put( { path: addBasePath('/auto_follow_patterns/{id}'), validate: { params: paramsSchema, - body: schema.object({}, { unknowns: 'allow' }), + body: bodySchema, }, }, license.guardApiRoute(async (context, request, response) => { diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts index 346bc98c1e952..1633fb0745549 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts @@ -19,12 +19,21 @@ export const registerCreateRoute = ({ license, lib: { isEsError, formatEsError }, }: RouteDependencies) => { - const bodySchema = schema.object( - { - name: schema.string(), - }, - { unknowns: 'allow' } - ); + const bodySchema = schema.object({ + name: schema.string(), + remoteCluster: schema.string(), + leaderIndex: schema.string(), + maxReadRequestOperationCount: schema.maybe(schema.number()), + maxOutstandingReadRequests: schema.maybe(schema.number()), + maxReadRequestSize: schema.maybe(schema.string()), // byte value + maxWriteRequestOperationCount: schema.maybe(schema.number()), + maxWriteRequestSize: schema.maybe(schema.string()), // byte value + maxOutstandingWriteRequests: schema.maybe(schema.number()), + maxWriteBufferCount: schema.maybe(schema.number()), + maxWriteBufferSize: schema.maybe(schema.string()), // byte value + maxRetryDelay: schema.maybe(schema.string()), // time value + readPollTimeout: schema.maybe(schema.string()), // time value + }); router.post( { diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts index da33a6e2b8061..c27d150e7dcdb 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts @@ -21,28 +21,45 @@ export const registerUpdateRoute = ({ }: RouteDependencies) => { const paramsSchema = schema.object({ id: schema.string() }); + const bodySchema = schema.object({ + maxReadRequestOperationCount: schema.maybe(schema.number()), + maxOutstandingReadRequests: schema.maybe(schema.number()), + maxReadRequestSize: schema.maybe(schema.string()), // byte value + maxWriteRequestOperationCount: schema.maybe(schema.number()), + maxWriteRequestSize: schema.maybe(schema.string()), // byte value + maxOutstandingWriteRequests: schema.maybe(schema.number()), + maxWriteBufferCount: schema.maybe(schema.number()), + maxWriteBufferSize: schema.maybe(schema.string()), // byte value + maxRetryDelay: schema.maybe(schema.string()), // time value + readPollTimeout: schema.maybe(schema.string()), // time value + }); + router.put( { path: addBasePath('/follower_indices/{id}'), validate: { params: paramsSchema, + body: bodySchema, }, }, license.guardApiRoute(async (context, request, response) => { const { id } = request.params as typeof paramsSchema.type; - // We need to first pause the follower and then resume it passing the advanced settings + // We need to first pause the follower and then resume it by passing the advanced settings try { const { follower_indices: followerIndices, } = await context.crossClusterReplication!.client.callAsCurrentUser('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 context.crossClusterReplication!.client.callAsCurrentUser( @@ -57,6 +74,7 @@ export const registerUpdateRoute = ({ const body = removeEmptyFields( serializeAdvancedSettings(request.body as FollowerIndexAdvancedSettings) ); + return response.ok({ body: await context.crossClusterReplication!.client.callAsCurrentUser( 'ccr.resumeFollowerIndex', From 74232162f7d16a9f632c40772ad2c94fc7759df5 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Wed, 15 Apr 2020 17:54:34 -0700 Subject: [PATCH 09/20] Sequester app-specific services into an asynchronously loaded mount function. --- .../public/app/index.tsx | 24 ++++++++++++++++++- .../public/app/services/breadcrumbs.ts | 2 +- .../public/plugin.ts | 19 +++++++-------- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/cross_cluster_replication/public/app/index.tsx b/x-pack/plugins/cross_cluster_replication/public/app/index.tsx index fe94245400920..06a7dd2d0b542 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/index.tsx +++ b/x-pack/plugins/cross_cluster_replication/public/app/index.tsx @@ -10,10 +10,12 @@ import { HashRouter } from 'react-router-dom'; import { I18nStart } from 'kibana/public'; import { UnmountCallback } from 'src/core/public'; +import { init as initBreadcrumbs, SetBreadcrumbs } from './services/breadcrumbs'; +import { init as initDocumentation } from './services/documentation_links'; import { App } from './app'; import { ccrStore } from './store'; -export const renderApp = (element: Element, I18nContext: I18nStart['Context']): UnmountCallback => { +const renderApp = (element: Element, I18nContext: I18nStart['Context']): UnmountCallback => { render( @@ -27,3 +29,23 @@ export const renderApp = (element: Element, I18nContext: I18nStart['Context']): return () => unmountComponentAtNode(element); }; + +export async function mountApp({ + element, + setBreadcrumbs, + I18nContext, + ELASTIC_WEBSITE_URL, + DOC_LINK_VERSION, +}: { + element: Element; + setBreadcrumbs: SetBreadcrumbs; + I18nContext: I18nStart['Context']; + ELASTIC_WEBSITE_URL: string; + DOC_LINK_VERSION: string; +}): UnmountCallback { + // Initialize additional services. + initBreadcrumbs(setBreadcrumbs); + initDocumentation(`${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/`); + + return renderApp(element, I18nContext); +} diff --git a/x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.ts b/x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.ts index cea6e66943a39..84ac9356462ad 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.ts +++ b/x-pack/plugins/cross_cluster_replication/public/app/services/breadcrumbs.ts @@ -11,7 +11,7 @@ import { ManagementAppMountParams } from '../../../../../../src/plugins/manageme import { BASE_PATH } from '../../../common/constants'; -type SetBreadcrumbs = ManagementAppMountParams['setBreadcrumbs']; +export type SetBreadcrumbs = ManagementAppMountParams['setBreadcrumbs']; let setBreadcrumbs: (crumbs: ChromeBreadcrumb[]) => void; diff --git a/x-pack/plugins/cross_cluster_replication/public/plugin.ts b/x-pack/plugins/cross_cluster_replication/public/plugin.ts index 05124eed8ec3d..3afddc5ea915b 100644 --- a/x-pack/plugins/cross_cluster_replication/public/plugin.ts +++ b/x-pack/plugins/cross_cluster_replication/public/plugin.ts @@ -10,8 +10,6 @@ import { first } from 'rxjs/operators'; import { CoreSetup, Plugin, PluginInitializerContext } from 'src/core/public'; import { PLUGIN } from '../common/constants'; -import { init as initBreadcrumbs } from './app/services/breadcrumbs'; -import { init as initDocumentation } from './app/services/documentation_links'; import { init as initUiMetric } from './app/services/track_ui_metric'; import { init as initNotification } from './app/services/notifications'; import { PluginDependencies, ClientConfigType } from './types'; @@ -53,20 +51,21 @@ export class CrossClusterReplicationPlugin implements Plugin { title: PLUGIN.TITLE, order: 4, mount: async ({ element, setBreadcrumbs }) => { + const { mountApp } = await import('./app'); + const [coreStart] = await getStartServices(); const { i18n: { Context: I18nContext }, docLinks: { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }, } = coreStart; - // Initialize additional services. - initBreadcrumbs(setBreadcrumbs); - initDocumentation( - `${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/` - ); - - const { renderApp } = await import('./app'); - return renderApp(element, I18nContext); + return mountApp({ + element, + setBreadcrumbs, + I18nContext, + ELASTIC_WEBSITE_URL, + DOC_LINK_VERSION, + }); }, }); From 155fcfc5d3dd8d948223bb5e2f4d10fa36930f59 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Wed, 15 Apr 2020 21:11:37 -0700 Subject: [PATCH 10/20] Disable UI and "Follower" index management badges when either the CCR UI or the Remote Clusters UI is disabled. - Publish isUiDisabled as part of Remote Clusters contract. --- .../cross_cluster_replication/public/plugin.ts | 13 +++++++------ .../cross_cluster_replication/public/types.ts | 2 ++ .../cross_cluster_replication/server/plugin.ts | 9 +++++++-- .../cross_cluster_replication/server/types.ts | 2 ++ x-pack/plugins/remote_clusters/public/index.ts | 3 +++ .../plugins/remote_clusters/public/plugin.ts | 11 ++++++++++- x-pack/plugins/remote_clusters/server/index.ts | 1 + .../plugins/remote_clusters/server/plugin.ts | 18 +++++++++++++++--- 8 files changed, 47 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/cross_cluster_replication/public/plugin.ts b/x-pack/plugins/cross_cluster_replication/public/plugin.ts index 3afddc5ea915b..dff19f4b6d1d1 100644 --- a/x-pack/plugins/cross_cluster_replication/public/plugin.ts +++ b/x-pack/plugins/cross_cluster_replication/public/plugin.ts @@ -21,15 +21,18 @@ export class CrossClusterReplicationPlugin implements Plugin { constructor(private readonly initializerContext: PluginInitializerContext) {} public setup(coreSetup: CoreSetup, plugins: PluginDependencies) { - plugins.licensing.license$ + const { licensing, remoteClusters, usageCollection, management, indexManagement } = plugins; + + licensing.license$ .pipe(first()) .toPromise() .then(license => { const isLicenseOk = license.isAvailable && license.isActive; - const { - ui: { enabled: isCcrUiEnabled }, - } = this.initializerContext.config.get(); + const config = this.initializerContext.config.get(); + + // The UI is also dependent upon the Remote Clusters UI. + const isCcrUiEnabled = config.ui.enabled && remoteClusters.isUiEnabled; if (isLicenseOk && isCcrUiEnabled) { const { @@ -39,8 +42,6 @@ export class CrossClusterReplicationPlugin implements Plugin { getStartServices, } = coreSetup; - const { usageCollection, management, indexManagement } = plugins; - // Initialize services even if the app isn't mounted, because they're used by index management extensions. setHttpClient(http); initUiMetric(usageCollection); diff --git a/x-pack/plugins/cross_cluster_replication/public/types.ts b/x-pack/plugins/cross_cluster_replication/public/types.ts index 8645541cdbd84..aac174b7524d3 100644 --- a/x-pack/plugins/cross_cluster_replication/public/types.ts +++ b/x-pack/plugins/cross_cluster_replication/public/types.ts @@ -7,12 +7,14 @@ import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/public'; import { ManagementSetup } from '../../../../src/plugins/management/public'; import { IndexManagementPluginSetup } from '../../index_management/public'; +import { RemoteClustersPluginSetup } from '../../remote_clusters/public'; import { LicensingPluginSetup } from '../../licensing/public'; export interface PluginDependencies { usageCollection: UsageCollectionSetup; management: ManagementSetup; indexManagement: IndexManagementPluginSetup; + remoteClusters: RemoteClustersPluginSetup; licensing: LicensingPluginSetup; } diff --git a/x-pack/plugins/cross_cluster_replication/server/plugin.ts b/x-pack/plugins/cross_cluster_replication/server/plugin.ts index 5d4676a6b7234..d1960300392e0 100644 --- a/x-pack/plugins/cross_cluster_replication/server/plugin.ts +++ b/x-pack/plugins/cross_cluster_replication/server/plugin.ts @@ -78,7 +78,7 @@ export class CrossClusterReplicationServerPlugin implements Plugin { const router = http.createRouter(); const config = await this.config$.pipe(first()).toPromise(); @@ -116,7 +116,12 @@ export class CrossClusterReplicationServerPlugin implements Plugin new RemoteClustersUIPlugin(initializerContext); diff --git a/x-pack/plugins/remote_clusters/public/plugin.ts b/x-pack/plugins/remote_clusters/public/plugin.ts index d110c461c1e3f..22f98e94748d8 100644 --- a/x-pack/plugins/remote_clusters/public/plugin.ts +++ b/x-pack/plugins/remote_clusters/public/plugin.ts @@ -14,7 +14,12 @@ import { init as initNotification } from './application/services/notification'; import { init as initRedirect } from './application/services/redirect'; import { Dependencies, ClientConfigType } from './types'; -export class RemoteClustersUIPlugin implements Plugin { +export interface RemoteClustersPluginSetup { + isUiEnabled: boolean; +} + +export class RemoteClustersUIPlugin + implements Plugin { constructor(private readonly initializerContext: PluginInitializerContext) {} setup( @@ -55,6 +60,10 @@ export class RemoteClustersUIPlugin implements Plugin new RemoteClustersServerPlugin(ctx); diff --git a/x-pack/plugins/remote_clusters/server/plugin.ts b/x-pack/plugins/remote_clusters/server/plugin.ts index fca4a5dbc5f94..a7ca30a6bf96d 100644 --- a/x-pack/plugins/remote_clusters/server/plugin.ts +++ b/x-pack/plugins/remote_clusters/server/plugin.ts @@ -7,6 +7,7 @@ import { i18n } from '@kbn/i18n'; import { CoreSetup, Logger, Plugin, PluginInitializerContext } from 'src/core/server'; import { Observable } from 'rxjs'; +import { first } from 'rxjs/operators'; import { PLUGIN } from '../common/constants'; import { Dependencies, LicenseStatus, RouteDependencies } from './types'; @@ -18,19 +19,26 @@ import { registerDeleteRoute, } from './routes/api'; -export class RemoteClustersServerPlugin implements Plugin { +export interface RemoteClustersPluginSetup { + isUiEnabled: boolean; +} + +export class RemoteClustersServerPlugin + implements Plugin { licenseStatus: LicenseStatus; log: Logger; - config: Observable; + config$: Observable; constructor({ logger, config }: PluginInitializerContext) { this.log = logger.get(); - this.config = config.create(); + this.config$ = config.create(); this.licenseStatus = { valid: false }; } async setup({ http }: CoreSetup, { licensing, cloud }: Dependencies) { const router = http.createRouter(); + const config = await this.config$.pipe(first()).toPromise(); + const routeDependencies: RouteDependencies = { router, getLicenseStatus: () => this.licenseStatus, @@ -64,6 +72,10 @@ export class RemoteClustersServerPlugin implements Plugin } } }); + + return { + isUiEnabled: config.ui.enabled, + }; } start() {} From 80766051496a88573fdc3bc31455e18702cd1dbe Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Thu, 16 Apr 2020 16:35:31 -0700 Subject: [PATCH 11/20] Default trackUiMetric service to be a no-op. --- .../public/app/services/track_ui_metric.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/cross_cluster_replication/public/app/services/track_ui_metric.ts b/x-pack/plugins/cross_cluster_replication/public/app/services/track_ui_metric.ts index 010155a2730ad..aecc4eb83893f 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/services/track_ui_metric.ts +++ b/x-pack/plugins/cross_cluster_replication/public/app/services/track_ui_metric.ts @@ -11,7 +11,8 @@ import { UIM_APP_NAME } from '../constants'; export { METRIC_TYPE }; -export let trackUiMetric: (metricType: UiStatsMetricType, eventName: string) => void; +// usageCollection is an optional dependency, so we default to a no-op. +export let trackUiMetric = (metricType: UiStatsMetricType, eventName: string) => {}; export function init(usageCollection: UsageCollectionSetup): void { trackUiMetric = usageCollection.reportUiStats.bind(usageCollection, UIM_APP_NAME); From 1daf9ad5a302f2b7221b4e001b5bf960eb267ea3 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Fri, 17 Apr 2020 16:31:47 -0700 Subject: [PATCH 12/20] Clean up permissions, security, and stats logic. - Remove security dependency. - Render timestamp for autofollow errors. - Fix license check so that CCR won't render if the license is invalid. - Fix server security check to be more precise by checking if ES has security disabled. --- .../common/constants/index.ts | 5 +++-- .../plugins/cross_cluster_replication/common/types.ts | 2 ++ x-pack/plugins/cross_cluster_replication/kibana.json | 3 +-- .../auto_follow_pattern_list.test.js | 4 +++- .../cross_cluster_replication/public/app/index.tsx | 2 +- .../components/detail_panel/detail_panel.js | 3 +++ .../public/app/services/auto_follow_errors.js | 3 ++- .../cross_cluster_replication/public/plugin.ts | 8 ++++---- .../ccr_stats_serialization.test.ts.snap | 2 ++ .../server/lib/ccr_stats_serialization.test.ts | 2 ++ .../server/lib/ccr_stats_serialization.ts | 2 ++ .../cross_cluster_replication/server/plugin.ts | 3 +-- .../register_permissions_route.ts | 6 +++--- .../server/services/license.ts | 11 +++++++++++ .../plugins/cross_cluster_replication/server/types.ts | 3 --- 15 files changed, 40 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/cross_cluster_replication/common/constants/index.ts b/x-pack/plugins/cross_cluster_replication/common/constants/index.ts index cad3b5cae83f0..797141b0996af 100644 --- a/x-pack/plugins/cross_cluster_replication/common/constants/index.ts +++ b/x-pack/plugins/cross_cluster_replication/common/constants/index.ts @@ -11,7 +11,7 @@ import { LicenseType } from '../../../licensing/common/types'; const platinumLicense: LicenseType = 'platinum'; export const PLUGIN = { - ID: 'cross_cluster_replication', + ID: 'crossClusterReplication', TITLE: i18n.translate('xpack.crossClusterReplication.appTitle', { defaultMessage: 'Cross-Cluster Replication', }), @@ -23,7 +23,8 @@ export const APPS = { REMOTE_CLUSTER_APP: 'remote_cluster', }; -export const BASE_PATH = '/management/elasticsearch/cross_cluster_replication'; +export const MANAGEMENT_ID = 'cross_cluster_replication'; +export const BASE_PATH = `/management/elasticsearch/${MANAGEMENT_ID}`; export const BASE_PATH_REMOTE_CLUSTERS = '/management/elasticsearch/remote_clusters'; export const API_BASE_PATH = '/api/cross_cluster_replication'; export const API_REMOTE_CLUSTERS_BASE_PATH = '/api/remote_clusters'; diff --git a/x-pack/plugins/cross_cluster_replication/common/types.ts b/x-pack/plugins/cross_cluster_replication/common/types.ts index 0cfaf729c9f39..4932d6c570297 100644 --- a/x-pack/plugins/cross_cluster_replication/common/types.ts +++ b/x-pack/plugins/cross_cluster_replication/common/types.ts @@ -140,6 +140,7 @@ export interface FollowerIndexAdvancedSettingsToEs { } export interface RecentAutoFollowError { + timestamp: number; leaderIndex: string; autoFollowException: { type: string; @@ -148,6 +149,7 @@ export interface RecentAutoFollowError { } export interface RecentAutoFollowErrorFromEs { + timestamp: number; leader_index: string; auto_follow_exception: { type: string; diff --git a/x-pack/plugins/cross_cluster_replication/kibana.json b/x-pack/plugins/cross_cluster_replication/kibana.json index 21e878ea153cf..ccf98f41def47 100644 --- a/x-pack/plugins/cross_cluster_replication/kibana.json +++ b/x-pack/plugins/cross_cluster_replication/kibana.json @@ -11,8 +11,7 @@ "indexManagement" ], "optionalPlugins": [ - "usageCollection", - "security" + "usageCollection" ], "configPath": ["xpack", "ccr"] } diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_list.test.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_list.test.js index 5941b8ef71a19..190400e988634 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_list.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/auto_follow_pattern_list.test.js @@ -302,10 +302,12 @@ describe('', () => { const message = 'bar'; const recentAutoFollowErrors = [ { + timestamp: 1587081600021, leaderIndex: `${autoFollowPattern1.name}:my-leader-test`, autoFollowException: { type: 'exception', reason: message }, }, { + timestamp: 1587081600021, leaderIndex: `${autoFollowPattern2.name}:my-leader-test`, autoFollowException: { type: 'exception', reason: message }, }, @@ -324,7 +326,7 @@ describe('', () => { expect(exists('autoFollowPatternDetail.errors')).toBe(true); expect(exists('autoFollowPatternDetail.titleErrors')).toBe(true); expect(find('autoFollowPatternDetail.recentError').map(error => error.text())).toEqual([ - message, + 'April 16th, 2020 8:00:00 PM: bar', ]); }); }); diff --git a/x-pack/plugins/cross_cluster_replication/public/app/index.tsx b/x-pack/plugins/cross_cluster_replication/public/app/index.tsx index 06a7dd2d0b542..0eb3eb3469ca0 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/index.tsx +++ b/x-pack/plugins/cross_cluster_replication/public/app/index.tsx @@ -42,7 +42,7 @@ export async function mountApp({ I18nContext: I18nStart['Context']; ELASTIC_WEBSITE_URL: string; DOC_LINK_VERSION: string; -}): UnmountCallback { +}): Promise { // Initialize additional services. initBreadcrumbs(setBreadcrumbs); initDocumentation(`${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/`); diff --git a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js index 51db467cc78b1..3f2ed82420ff1 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/sections/home/auto_follow_pattern_list/components/detail_panel/detail_panel.js @@ -7,6 +7,8 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from '@kbn/i18n/react'; +import moment from 'moment'; + import { getIndexListUri } from '../../../../../../../../../plugins/index_management/public'; import { @@ -247,6 +249,7 @@ export class DetailPanel extends Component {
    {autoFollowPattern.errors.map((error, i) => (
  • + {moment(error.timestamp).format('MMMM Do, YYYY h:mm:ss A')}:{' '} {error.autoFollowException.reason}
  • ))} diff --git a/x-pack/plugins/cross_cluster_replication/public/app/services/auto_follow_errors.js b/x-pack/plugins/cross_cluster_replication/public/app/services/auto_follow_errors.js index 95aa3f0ebc3e4..70311d5ba1e4d 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/services/auto_follow_errors.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/services/auto_follow_errors.js @@ -9,11 +9,12 @@ export const parseAutoFollowError = error => { return null; } - const { leaderIndex, autoFollowException } = error; + const { leaderIndex, autoFollowException, timestamp } = error; const id = leaderIndex.substring(0, leaderIndex.lastIndexOf(':')); return { id, + timestamp, leaderIndex, autoFollowException, }; diff --git a/x-pack/plugins/cross_cluster_replication/public/plugin.ts b/x-pack/plugins/cross_cluster_replication/public/plugin.ts index dff19f4b6d1d1..c41b9e0c00840 100644 --- a/x-pack/plugins/cross_cluster_replication/public/plugin.ts +++ b/x-pack/plugins/cross_cluster_replication/public/plugin.ts @@ -9,7 +9,7 @@ import { get } from 'lodash'; import { first } from 'rxjs/operators'; import { CoreSetup, Plugin, PluginInitializerContext } from 'src/core/public'; -import { PLUGIN } from '../common/constants'; +import { PLUGIN, MANAGEMENT_ID } from '../common/constants'; import { init as initUiMetric } from './app/services/track_ui_metric'; import { init as initNotification } from './app/services/notifications'; import { PluginDependencies, ClientConfigType } from './types'; @@ -27,8 +27,8 @@ export class CrossClusterReplicationPlugin implements Plugin { .pipe(first()) .toPromise() .then(license => { - const isLicenseOk = license.isAvailable && license.isActive; - + const licenseStatus = license.check(PLUGIN.ID, PLUGIN.minimumLicenseType); + const isLicenseOk = licenseStatus.state === 'valid'; const config = this.initializerContext.config.get(); // The UI is also dependent upon the Remote Clusters UI. @@ -48,7 +48,7 @@ export class CrossClusterReplicationPlugin implements Plugin { initNotification(toasts, fatalErrors); management.sections.getSection('elasticsearch')!.registerApp({ - id: PLUGIN.ID, + id: MANAGEMENT_ID, title: PLUGIN.TITLE, order: 4, mount: async ({ element, setBreadcrumbs }) => { diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/__snapshots__/ccr_stats_serialization.test.ts.snap b/x-pack/plugins/cross_cluster_replication/server/lib/__snapshots__/ccr_stats_serialization.test.ts.snap index 92ac6070904b5..3eced37112a35 100644 --- a/x-pack/plugins/cross_cluster_replication/server/lib/__snapshots__/ccr_stats_serialization.test.ts.snap +++ b/x-pack/plugins/cross_cluster_replication/server/lib/__snapshots__/ccr_stats_serialization.test.ts.snap @@ -19,6 +19,7 @@ Object { "type": "exception", }, "leaderIndex": "pattern-1:kibana_sample_1", + "timestamp": 1587081600021, }, Object { "autoFollowException": Object { @@ -26,6 +27,7 @@ Object { "type": "exception", }, "leaderIndex": "pattern-2:kibana_sample_1", + "timestamp": 1587081600021, }, ], } diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.test.ts b/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.test.ts index 5120c56701e5b..5141aa56c1d7e 100644 --- a/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.test.ts @@ -15,6 +15,7 @@ describe('[CCR] auto-follow stats serialization', () => { recent_auto_follow_errors: [ { leader_index: 'pattern-1:kibana_sample_1', + timestamp: 1587081600021, auto_follow_exception: { type: 'exception', reason: @@ -23,6 +24,7 @@ describe('[CCR] auto-follow stats serialization', () => { }, { leader_index: 'pattern-2:kibana_sample_1', + timestamp: 1587081600021, auto_follow_exception: { type: 'exception', reason: diff --git a/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.ts b/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.ts index e972f6ddc20ec..7e2b088919842 100644 --- a/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.ts +++ b/x-pack/plugins/cross_cluster_replication/server/lib/ccr_stats_serialization.ts @@ -14,9 +14,11 @@ import { } from '../../common/types'; export const deserializeRecentAutoFollowErrors = ({ + timestamp, leader_index, auto_follow_exception: { type, reason }, }: RecentAutoFollowErrorFromEs): RecentAutoFollowError => ({ + timestamp, leaderIndex: leader_index, autoFollowException: { type, diff --git a/x-pack/plugins/cross_cluster_replication/server/plugin.ts b/x-pack/plugins/cross_cluster_replication/server/plugin.ts index d1960300392e0..19865569f3760 100644 --- a/x-pack/plugins/cross_cluster_replication/server/plugin.ts +++ b/x-pack/plugins/cross_cluster_replication/server/plugin.ts @@ -78,7 +78,7 @@ export class CrossClusterReplicationServerPlugin implements Plugin { const router = http.createRouter(); const config = await this.config$.pipe(first()).toPromise(); @@ -109,7 +109,6 @@ export class CrossClusterReplicationServerPlugin implements Plugin { router.get( { @@ -22,8 +21,9 @@ export const registerPermissionsRoute = ({ validate: false, }, license.guardApiRoute(async (context, request, response) => { - if (!security) { - // If security isn't enabled or available (in the case where security is enabled but license reverted to Basic) let the user use CCR. + if (!license.isEsSecurityEnabled) { + // If security has been disabled in elasticsearch.yml. we'll just let the user use CCR + // because permissions are irrelevant. return response.ok({ body: { hasPermission: true, diff --git a/x-pack/plugins/cross_cluster_replication/server/services/license.ts b/x-pack/plugins/cross_cluster_replication/server/services/license.ts index 31d3654c51e3e..c45fc87948613 100644 --- a/x-pack/plugins/cross_cluster_replication/server/services/license.ts +++ b/x-pack/plugins/cross_cluster_replication/server/services/license.ts @@ -31,6 +31,8 @@ export class License { message: 'Invalid License', }; + private _isEsSecurityEnabled: boolean = false; + setup( { pluginId, minimumLicenseType, defaultErrorMessage }: SetupSettings, { licensing, logger }: { licensing: LicensingPluginSetup; logger: Logger } @@ -39,6 +41,10 @@ export class License { const { state, message } = license.check(pluginId, minimumLicenseType); const hasRequiredLicense = state === 'valid'; + // Retrieving security checks the results of GET /_xpack as well as license state, + // so we're also checking whether the security is disabled in elasticsearch.yml. + this._isEsSecurityEnabled = license.getFeature('security').isEnabled; + if (hasRequiredLicense) { this.licenseStatus = { isValid: true }; } else { @@ -79,4 +85,9 @@ export class License { getStatus() { return this.licenseStatus; } + + // eslint-disable-next-line @typescript-eslint/explicit-member-accessibility + get isEsSecurityEnabled() { + return this._isEsSecurityEnabled; + } } diff --git a/x-pack/plugins/cross_cluster_replication/server/types.ts b/x-pack/plugins/cross_cluster_replication/server/types.ts index d5b542513eb9f..049d440e3d85d 100644 --- a/x-pack/plugins/cross_cluster_replication/server/types.ts +++ b/x-pack/plugins/cross_cluster_replication/server/types.ts @@ -8,7 +8,6 @@ import { IRouter } from 'src/core/server'; import { LicensingPluginSetup } from '../../licensing/server'; import { IndexManagementPluginSetup } from '../../index_management/server'; import { RemoteClustersPluginSetup } from '../../remote_clusters/server'; -import { SecurityPluginSetup } from '../../security/server'; import { License } from './services'; import { isEsError } from './lib/is_es_error'; import { formatEsError } from './lib/format_es_error'; @@ -17,13 +16,11 @@ export interface Dependencies { licensing: LicensingPluginSetup; indexManagement: IndexManagementPluginSetup; remoteClusters: RemoteClustersPluginSetup; - security?: SecurityPluginSetup; } export interface RouteDependencies { router: IRouter; license: License; - security?: SecurityPluginSetup; lib: { isEsError: typeof isEsError; formatEsError: typeof formatEsError; From af76d67c00d3823351af12960e866937f92a252a Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Sun, 19 Apr 2020 08:21:07 -0700 Subject: [PATCH 13/20] Fix API integration tests. --- .../auto_follow_pattern.helpers.js | 20 +++---- .../auto_follow_pattern.js | 56 ++++++++++++------- .../cross_cluster_replication/fixtures.js | 7 --- 3 files changed, 43 insertions(+), 40 deletions(-) diff --git a/x-pack/test/api_integration/apis/management/cross_cluster_replication/auto_follow_pattern.helpers.js b/x-pack/test/api_integration/apis/management/cross_cluster_replication/auto_follow_pattern.helpers.js index 22f0bde50b073..b9a0bfd40a8d6 100644 --- a/x-pack/test/api_integration/apis/management/cross_cluster_replication/auto_follow_pattern.helpers.js +++ b/x-pack/test/api_integration/apis/management/cross_cluster_replication/auto_follow_pattern.helpers.js @@ -5,33 +5,27 @@ */ import { API_BASE_PATH } from './constants'; -import { getRandomString } from './lib'; -import { getAutoFollowIndexPayload } from './fixtures'; export const registerHelpers = supertest => { let autoFollowPatternsCreated = []; const loadAutoFollowPatterns = () => supertest.get(`${API_BASE_PATH}/auto_follow_patterns`); - const getAutoFollowPattern = name => - supertest.get(`${API_BASE_PATH}/auto_follow_patterns/${name}`); + const getAutoFollowPattern = id => supertest.get(`${API_BASE_PATH}/auto_follow_patterns/${id}`); - const createAutoFollowPattern = ( - name = getRandomString(), - payload = getAutoFollowIndexPayload() - ) => { - autoFollowPatternsCreated.push(name); + const createAutoFollowPattern = payload => { + autoFollowPatternsCreated.push(payload.id); return supertest .post(`${API_BASE_PATH}/auto_follow_patterns`) .set('kbn-xsrf', 'xxx') - .send({ ...payload, id: name }); + .send(payload); }; - const deleteAutoFollowPattern = name => { - autoFollowPatternsCreated = autoFollowPatternsCreated.filter(c => c !== name); + const deleteAutoFollowPattern = id => { + autoFollowPatternsCreated = autoFollowPatternsCreated.filter(c => c !== id); - return supertest.delete(`${API_BASE_PATH}/auto_follow_patterns/${name}`).set('kbn-xsrf', 'xxx'); + return supertest.delete(`${API_BASE_PATH}/auto_follow_patterns/${id}`).set('kbn-xsrf', 'xxx'); }; const deleteAllAutoFollowPatterns = () => 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 f424570737541..7a95ba7fcd981 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 @@ -6,8 +6,7 @@ import expect from '@kbn/expect'; -import { getRandomString } from './lib'; -import { getAutoFollowIndexPayload } from './fixtures'; +import { REMOTE_CLUSTER_NAME } from './constants'; import { registerHelpers as registerRemoteClustersHelpers } from './remote_clusters.helpers'; import { registerHelpers as registerAutoFollowPatternHelpers } from './auto_follow_pattern.helpers'; @@ -37,43 +36,60 @@ export default function({ getService }) { describe('when remote cluster does not exist', () => { it('should throw a 404 error when cluster is unknown', async () => { - const payload = getAutoFollowIndexPayload(); - payload.remoteCluster = 'unknown-cluster'; + const { body } = await createAutoFollowPattern({ + id: 'pattern0', + remoteCluster: 'unknown-cluster', + leaderIndexPatterns: ['leader-*'], + followIndexPattern: '{{leader_index}}_follower', + }); - const { body } = await createAutoFollowPattern(undefined, payload).expect(404); + expect(body.statusCode).to.be(404); expect(body.attributes.cause[0]).to.contain('no such remote cluster'); }); }); describe('when remote cluster exists', () => { - before(() => addCluster()); + before(async () => addCluster()); describe('create()', () => { it('should create an auto-follow pattern when cluster is known', async () => { - const name = getRandomString(); - const { body } = await createAutoFollowPattern(name).expect(200); - + const { body, statusCode } = await createAutoFollowPattern({ + id: 'pattern1', + remoteCluster: REMOTE_CLUSTER_NAME, + leaderIndexPatterns: ['leader-*'], + followIndexPattern: '{{leader_index}}_follower', + }); + + expect(statusCode).to.be(200); expect(body.acknowledged).to.eql(true); }); }); describe('get()', () => { it('should return a 404 when the auto-follow pattern is not found', async () => { - const name = getRandomString(); - const { body } = await getAutoFollowPattern(name).expect(404); - + const { body } = await getAutoFollowPattern('missing-pattern'); + expect(body.statusCode).to.be(404); expect(body.attributes.cause).not.to.be(undefined); }); it('should return an auto-follow pattern that was created', async () => { - const name = getRandomString(); - const autoFollowPattern = getAutoFollowIndexPayload(); - - await createAutoFollowPattern(name, autoFollowPattern); - - const { body } = await getAutoFollowPattern(name).expect(200); - - expect(body).to.eql({ ...autoFollowPattern, name }); + await createAutoFollowPattern({ + id: 'pattern2', + remoteCluster: REMOTE_CLUSTER_NAME, + leaderIndexPatterns: ['leader-*'], + followIndexPattern: '{{leader_index}}_follower', + }); + + const { body, statusCode } = await getAutoFollowPattern('pattern2'); + + expect(statusCode).to.be(200); + expect(body).to.eql({ + name: 'pattern2', + remoteCluster: REMOTE_CLUSTER_NAME, + active: true, + leaderIndexPatterns: ['leader-*'], + followIndexPattern: '{{leader_index}}_follower', + }); }); }); }); diff --git a/x-pack/test/api_integration/apis/management/cross_cluster_replication/fixtures.js b/x-pack/test/api_integration/apis/management/cross_cluster_replication/fixtures.js index de47f5d9ea85e..6e254b27356f2 100644 --- a/x-pack/test/api_integration/apis/management/cross_cluster_replication/fixtures.js +++ b/x-pack/test/api_integration/apis/management/cross_cluster_replication/fixtures.js @@ -7,13 +7,6 @@ import { REMOTE_CLUSTER_NAME } from './constants'; import { getRandomString } from './lib'; -export const getAutoFollowIndexPayload = (remoteCluster = REMOTE_CLUSTER_NAME, active = true) => ({ - active, - remoteCluster, - leaderIndexPatterns: ['leader-*'], - followIndexPattern: '{{leader_index}}_follower', -}); - export const getFollowerIndexPayload = ( leaderIndexName = getRandomString(), remoteCluster = REMOTE_CLUSTER_NAME, From 8654d34b47a8a83e7a6e88239d6f806a888e1823 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Sun, 19 Apr 2020 10:30:47 -0700 Subject: [PATCH 14/20] Fix i18n. --- x-pack/.i18nrc.json | 2 +- .../cross_cluster_replication/server/plugin.ts | 9 ++++++--- .../plugins/translations/translations/ja-JP.json | 15 ++++++--------- .../plugins/translations/translations/zh-CN.json | 15 ++++++--------- 4 files changed, 19 insertions(+), 22 deletions(-) diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index c8715ac3447bd..8e5563e4ff674 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -8,7 +8,7 @@ "xpack.apm": ["legacy/plugins/apm", "plugins/apm"], "xpack.beatsManagement": "legacy/plugins/beats_management", "xpack.canvas": "legacy/plugins/canvas", - "xpack.crossClusterReplication": "legacy/plugins/cross_cluster_replication", + "xpack.crossClusterReplication": "plugins/cross_cluster_replication", "xpack.dashboardMode": "legacy/plugins/dashboard_mode", "xpack.data": "plugins/data_enhanced", "xpack.drilldowns": "plugins/drilldowns", diff --git a/x-pack/plugins/cross_cluster_replication/server/plugin.ts b/x-pack/plugins/cross_cluster_replication/server/plugin.ts index 19865569f3760..39b71eac54781 100644 --- a/x-pack/plugins/cross_cluster_replication/server/plugin.ts +++ b/x-pack/plugins/cross_cluster_replication/server/plugin.ts @@ -87,9 +87,12 @@ export class CrossClusterReplicationServerPlugin implements Plugin Date: Sun, 19 Apr 2020 10:36:07 -0700 Subject: [PATCH 15/20] Fix index management API integration tests. --- .../apis/management/index_management/indices.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/test/api_integration/apis/management/index_management/indices.js b/x-pack/test/api_integration/apis/management/index_management/indices.js index 7195b8680a286..d2d07eca475e7 100644 --- a/x-pack/test/api_integration/apis/management/index_management/indices.js +++ b/x-pack/test/api_integration/apis/management/index_management/indices.js @@ -193,10 +193,10 @@ export default function({ getService }) { 'size', 'isFrozen', 'aliases', - 'ilm', // data enricher - 'isRollupIndex', // data enricher // Cloud disables CCR, so wouldn't expect follower indices. 'isFollowerIndex', // data enricher + 'ilm', // data enricher + 'isRollupIndex', // data enricher ]; expect(Object.keys(body[0])).to.eql(expectedKeys); }); @@ -219,10 +219,10 @@ export default function({ getService }) { 'size', 'isFrozen', 'aliases', - 'ilm', // data enricher - 'isRollupIndex', // data enricher // Cloud disables CCR, so wouldn't expect follower indices. 'isFollowerIndex', // data enricher + 'ilm', // data enricher + 'isRollupIndex', // data enricher ]; expect(Object.keys(body[0])).to.eql(expectedKeys); expect(body.length > 1).to.be(true); // to contrast it with the next test From 032b84419a131156069d930f943555543992da78 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Tue, 21 Apr 2020 11:48:07 -0700 Subject: [PATCH 16/20] Address JL's feedback: - Import and use History type. - Make public and server plugin setup functions synchronous. - Add comments to explain role of remote_clusters.ui.enabled setting and purpose for initializing services inside of the app mount function. --- .../public/app/app.tsx | 6 +- .../public/app/index.tsx | 3 +- .../public/plugin.ts | 77 ++++++++++--------- .../server/plugin.ts | 36 +++++---- 4 files changed, 66 insertions(+), 56 deletions(-) diff --git a/x-pack/plugins/cross_cluster_replication/public/app/app.tsx b/x-pack/plugins/cross_cluster_replication/public/app/app.tsx index 1a5da373cf37f..ec349ccd6f2c7 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/app.tsx +++ b/x-pack/plugins/cross_cluster_replication/public/app/app.tsx @@ -6,6 +6,7 @@ import React, { Component, Fragment } from 'react'; import { Route, Switch, Redirect, withRouter, RouteComponentProps } from 'react-router-dom'; +import { History } from 'history'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -36,10 +37,7 @@ import { } from './sections'; interface AppProps { - history: { - push: any; - createHref: any; - }; + history: History; location: any; } diff --git a/x-pack/plugins/cross_cluster_replication/public/app/index.tsx b/x-pack/plugins/cross_cluster_replication/public/app/index.tsx index 0eb3eb3469ca0..79569b587f97f 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/index.tsx +++ b/x-pack/plugins/cross_cluster_replication/public/app/index.tsx @@ -43,7 +43,8 @@ export async function mountApp({ ELASTIC_WEBSITE_URL: string; DOC_LINK_VERSION: string; }): Promise { - // Initialize additional services. + // Import and initialize additional services here instead of in plugin.ts to reduce the size of the + // initial bundle as much as possible. initBreadcrumbs(setBreadcrumbs); initDocumentation(`${ELASTIC_WEBSITE_URL}guide/en/elasticsearch/reference/${DOC_LINK_VERSION}/`); diff --git a/x-pack/plugins/cross_cluster_replication/public/plugin.ts b/x-pack/plugins/cross_cluster_replication/public/plugin.ts index c41b9e0c00840..bdaa04e9d53ee 100644 --- a/x-pack/plugins/cross_cluster_replication/public/plugin.ts +++ b/x-pack/plugins/cross_cluster_replication/public/plugin.ts @@ -22,6 +22,44 @@ export class CrossClusterReplicationPlugin implements Plugin { public setup(coreSetup: CoreSetup, plugins: PluginDependencies) { const { licensing, remoteClusters, usageCollection, management, indexManagement } = plugins; + const esSection = management.sections.getSection('elasticsearch'); + + const { + http, + notifications: { toasts }, + fatalErrors, + getStartServices, + } = coreSetup; + + // Initialize services even if the app isn't mounted, because they're used by index management extensions. + setHttpClient(http); + initUiMetric(usageCollection); + initNotification(toasts, fatalErrors); + + const ccrApp = esSection!.registerApp({ + id: MANAGEMENT_ID, + title: PLUGIN.TITLE, + order: 4, + mount: async ({ element, setBreadcrumbs }) => { + const { mountApp } = await import('./app'); + + const [coreStart] = await getStartServices(); + const { + i18n: { Context: I18nContext }, + docLinks: { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }, + } = coreStart; + + return mountApp({ + element, + setBreadcrumbs, + I18nContext, + ELASTIC_WEBSITE_URL, + DOC_LINK_VERSION, + }); + }, + }); + + ccrApp.disable(); licensing.license$ .pipe(first()) @@ -31,44 +69,13 @@ export class CrossClusterReplicationPlugin implements Plugin { const isLicenseOk = licenseStatus.state === 'valid'; const config = this.initializerContext.config.get(); - // The UI is also dependent upon the Remote Clusters UI. + // remoteClusters.isUiEnabled is driven by the xpack.remote_clusters.ui.enabled setting. + // The CCR UI depends upon the Remote Clusters UI (e.g. by cross-linking to it), so if + // the Remote Clusters UI is disabled we can't show the CCR UI. const isCcrUiEnabled = config.ui.enabled && remoteClusters.isUiEnabled; if (isLicenseOk && isCcrUiEnabled) { - const { - http, - notifications: { toasts }, - fatalErrors, - getStartServices, - } = coreSetup; - - // Initialize services even if the app isn't mounted, because they're used by index management extensions. - setHttpClient(http); - initUiMetric(usageCollection); - initNotification(toasts, fatalErrors); - - management.sections.getSection('elasticsearch')!.registerApp({ - id: MANAGEMENT_ID, - title: PLUGIN.TITLE, - order: 4, - mount: async ({ element, setBreadcrumbs }) => { - const { mountApp } = await import('./app'); - - const [coreStart] = await getStartServices(); - const { - i18n: { Context: I18nContext }, - docLinks: { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION }, - } = coreStart; - - return mountApp({ - element, - setBreadcrumbs, - I18nContext, - ELASTIC_WEBSITE_URL, - DOC_LINK_VERSION, - }); - }, - }); + ccrApp.enable(); if (indexManagement) { const propertyPath = 'isFollowerIndex'; diff --git a/x-pack/plugins/cross_cluster_replication/server/plugin.ts b/x-pack/plugins/cross_cluster_replication/server/plugin.ts index 39b71eac54781..02d4ff2684593 100644 --- a/x-pack/plugins/cross_cluster_replication/server/plugin.ts +++ b/x-pack/plugins/cross_cluster_replication/server/plugin.ts @@ -76,12 +76,27 @@ export class CrossClusterReplicationServerPlugin implements Plugin { - const router = http.createRouter(); - const config = await this.config$.pipe(first()).toPromise(); + ) { + this.config$ + .pipe(first()) + .toPromise() + .then(config => { + // remoteClusters.isUiEnabled is driven by the xpack.remote_clusters.ui.enabled setting. + // The CCR UI depends upon the Remote Clusters UI (e.g. by cross-linking to it), so if + // the Remote Clusters UI is disabled we can't show the CCR UI. + const isCcrUiEnabled = config.ui.enabled && remoteClusters.isUiEnabled; + + // If the UI isn't enabled, then we don't want to expose any CCR concepts in the UI, including + // "follower" badges for follower indices. + if (isCcrUiEnabled) { + if (indexManagement.indexDataEnricher) { + indexManagement.indexDataEnricher.add(ccrDataEnricher); + } + } + }); this.license.setup( { @@ -110,24 +125,13 @@ export class CrossClusterReplicationServerPlugin implements Plugin Date: Tue, 21 Apr 2020 11:59:50 -0700 Subject: [PATCH 17/20] Remove use of 'as' in route handler definitions. --- .../routes/api/auto_follow_pattern/register_create_route.ts | 2 +- .../routes/api/auto_follow_pattern/register_delete_route.ts | 2 +- .../routes/api/auto_follow_pattern/register_get_route.ts | 2 +- .../routes/api/auto_follow_pattern/register_pause_route.ts | 2 +- .../routes/api/auto_follow_pattern/register_resume_route.ts | 2 +- .../routes/api/auto_follow_pattern/register_update_route.ts | 2 +- .../server/routes/api/follower_index/register_create_route.ts | 2 +- .../server/routes/api/follower_index/register_get_route.ts | 2 +- .../server/routes/api/follower_index/register_pause_route.ts | 2 +- .../server/routes/api/follower_index/register_resume_route.ts | 2 +- .../routes/api/follower_index/register_unfollow_route.ts | 2 +- .../server/routes/api/follower_index/register_update_route.ts | 2 +- .../cross_cluster_replication/server/services/license.ts | 4 ++-- 13 files changed, 14 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts index bf8294496f05b..12503e3532a47 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.ts @@ -33,7 +33,7 @@ export const registerCreateRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { id, ...rest } = request.body as typeof bodySchema.type; + const { id, ...rest } = request.body; const body = serializeAutoFollowPattern(rest as AutoFollowPattern); /** diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts index 5f7f476660eaa..ed2633a4a469e 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.ts @@ -29,7 +29,7 @@ export const registerDeleteRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { id } = request.params as typeof paramsSchema.type; + const { id } = request.params; const ids = id.split(','); const itemsDeleted: string[] = []; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts index 3321ee8c9e6f8..1edbf7e8806c7 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.ts @@ -30,7 +30,7 @@ export const registerGetRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { id } = request.params as typeof paramsSchema.type; + const { id } = request.params; try { const result = await context.crossClusterReplication!.client.callAsCurrentUser( diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts index 6c3333b1b7b2e..325939709e751 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.ts @@ -28,7 +28,7 @@ export const registerPauseRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { id } = request.params as typeof paramsSchema.type; + const { id } = request.params; const ids = id.split(','); const itemsPaused: string[] = []; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts index 9c966d4bf86ee..f5e917773704c 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.ts @@ -28,7 +28,7 @@ export const registerResumeRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { id } = request.params as typeof paramsSchema.type; + const { id } = request.params; const ids = id.split(','); const itemsResumed: string[] = []; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts index cefc67e6af14b..836e5f55c5a48 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.ts @@ -38,7 +38,7 @@ export const registerUpdateRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { id } = request.params as typeof paramsSchema.type; + const { id } = request.params; const body = serializeAutoFollowPattern(request.body as AutoFollowPattern); try { diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts index 1633fb0745549..acaeedacfdb2a 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.ts @@ -43,7 +43,7 @@ export const registerCreateRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { name, ...rest } = request.body as typeof bodySchema.type; + const { name, ...rest } = request.body; const body = removeEmptyFields(serializeFollowerIndex(rest as FollowerIndex)); try { diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts index 77394fb705c9a..98a182fc15681 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.ts @@ -29,7 +29,7 @@ export const registerGetRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { id } = request.params as typeof paramsSchema.type; + const { id } = request.params; try { const { diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts index 8beffebed6c21..7432ea7ca5c82 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.ts @@ -26,7 +26,7 @@ export const registerPauseRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { id } = request.params as typeof paramsSchema.type; + const { id } = request.params; const ids = id.split(','); const itemsPaused: string[] = []; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts index 2624a68001baf..ca8f3a9f5fe9d 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.ts @@ -26,7 +26,7 @@ export const registerResumeRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { id } = request.params as typeof paramsSchema.type; + const { id } = request.params; const ids = id.split(','); const itemsResumed: string[] = []; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts index cde7697d7274d..282fead02bbe0 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.ts @@ -26,7 +26,7 @@ export const registerUnfollowRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { id } = request.params as typeof paramsSchema.type; + const { id } = request.params; const ids = id.split(','); const itemsUnfollowed: string[] = []; diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts index c27d150e7dcdb..521de77180974 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_update_route.ts @@ -43,7 +43,7 @@ export const registerUpdateRoute = ({ }, }, license.guardApiRoute(async (context, request, response) => { - const { id } = request.params as typeof paramsSchema.type; + const { id } = request.params; // We need to first pause the follower and then resume it by passing the advanced settings try { diff --git a/x-pack/plugins/cross_cluster_replication/server/services/license.ts b/x-pack/plugins/cross_cluster_replication/server/services/license.ts index c45fc87948613..e41da3faf8069 100644 --- a/x-pack/plugins/cross_cluster_replication/server/services/license.ts +++ b/x-pack/plugins/cross_cluster_replication/server/services/license.ts @@ -59,12 +59,12 @@ export class License { }); } - guardApiRoute(handler: RequestHandler) { + guardApiRoute(handler: RequestHandler) { const license = this; return function licenseCheck( ctx: RequestHandlerContext, - request: KibanaRequest, + request: KibanaRequest, response: KibanaResponseFactory ) { const licenseStatus = license.getStatus(); From 11e117bccd8d969765742eb7281404700f8bfe19 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Tue, 21 Apr 2020 13:36:35 -0700 Subject: [PATCH 18/20] Extract mockRouteContext into a helper. --- .../register_create_route.test.ts | 42 +++---- .../register_delete_route.test.ts | 58 ++++------ .../register_fetch_route.test.ts | 20 +--- .../register_get_route.test.ts | 20 +--- .../register_pause_route.test.ts | 58 ++++------ .../register_resume_route.test.ts | 58 ++++------ .../register_update_route.test.ts | 22 ++-- .../register_create_route.test.ts | 20 +--- .../register_fetch_route.test.ts | 26 ++--- .../follower_index/register_get_route.test.ts | 26 ++--- .../register_pause_route.test.ts | 58 ++++------ .../register_resume_route.test.ts | 58 ++++------ .../register_unfollow_route.test.ts | 104 ++++++++---------- .../server/routes/api/test_lib.ts | 23 ++++ 14 files changed, 230 insertions(+), 363 deletions(-) create mode 100644 x-pack/plugins/cross_cluster_replication/server/routes/api/test_lib.ts diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.test.ts index e6712f9e3c23b..b41b52e1764c8 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_create_route.test.ts @@ -5,16 +5,12 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { - IRouter, - kibanaResponseFactory, - RequestHandler, - RequestHandlerContext, -} from 'src/core/server'; +import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; +import { mockRouteContext } from '../test_lib'; import { registerCreateRoute } from './register_create_route'; const httpService = httpServiceMock.createSetupContract(); @@ -40,14 +36,10 @@ describe('[CCR API] Create auto-follow pattern', () => { }); it('should throw a 409 conflict error if id already exists', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - // Fail the uniqueness check. - callAsCurrentUser: jest.fn().mockResolvedValueOnce(true), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + // Fail the uniqueness check. + callAsCurrentUser: jest.fn().mockResolvedValueOnce(true), + }); const request = httpServerMock.createKibanaRequest({ body: { @@ -56,22 +48,18 @@ describe('[CCR API] Create auto-follow pattern', () => { }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.status).toEqual(409); }); it('should return 200 status when the id does not exist', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest - .fn() - // Pass the uniqueness check. - .mockRejectedValueOnce({ statusCode: 404 }) - .mockResolvedValueOnce(true), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest + .fn() + // Pass the uniqueness check. + .mockRejectedValueOnce({ statusCode: 404 }) + .mockResolvedValueOnce(true), + }); const request = httpServerMock.createKibanaRequest({ body: { @@ -80,7 +68,7 @@ describe('[CCR API] Create auto-follow pattern', () => { }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.status).toEqual(200); }); }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.test.ts index 9bd8a247563af..e610d09b44275 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_delete_route.test.ts @@ -5,16 +5,12 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { - IRouter, - kibanaResponseFactory, - RequestHandler, - RequestHandlerContext, -} from 'src/core/server'; +import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; +import { mockRouteContext } from '../test_lib'; import { registerDeleteRoute } from './register_delete_route'; const httpService = httpServiceMock.createSetupContract(); @@ -40,62 +36,50 @@ describe('[CCR API] Delete auto-follow pattern(s)', () => { }); it('deletes a single item', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest.fn().mockResolvedValueOnce({ acknowledge: true }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest.fn().mockResolvedValueOnce({ acknowledge: true }), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'a' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.itemsDeleted).toEqual(['a']); expect(response.payload.errors).toEqual([]); }); it('deletes multiple items', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest - .fn() - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'a,b,c' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.itemsDeleted).toEqual(['a', 'b', 'c']); expect(response.payload.errors).toEqual([]); }); it('returns partial errors', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest - .fn() - .mockResolvedValueOnce({ acknowledge: true }) - .mockRejectedValueOnce({ response: { error: {} } }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockRejectedValueOnce({ response: { error: {} } }), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'a,b' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.itemsDeleted).toEqual(['a']); expect(response.payload.errors[0].id).toEqual('b'); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts index a7632a5d66317..dd102c45665cb 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_fetch_route.test.ts @@ -5,16 +5,12 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { - IRouter, - kibanaResponseFactory, - RequestHandler, - RequestHandlerContext, -} from 'src/core/server'; +import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; +import { mockRouteContext } from '../test_lib'; import { registerFetchRoute } from './register_fetch_route'; const httpService = httpServiceMock.createSetupContract(); @@ -54,16 +50,12 @@ describe('[CCR API] Fetch all auto-follow patterns', () => { ], }; - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest.fn().mockResolvedValueOnce(ccrAutoFollowPatternResponseMock), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest.fn().mockResolvedValueOnce(ccrAutoFollowPatternResponseMock), + }); const request = httpServerMock.createKibanaRequest(); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.patterns).toEqual([ { active: true, diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts index 4510478cea6db..d5889074651f5 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_get_route.test.ts @@ -5,16 +5,12 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { - IRouter, - kibanaResponseFactory, - RequestHandler, - RequestHandlerContext, -} from 'src/core/server'; +import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; +import { mockRouteContext } from '../test_lib'; import { registerGetRoute } from './register_get_route'; const httpService = httpServiceMock.createSetupContract(); @@ -54,16 +50,12 @@ describe('[CCR API] Get one auto-follow pattern', () => { ], }; - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest.fn().mockResolvedValueOnce(ccrAutoFollowPatternResponseMock), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest.fn().mockResolvedValueOnce(ccrAutoFollowPatternResponseMock), + }); const request = httpServerMock.createKibanaRequest(); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload).toEqual({ active: true, followIndexPattern: 'follow', diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.test.ts index 3bb0fe32220ba..1eaac02918b88 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_pause_route.test.ts @@ -5,16 +5,12 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { - IRouter, - kibanaResponseFactory, - RequestHandler, - RequestHandlerContext, -} from 'src/core/server'; +import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; +import { mockRouteContext } from '../test_lib'; import { registerPauseRoute } from './register_pause_route'; const httpService = httpServiceMock.createSetupContract(); @@ -40,62 +36,50 @@ describe('[CCR API] Pause auto-follow pattern(s)', () => { }); it('pauses a single item', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest.fn().mockResolvedValueOnce({ acknowledge: true }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest.fn().mockResolvedValueOnce({ acknowledge: true }), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'a' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.itemsPaused).toEqual(['a']); expect(response.payload.errors).toEqual([]); }); it('pauses multiple items', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest - .fn() - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'a,b,c' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.itemsPaused).toEqual(['a', 'b', 'c']); expect(response.payload.errors).toEqual([]); }); it('returns partial errors', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest - .fn() - .mockResolvedValueOnce({ acknowledge: true }) - .mockRejectedValueOnce({ response: { error: {} } }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockRejectedValueOnce({ response: { error: {} } }), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'a,b' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.itemsPaused).toEqual(['a']); expect(response.payload.errors[0].id).toEqual('b'); }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.test.ts index 00a244ac5ec9c..9839761e701fc 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_resume_route.test.ts @@ -5,16 +5,12 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { - IRouter, - kibanaResponseFactory, - RequestHandler, - RequestHandlerContext, -} from 'src/core/server'; +import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; +import { mockRouteContext } from '../test_lib'; import { registerResumeRoute } from './register_resume_route'; const httpService = httpServiceMock.createSetupContract(); @@ -40,62 +36,50 @@ describe('[CCR API] Resume auto-follow pattern(s)', () => { }); it('resumes a single item', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest.fn().mockResolvedValueOnce({ acknowledge: true }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest.fn().mockResolvedValueOnce({ acknowledge: true }), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'a' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.itemsResumed).toEqual(['a']); expect(response.payload.errors).toEqual([]); }); it('resumes multiple items', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest - .fn() - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'a,b,c' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.itemsResumed).toEqual(['a', 'b', 'c']); expect(response.payload.errors).toEqual([]); }); it('returns partial errors', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest - .fn() - .mockResolvedValueOnce({ acknowledge: true }) - .mockRejectedValueOnce({ response: { error: {} } }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockRejectedValueOnce({ response: { error: {} } }), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'a,b' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.itemsResumed).toEqual(['a']); expect(response.payload.errors[0].id).toEqual('b'); }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts index 09f27751f2b97..85f2270ec3aee 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/auto_follow_pattern/register_update_route.test.ts @@ -5,16 +5,12 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { - IRouter, - kibanaResponseFactory, - RequestHandler, - RequestHandlerContext, -} from 'src/core/server'; +import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; +import { mockRouteContext } from '../test_lib'; import { registerUpdateRoute } from './register_update_route'; const httpService = httpServiceMock.createSetupContract(); @@ -40,14 +36,10 @@ describe('[CCR API] Update auto-follow pattern', () => { }); it('should serialize the payload before sending it to Elasticsearch', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - // Just echo back what we send so we can inspect it. - callAsCurrentUser: jest.fn().mockImplementation((endpoint, payload) => payload), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + // Just echo back what we send so we can inspect it. + callAsCurrentUser: jest.fn().mockImplementation((endpoint, payload) => payload), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'foo' }, @@ -58,7 +50,7 @@ describe('[CCR API] Update auto-follow pattern', () => { }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload).toEqual({ id: 'foo', diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.test.ts index feb71a8e94f0f..bba82b04ce9a0 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_create_route.test.ts @@ -5,16 +5,12 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { - IRouter, - kibanaResponseFactory, - RequestHandler, - RequestHandlerContext, -} from 'src/core/server'; +import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; +import { mockRouteContext } from '../test_lib'; import { registerCreateRoute } from './register_create_route'; const httpService = httpServiceMock.createSetupContract(); @@ -40,13 +36,9 @@ describe('[CCR API] Create follower index', () => { }); it('should return 200 status when follower index is created', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest.fn().mockResolvedValueOnce({ acknowledge: true }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest.fn().mockResolvedValueOnce({ acknowledge: true }), + }); const request = httpServerMock.createKibanaRequest({ body: { @@ -56,7 +48,7 @@ describe('[CCR API] Create follower index', () => { }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.status).toEqual(200); }); }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts index d452db8c969d5..151ab84fabf4c 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_fetch_route.test.ts @@ -5,16 +5,12 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { - IRouter, - kibanaResponseFactory, - RequestHandler, - RequestHandlerContext, -} from 'src/core/server'; +import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; +import { mockRouteContext } from '../test_lib'; import { registerFetchRoute } from './register_fetch_route'; const httpService = httpServiceMock.createSetupContract(); @@ -103,19 +99,15 @@ describe('[CCR API] Fetch all follower indices', () => { }, }; - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest - .fn() - .mockResolvedValueOnce(ccrInfoMockResponse) - .mockResolvedValueOnce(ccrStatsMockResponse), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce(ccrInfoMockResponse) + .mockResolvedValueOnce(ccrStatsMockResponse), + }); const request = httpServerMock.createKibanaRequest(); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.indices).toEqual([ { diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts index 9489011939bbf..42d04ca65b1cb 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_get_route.test.ts @@ -5,16 +5,12 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { - IRouter, - kibanaResponseFactory, - RequestHandler, - RequestHandlerContext, -} from 'src/core/server'; +import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; +import { mockRouteContext } from '../test_lib'; import { registerGetRoute } from './register_get_route'; const httpService = httpServiceMock.createSetupContract(); @@ -101,22 +97,18 @@ describe('[CCR API] Get one follower index', () => { ], }; - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest - .fn() - .mockResolvedValueOnce(ccrInfoMockResponse) - .mockResolvedValueOnce(ccrFollowerIndexStatsMockResponse), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce(ccrInfoMockResponse) + .mockResolvedValueOnce(ccrFollowerIndexStatsMockResponse), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'doesnt_matter' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload).toEqual({ name: 'followerIndexName', diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.test.ts index 3f1727a35e2b2..82cb88cbacea7 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_pause_route.test.ts @@ -5,16 +5,12 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { - IRouter, - kibanaResponseFactory, - RequestHandler, - RequestHandlerContext, -} from 'src/core/server'; +import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; +import { mockRouteContext } from '../test_lib'; import { registerPauseRoute } from './register_pause_route'; const httpService = httpServiceMock.createSetupContract(); @@ -40,62 +36,50 @@ describe('[CCR API] Pause follower index/indices', () => { }); it('pauses a single item', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest.fn().mockResolvedValueOnce({ acknowledge: true }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest.fn().mockResolvedValueOnce({ acknowledge: true }), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'a' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.itemsPaused).toEqual(['a']); expect(response.payload.errors).toEqual([]); }); it('pauses multiple items', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest - .fn() - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'a,b,c' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.itemsPaused).toEqual(['a', 'b', 'c']); expect(response.payload.errors).toEqual([]); }); it('returns partial errors', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest - .fn() - .mockResolvedValueOnce({ acknowledge: true }) - .mockRejectedValueOnce({ response: { error: {} } }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockRejectedValueOnce({ response: { error: {} } }), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'a,b' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.itemsPaused).toEqual(['a']); expect(response.payload.errors[0].id).toEqual('b'); }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.test.ts index e21a105cbeb74..04167c5db3162 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_resume_route.test.ts @@ -5,16 +5,12 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { - IRouter, - kibanaResponseFactory, - RequestHandler, - RequestHandlerContext, -} from 'src/core/server'; +import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; +import { mockRouteContext } from '../test_lib'; import { registerResumeRoute } from './register_resume_route'; const httpService = httpServiceMock.createSetupContract(); @@ -40,62 +36,50 @@ describe('[CCR API] Resume follower index/indices', () => { }); it('resumes a single item', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest.fn().mockResolvedValueOnce({ acknowledge: true }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest.fn().mockResolvedValueOnce({ acknowledge: true }), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'a' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.itemsResumed).toEqual(['a']); expect(response.payload.errors).toEqual([]); }); it('resumes multiple items', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest - .fn() - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'a,b,c' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.itemsResumed).toEqual(['a', 'b', 'c']); expect(response.payload.errors).toEqual([]); }); it('returns partial errors', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest - .fn() - .mockResolvedValueOnce({ acknowledge: true }) - .mockRejectedValueOnce({ response: { error: {} } }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockRejectedValueOnce({ response: { error: {} } }), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'a,b' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.itemsResumed).toEqual(['a']); expect(response.payload.errors[0].id).toEqual('b'); }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.test.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.test.ts index 3d2377f881252..6302d5868b0db 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.test.ts +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/follower_index/register_unfollow_route.test.ts @@ -5,16 +5,12 @@ */ import { httpServiceMock, httpServerMock } from 'src/core/server/mocks'; -import { - IRouter, - kibanaResponseFactory, - RequestHandler, - RequestHandlerContext, -} from 'src/core/server'; +import { IRouter, kibanaResponseFactory, RequestHandler } from 'src/core/server'; import { isEsError } from '../../../lib/is_es_error'; import { formatEsError } from '../../../lib/format_es_error'; import { License } from '../../../services'; +import { mockRouteContext } from '../test_lib'; import { registerUnfollowRoute } from './register_unfollow_route'; const httpService = httpServiceMock.createSetupContract(); @@ -40,85 +36,73 @@ describe('[CCR API] Unfollow follower index/indices', () => { }); it('unfollows a single item', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest - .fn() - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest + .fn() + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'a' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.itemsUnfollowed).toEqual(['a']); expect(response.payload.errors).toEqual([]); }); it('unfollows multiple items', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest - .fn() - // a - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }) - // b - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }) - // c - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest + .fn() + // a + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + // b + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + // c + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'a,b,c' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.itemsUnfollowed).toEqual(['a', 'b', 'c']); expect(response.payload.errors).toEqual([]); }); it('returns partial errors', async () => { - const mockRouteContext = ({ - crossClusterReplication: { - client: { - callAsCurrentUser: jest - .fn() - // a - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }) - .mockResolvedValueOnce({ acknowledge: true }) - // b - .mockResolvedValueOnce({ acknowledge: true }) - .mockRejectedValueOnce({ response: { error: {} } }), - }, - }, - } as unknown) as RequestHandlerContext; + const routeContextMock = mockRouteContext({ + callAsCurrentUser: jest + .fn() + // a + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + .mockResolvedValueOnce({ acknowledge: true }) + // b + .mockResolvedValueOnce({ acknowledge: true }) + .mockRejectedValueOnce({ response: { error: {} } }), + }); const request = httpServerMock.createKibanaRequest({ params: { id: 'a,b' }, }); - const response = await routeHandler(mockRouteContext, request, kibanaResponseFactory); + const response = await routeHandler(routeContextMock, request, kibanaResponseFactory); expect(response.payload.itemsUnfollowed).toEqual(['a']); expect(response.payload.errors[0].id).toEqual('b'); }); diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/test_lib.ts b/x-pack/plugins/cross_cluster_replication/server/routes/api/test_lib.ts new file mode 100644 index 0000000000000..9b4fb134ed230 --- /dev/null +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/test_lib.ts @@ -0,0 +1,23 @@ +/* + * 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 { RequestHandlerContext } from 'src/core/server'; + +export function mockRouteContext({ + callAsCurrentUser, +}: { + callAsCurrentUser: any; +}): RequestHandlerContext { + const routeContextMock = ({ + crossClusterReplication: { + client: { + callAsCurrentUser, + }, + }, + } as unknown) as RequestHandlerContext; + + return routeContextMock; +} From 4baad1613a3c492b357e0996b8a5b73d648f31fa Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Tue, 21 Apr 2020 13:43:36 -0700 Subject: [PATCH 19/20] Remove unnecessary styles. --- .../cross_cluster_replication/public/app/_app.scss | 14 -------------- .../app/components/auto_follow_pattern_form.js | 6 +----- .../components/detail_panel/detail_panel.js | 1 - .../cross_cluster_replication/public/index.scss | 10 ---------- 4 files changed, 1 insertion(+), 30 deletions(-) delete mode 100644 x-pack/plugins/cross_cluster_replication/public/app/_app.scss delete mode 100644 x-pack/plugins/cross_cluster_replication/public/index.scss diff --git a/x-pack/plugins/cross_cluster_replication/public/app/_app.scss b/x-pack/plugins/cross_cluster_replication/public/app/_app.scss deleted file mode 100644 index 5ee862b1d9e44..0000000000000 --- a/x-pack/plugins/cross_cluster_replication/public/app/_app.scss +++ /dev/null @@ -1,14 +0,0 @@ -.ccrFollowerIndicesFormRow { - padding-bottom: 0; -} - -.ccrFollowerIndicesHelpText { - transform: translateY(-3px); -} - -/** - * 1. Prevent context menu popover appearing above confirmation modal - */ -.ccrFollowerIndicesDetailPanel { - z-index: $euiZMask - 1; /* 1 */ -} diff --git a/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_form.js b/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_form.js index b41511445da42..c817637ae1854 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_form.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/components/auto_follow_pattern_form.js @@ -512,7 +512,6 @@ export class AutoFollowPatternForm extends PureComponent { - + Date: Tue, 21 Apr 2020 17:03:17 -0700 Subject: [PATCH 20/20] Migrate kibana/server dependencies to src/core/server. --- x-pack/plugins/cross_cluster_replication/server/index.ts | 6 +++--- x-pack/plugins/cross_cluster_replication/server/plugin.ts | 2 +- .../cross_cluster_replication/server/services/license.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/cross_cluster_replication/server/index.ts b/x-pack/plugins/cross_cluster_replication/server/index.ts index 483dccfbd506a..597c039ad202e 100644 --- a/x-pack/plugins/cross_cluster_replication/server/index.ts +++ b/x-pack/plugins/cross_cluster_replication/server/index.ts @@ -4,12 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { PluginInitializerContext, PluginConfigDescriptor } from 'kibana/server'; +import { PluginInitializerContext, PluginConfigDescriptor } from 'src/core/server'; import { CrossClusterReplicationServerPlugin } from './plugin'; import { configSchema, CrossClusterReplicationConfig } from './config'; -export const plugin = (ctx: PluginInitializerContext) => - new CrossClusterReplicationServerPlugin(ctx); +export const plugin = (pluginInitializerContext: PluginInitializerContext) => + new CrossClusterReplicationServerPlugin(pluginInitializerContext); export const config: PluginConfigDescriptor = { schema: configSchema, diff --git a/x-pack/plugins/cross_cluster_replication/server/plugin.ts b/x-pack/plugins/cross_cluster_replication/server/plugin.ts index 02d4ff2684593..25c99803480f3 100644 --- a/x-pack/plugins/cross_cluster_replication/server/plugin.ts +++ b/x-pack/plugins/cross_cluster_replication/server/plugin.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -declare module 'kibana/server' { +declare module 'src/core/server' { interface RequestHandlerContext { crossClusterReplication?: CrossClusterReplicationContext; } diff --git a/x-pack/plugins/cross_cluster_replication/server/services/license.ts b/x-pack/plugins/cross_cluster_replication/server/services/license.ts index e41da3faf8069..bfd357867c3e2 100644 --- a/x-pack/plugins/cross_cluster_replication/server/services/license.ts +++ b/x-pack/plugins/cross_cluster_replication/server/services/license.ts @@ -9,7 +9,7 @@ import { KibanaResponseFactory, RequestHandler, RequestHandlerContext, -} from 'kibana/server'; +} from 'src/core/server'; import { LicensingPluginSetup } from '../../../licensing/server'; import { LicenseType } from '../../../licensing/common/types';