From 91ce7999de72f9efc617b06ba0ecb1d7a77d4c9a Mon Sep 17 00:00:00 2001 From: Joe Portner <5295965+jportner@users.noreply.github.com> Date: Wed, 10 Feb 2021 16:58:09 -0500 Subject: [PATCH 01/12] Fix calls to `/api/saved_objects_tagging/tags` Seen on all pages. --- .../saved_objects_tagging_oss/common/index.ts | 2 +- .../saved_objects_tagging_oss/common/types.ts | 6 +++++- .../saved_objects_tagging/common/types.ts | 1 + .../saved_objects_tagging/public/plugin.ts | 2 +- .../public/services/tags/tags_client.test.ts | 12 +++++++++++- .../public/services/tags/tags_client.ts | 16 +++++++++++++--- 6 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/plugins/saved_objects_tagging_oss/common/index.ts b/src/plugins/saved_objects_tagging_oss/common/index.ts index 231bec46f57ab..a892f41c69314 100644 --- a/src/plugins/saved_objects_tagging_oss/common/index.ts +++ b/src/plugins/saved_objects_tagging_oss/common/index.ts @@ -6,4 +6,4 @@ * Side Public License, v 1. */ -export { Tag, TagAttributes, ITagsClient } from './types'; +export { Tag, TagAttributes, GetAllTagsOptions, ITagsClient } from './types'; diff --git a/src/plugins/saved_objects_tagging_oss/common/types.ts b/src/plugins/saved_objects_tagging_oss/common/types.ts index 344e18a5fd76d..205f6984ed618 100644 --- a/src/plugins/saved_objects_tagging_oss/common/types.ts +++ b/src/plugins/saved_objects_tagging_oss/common/types.ts @@ -19,10 +19,14 @@ export interface TagAttributes { color: string; } +export interface GetAllTagsOptions { + asSystemRequest?: boolean; +} + export interface ITagsClient { create(attributes: TagAttributes): Promise; get(id: string): Promise; - getAll(): Promise; + getAll(options?: GetAllTagsOptions): Promise; delete(id: string): Promise; update(id: string, attributes: TagAttributes): Promise; } diff --git a/x-pack/plugins/saved_objects_tagging/common/types.ts b/x-pack/plugins/saved_objects_tagging/common/types.ts index bd65f74044bc1..c0b92a71a3d1b 100644 --- a/x-pack/plugins/saved_objects_tagging/common/types.ts +++ b/x-pack/plugins/saved_objects_tagging/common/types.ts @@ -21,5 +21,6 @@ export type TagWithRelations = Tag & { export type { Tag, TagAttributes, + GetAllTagsOptions, ITagsClient, } from '../../../../src/plugins/saved_objects_tagging_oss/common'; diff --git a/x-pack/plugins/saved_objects_tagging/public/plugin.ts b/x-pack/plugins/saved_objects_tagging/public/plugin.ts index 9821bfb397802..d4e3f8678fe1f 100644 --- a/x-pack/plugins/saved_objects_tagging/public/plugin.ts +++ b/x-pack/plugins/saved_objects_tagging/public/plugin.ts @@ -66,7 +66,7 @@ export class SavedObjectTaggingPlugin public start({ http, application, overlays }: CoreStart) { this.tagCache = new TagsCache({ - refreshHandler: () => this.tagClient!.getAll(), + refreshHandler: () => this.tagClient!.getAll({ asSystemRequest: true }), refreshInterval: this.config.cacheRefreshInterval, }); this.tagClient = new TagsClient({ http, changeListener: this.tagCache }); diff --git a/x-pack/plugins/saved_objects_tagging/public/services/tags/tags_client.test.ts b/x-pack/plugins/saved_objects_tagging/public/services/tags/tags_client.test.ts index 39e2df073591e..24409e8596265 100644 --- a/x-pack/plugins/saved_objects_tagging/public/services/tags/tags_client.test.ts +++ b/x-pack/plugins/saved_objects_tagging/public/services/tags/tags_client.test.ts @@ -156,7 +156,17 @@ describe('TagsClient', () => { await tagsClient.getAll(); expect(http.get).toHaveBeenCalledTimes(1); - expect(http.get).toHaveBeenCalledWith(`/api/saved_objects_tagging/tags`); + expect(http.get).toHaveBeenCalledWith(`/api/saved_objects_tagging/tags`, { + asSystemRequest: undefined, + }); + }); + it('allows `asSystemRequest` option to be set', async () => { + await tagsClient.getAll({ asSystemRequest: true }); + + expect(http.get).toHaveBeenCalledTimes(1); + expect(http.get).toHaveBeenCalledWith(`/api/saved_objects_tagging/tags`, { + asSystemRequest: true, + }); }); it('returns the tag objects from the response', async () => { const tags = await tagsClient.getAll(); diff --git a/x-pack/plugins/saved_objects_tagging/public/services/tags/tags_client.ts b/x-pack/plugins/saved_objects_tagging/public/services/tags/tags_client.ts index 8a99af7af6d02..ef484f0a550b1 100644 --- a/x-pack/plugins/saved_objects_tagging/public/services/tags/tags_client.ts +++ b/x-pack/plugins/saved_objects_tagging/public/services/tags/tags_client.ts @@ -6,7 +6,13 @@ */ import { HttpSetup } from 'src/core/public'; -import { Tag, TagAttributes, ITagsClient, TagWithRelations } from '../../../common/types'; +import { + Tag, + TagAttributes, + GetAllTagsOptions, + ITagsClient, + TagWithRelations, +} from '../../../common/types'; import { ITagsChangeListener } from './tags_cache'; export interface TagsClientOptions { @@ -83,8 +89,12 @@ export class TagsClient implements ITagInternalClient { return tag; } - public async getAll() { - const { tags } = await this.http.get<{ tags: Tag[] }>('/api/saved_objects_tagging/tags'); + public async getAll({ asSystemRequest }: GetAllTagsOptions = {}) { + const fetchOptions = { asSystemRequest }; + const { tags } = await this.http.get<{ tags: Tag[] }>( + '/api/saved_objects_tagging/tags', + fetchOptions + ); trapErrors(() => { if (this.changeListener) { From f9d1fc06436f424ca431816c2e50782387f0903a Mon Sep 17 00:00:00 2001 From: Joe Portner <5295965+jportner@users.noreply.github.com> Date: Wed, 10 Feb 2021 17:00:52 -0500 Subject: [PATCH 02/12] Fix calls to `/api/ui_counters/_report` Seen on all pages. --- src/plugins/usage_collection/public/services/create_reporter.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/usage_collection/public/services/create_reporter.ts b/src/plugins/usage_collection/public/services/create_reporter.ts index ef4c007735ff4..e5006646fe368 100644 --- a/src/plugins/usage_collection/public/services/create_reporter.ts +++ b/src/plugins/usage_collection/public/services/create_reporter.ts @@ -24,6 +24,7 @@ export function createReporter(config: AnalyicsReporterConfig): Reporter { async http(report) { const response = await fetch.post('/api/ui_counters/_report', { body: JSON.stringify({ report }), + asSystemRequest: true, }); if (response.status !== 'ok') { From 4028d8d34252d277d30c256a3a0f5c40620c7bc4 Mon Sep 17 00:00:00 2001 From: Joe Portner <5295965+jportner@users.noreply.github.com> Date: Wed, 10 Feb 2021 18:19:13 -0500 Subject: [PATCH 03/12] Fix calls to `/api/index_management/indices/reload` Seen on page: /app/management/data/index_management --- .../index_table/index_table.container.js | 4 ++-- .../home/index_list/index_table/index_table.js | 6 +++++- .../public/application/services/api.ts | 14 ++++++++++++-- .../application/store/actions/reload_indices.js | 4 ++-- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.container.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.container.js index a435d9be54864..93ad0e0dc3be5 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.container.js +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.container.js @@ -76,8 +76,8 @@ const mapDispatchToProps = (dispatch) => { loadIndices: () => { dispatch(loadIndices()); }, - reloadIndices: (indexNames) => { - dispatch(reloadIndices(indexNames)); + reloadIndices: (indexNames, options) => { + dispatch(reloadIndices(indexNames, options)); }, }; }; diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js index d966c39b76c17..f488290692e7e 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js @@ -103,7 +103,11 @@ export class IndexTable extends Component { componentDidMount() { this.props.loadIndices(); this.interval = setInterval( - () => this.props.reloadIndices(this.props.indices.map((i) => i.name)), + () => + this.props.reloadIndices( + this.props.indices.map((i) => i.name), + { asSystemRequest: true } + ), REFRESH_RATE_INDEX_LIST ); const { location, filterChanged } = this.props; diff --git a/x-pack/plugins/index_management/public/application/services/api.ts b/x-pack/plugins/index_management/public/application/services/api.ts index ad080b0723b1c..a7109854d676f 100644 --- a/x-pack/plugins/index_management/public/application/services/api.ts +++ b/x-pack/plugins/index_management/public/application/services/api.ts @@ -40,6 +40,10 @@ import { useRequest, sendRequest } from './use_request'; import { httpService } from './http'; import { UiMetricService } from './ui_metric'; +interface ReloadIndicesOptions { + asSystemRequest?: boolean; +} + // Temporary hack to provide the uiMetricService instance to this file. // TODO: Refactor and export an ApiService instance through the app dependencies context let uiMetricService: UiMetricService; @@ -78,11 +82,17 @@ export async function loadIndices() { return response.data ? response.data : response; } -export async function reloadIndices(indexNames: string[]) { +export async function reloadIndices( + indexNames: string[], + { asSystemRequest }: ReloadIndicesOptions = {} +) { const body = JSON.stringify({ indexNames, }); - const response = await httpService.httpClient.post(`${API_BASE_PATH}/indices/reload`, { body }); + const response = await httpService.httpClient.post(`${API_BASE_PATH}/indices/reload`, { + body, + asSystemRequest, + }); return response.data ? response.data : response; } diff --git a/x-pack/plugins/index_management/public/application/store/actions/reload_indices.js b/x-pack/plugins/index_management/public/application/store/actions/reload_indices.js index 71838d61c20f8..9498e55154839 100644 --- a/x-pack/plugins/index_management/public/application/store/actions/reload_indices.js +++ b/x-pack/plugins/index_management/public/application/store/actions/reload_indices.js @@ -12,10 +12,10 @@ import { loadIndices } from './load_indices'; import { notificationService } from '../../services/notification'; export const reloadIndicesSuccess = createAction('INDEX_MANAGEMENT_RELOAD_INDICES_SUCCESS'); -export const reloadIndices = (indexNames) => async (dispatch) => { +export const reloadIndices = (indexNames, options) => async (dispatch) => { let indices; try { - indices = await request(indexNames); + indices = await request(indexNames, options); } catch (error) { // an index has been deleted // or the user does not have privileges for one of the indices on the current page, From 8006eb7b289dd0789430982dd5ce095f1d942abd Mon Sep 17 00:00:00 2001 From: Joe Portner <5295965+jportner@users.noreply.github.com> Date: Wed, 10 Feb 2021 18:52:22 -0500 Subject: [PATCH 04/12] Fix calls to `/api/watcher/watches` Seen on page: /app/management/insightsAndAlerting/watcher/watches --- .../request/send_request.test.helpers.ts | 22 ++++-- .../public/request/send_request.ts | 9 ++- .../request/use_request.test.helpers.tsx | 33 +++++--- .../public/request/use_request.ts | 76 ++++++++++--------- .../public/application/services/api.js | 4 +- .../public/application/services/http.ts | 13 +++- .../store/actions/refresh_clusters.js | 2 +- 7 files changed, 95 insertions(+), 64 deletions(-) diff --git a/src/plugins/es_ui_shared/public/request/send_request.test.helpers.ts b/src/plugins/es_ui_shared/public/request/send_request.test.helpers.ts index 5244a6c1e8bf1..3ef33b651f4d2 100644 --- a/src/plugins/es_ui_shared/public/request/send_request.test.helpers.ts +++ b/src/plugins/es_ui_shared/public/request/send_request.test.helpers.ts @@ -41,20 +41,26 @@ export const createSendRequestHelpers = (): SendRequestHelpers => { // Set up successful request helpers. sendRequestSpy - .withArgs(successRequest.path, { - body: JSON.stringify(successRequest.body), - query: undefined, - }) + .withArgs( + successRequest.path, + sinon.match({ + body: JSON.stringify(successRequest.body), + query: undefined, + }) + ) .resolves(successResponse); const sendSuccessRequest = () => sendRequest({ ...successRequest }); const getSuccessResponse = () => ({ data: successResponse.data, error: null }); // Set up failed request helpers. sendRequestSpy - .withArgs(errorRequest.path, { - body: JSON.stringify(errorRequest.body), - query: undefined, - }) + .withArgs( + errorRequest.path, + sinon.match({ + body: JSON.stringify(errorRequest.body), + query: undefined, + }) + ) .rejects(errorResponse); const sendErrorRequest = () => sendRequest({ ...errorRequest }); const getErrorResponse = () => ({ diff --git a/src/plugins/es_ui_shared/public/request/send_request.ts b/src/plugins/es_ui_shared/public/request/send_request.ts index 32703f21a4668..889ec59d91a4b 100644 --- a/src/plugins/es_ui_shared/public/request/send_request.ts +++ b/src/plugins/es_ui_shared/public/request/send_request.ts @@ -13,6 +13,7 @@ export interface SendRequestConfig { method: 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head'; query?: HttpFetchQuery; body?: any; + asSystemRequest?: boolean; } export interface SendRequestResponse { @@ -22,11 +23,15 @@ export interface SendRequestResponse { export const sendRequest = async ( httpClient: HttpSetup, - { path, method, body, query }: SendRequestConfig + { path, method, body, query, asSystemRequest }: SendRequestConfig ): Promise> => { try { const stringifiedBody = typeof body === 'string' ? body : JSON.stringify(body); - const response = await httpClient[method](path, { body: stringifiedBody, query }); + const response = await httpClient[method](path, { + body: stringifiedBody, + query, + asSystemRequest, + }); return { data: response.data ? response.data : response, diff --git a/src/plugins/es_ui_shared/public/request/use_request.test.helpers.tsx b/src/plugins/es_ui_shared/public/request/use_request.test.helpers.tsx index 9f41d13112bc8..82d3764dbf72a 100644 --- a/src/plugins/es_ui_shared/public/request/use_request.test.helpers.tsx +++ b/src/plugins/es_ui_shared/public/request/use_request.test.helpers.tsx @@ -123,10 +123,13 @@ export const createUseRequestHelpers = (): UseRequestHelpers => { // Set up successful request helpers. sendRequestSpy - .withArgs(successRequest.path, { - body: JSON.stringify(successRequest.body), - query: undefined, - }) + .withArgs( + successRequest.path, + sinon.match({ + body: JSON.stringify(successRequest.body), + query: undefined, + }) + ) .resolves(successResponse); const setupSuccessRequest = (overrides = {}, requestTimings?: number[]) => setupUseRequest({ ...successRequest, ...overrides }, requestTimings); @@ -134,10 +137,13 @@ export const createUseRequestHelpers = (): UseRequestHelpers => { // Set up failed request helpers. sendRequestSpy - .withArgs(errorRequest.path, { - body: JSON.stringify(errorRequest.body), - query: undefined, - }) + .withArgs( + errorRequest.path, + sinon.match({ + body: JSON.stringify(errorRequest.body), + query: undefined, + }) + ) .rejects(errorResponse); const setupErrorRequest = (overrides = {}, requestTimings?: number[]) => setupUseRequest({ ...errorRequest, ...overrides }, requestTimings); @@ -152,10 +158,13 @@ export const createUseRequestHelpers = (): UseRequestHelpers => { // Set up failed request helpers with the alternative error shape. sendRequestSpy - .withArgs(errorWithBodyRequest.path, { - body: JSON.stringify(errorWithBodyRequest.body), - query: undefined, - }) + .withArgs( + errorWithBodyRequest.path, + sinon.match({ + body: JSON.stringify(errorWithBodyRequest.body), + query: undefined, + }) + ) .rejects(errorWithBodyResponse); const setupErrorWithBodyRequest = (overrides = {}) => setupUseRequest({ ...errorWithBodyRequest, ...overrides }); diff --git a/src/plugins/es_ui_shared/public/request/use_request.ts b/src/plugins/es_ui_shared/public/request/use_request.ts index 99eb38ff6023f..7d939141b7969 100644 --- a/src/plugins/es_ui_shared/public/request/use_request.ts +++ b/src/plugins/es_ui_shared/public/request/use_request.ts @@ -65,49 +65,53 @@ export const useRequest = ( /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [path, method, queryStringified, bodyStringified]); - const resendRequest = useCallback(async () => { - // If we're on an interval, this allows us to reset it if the user has manually requested the - // data, to avoid doubled-up requests. - clearPollInterval(); - - const requestId = ++requestCountRef.current; - - // We don't clear error or data, so it's up to the consumer to decide whether to display the - // "old" error/data or loading state when a new request is in-flight. - setIsLoading(true); - - const response = await sendRequest(httpClient, requestBody); - const { data: serializedResponseData, error: responseError } = response; - - const isOutdatedRequest = requestId !== requestCountRef.current; - const isUnmounted = isMounted.current === false; - - // Ignore outdated or irrelevant data. - if (isOutdatedRequest || isUnmounted) { - return; - } - - // Surface to consumers that at least one request has resolved. - isInitialRequestRef.current = false; + const resendRequest = useCallback( + async (asSystemRequest?: boolean) => { + // If we're on an interval, this allows us to reset it if the user has manually requested the + // data, to avoid doubled-up requests. + clearPollInterval(); - setError(responseError); - // If there's an error, keep the data from the last request in case it's still useful to the user. - if (!responseError) { - const responseData = deserializer - ? deserializer(serializedResponseData) - : serializedResponseData; - setData(responseData); - } - // Setting isLoading to false also acts as a signal for scheduling the next poll request. - setIsLoading(false); - }, [requestBody, httpClient, deserializer, clearPollInterval]); + const requestId = ++requestCountRef.current; + + // We don't clear error or data, so it's up to the consumer to decide whether to display the + // "old" error/data or loading state when a new request is in-flight. + setIsLoading(true); + + const requestPayload = { ...requestBody, asSystemRequest }; + const response = await sendRequest(httpClient, requestPayload); + const { data: serializedResponseData, error: responseError } = response; + + const isOutdatedRequest = requestId !== requestCountRef.current; + const isUnmounted = isMounted.current === false; + + // Ignore outdated or irrelevant data. + if (isOutdatedRequest || isUnmounted) { + return; + } + + // Surface to consumers that at least one request has resolved. + isInitialRequestRef.current = false; + + setError(responseError); + // If there's an error, keep the data from the last request in case it's still useful to the user. + if (!responseError) { + const responseData = deserializer + ? deserializer(serializedResponseData) + : serializedResponseData; + setData(responseData); + } + // Setting isLoading to false also acts as a signal for scheduling the next poll request. + setIsLoading(false); + }, + [requestBody, httpClient, deserializer, clearPollInterval] + ); const scheduleRequest = useCallback(() => { // If there's a scheduled poll request, this new one will supersede it. clearPollInterval(); if (pollIntervalMs) { - pollIntervalIdRef.current = setTimeout(resendRequest, pollIntervalMs); + pollIntervalIdRef.current = setTimeout(() => resendRequest(true), pollIntervalMs); } }, [pollIntervalMs, resendRequest, clearPollInterval]); diff --git a/x-pack/plugins/remote_clusters/public/application/services/api.js b/x-pack/plugins/remote_clusters/public/application/services/api.js index c0d21f577dae8..6dd04b7090283 100644 --- a/x-pack/plugins/remote_clusters/public/application/services/api.js +++ b/x-pack/plugins/remote_clusters/public/application/services/api.js @@ -9,8 +9,8 @@ import { UIM_CLUSTER_ADD, UIM_CLUSTER_UPDATE } from '../constants'; import { trackUserRequest } from './ui_metric'; import { sendGet, sendPost, sendPut, sendDelete } from './http'; -export async function loadClusters() { - return await sendGet(); +export async function loadClusters(options) { + return await sendGet(undefined, options); } export async function addCluster(cluster) { diff --git a/x-pack/plugins/remote_clusters/public/application/services/http.ts b/x-pack/plugins/remote_clusters/public/application/services/http.ts index 7f205023dfa8a..831e706b5fa08 100644 --- a/x-pack/plugins/remote_clusters/public/application/services/http.ts +++ b/x-pack/plugins/remote_clusters/public/application/services/http.ts @@ -10,11 +10,15 @@ import { API_BASE_PATH } from '../../../common/constants'; let _httpClient: HttpSetup; +interface SendGetOptions { + asSystemRequest?: boolean; +} + export function init(httpClient: HttpSetup): void { _httpClient = httpClient; } -export function getFullPath(path: string): string { +export function getFullPath(path?: string): string { if (path) { return `${API_BASE_PATH}/${path}`; } @@ -35,8 +39,11 @@ export function sendPost( }); } -export function sendGet(path: string): Promise { - return _httpClient.get(getFullPath(path)); +export function sendGet( + path?: string, + { asSystemRequest }: SendGetOptions = {} +): Promise { + return _httpClient.get(getFullPath(path), { asSystemRequest }); } export function sendPut( diff --git a/x-pack/plugins/remote_clusters/public/application/store/actions/refresh_clusters.js b/x-pack/plugins/remote_clusters/public/application/store/actions/refresh_clusters.js index 8a765e171a8af..3dae779f0dc78 100644 --- a/x-pack/plugins/remote_clusters/public/application/store/actions/refresh_clusters.js +++ b/x-pack/plugins/remote_clusters/public/application/store/actions/refresh_clusters.js @@ -14,7 +14,7 @@ import { REFRESH_CLUSTERS_SUCCESS } from '../action_types'; export const refreshClusters = () => async (dispatch) => { let clusters; try { - clusters = await sendLoadClustersRequest(); + clusters = await sendLoadClustersRequest({ asSystemRequest: true }); } catch (error) { return showApiWarning( error, From 4561057e0dcea9476976d19f2b3fab461e08e35a Mon Sep 17 00:00:00 2001 From: Joe Portner <5295965+jportner@users.noreply.github.com> Date: Wed, 10 Feb 2021 19:13:25 -0500 Subject: [PATCH 05/12] Fix calls to `/api/rollup/jobs` Seen on page: /app/management/data/rollup_jobs/job_list --- .../public/crud_app/sections/job_list/job_list.container.js | 4 ++-- .../rollup/public/crud_app/sections/job_list/job_list.js | 5 ++++- x-pack/plugins/rollup/public/crud_app/services/api.js | 5 +++-- .../rollup/public/crud_app/store/actions/refresh_jobs.js | 4 ++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/rollup/public/crud_app/sections/job_list/job_list.container.js b/x-pack/plugins/rollup/public/crud_app/sections/job_list/job_list.container.js index e71b3b6870267..ce7e29af8323d 100644 --- a/x-pack/plugins/rollup/public/crud_app/sections/job_list/job_list.container.js +++ b/x-pack/plugins/rollup/public/crud_app/sections/job_list/job_list.container.js @@ -32,8 +32,8 @@ const mapDispatchToProps = (dispatch) => { loadJobs: () => { dispatch(loadJobs()); }, - refreshJobs: () => { - dispatch(refreshJobs()); + refreshJobs: (options) => { + dispatch(refreshJobs(options)); }, openDetailPanel: (jobId) => { dispatch(openDetailPanel({ jobId: jobId })); diff --git a/x-pack/plugins/rollup/public/crud_app/sections/job_list/job_list.js b/x-pack/plugins/rollup/public/crud_app/sections/job_list/job_list.js index d5038f40a686b..589546a11ef38 100644 --- a/x-pack/plugins/rollup/public/crud_app/sections/job_list/job_list.js +++ b/x-pack/plugins/rollup/public/crud_app/sections/job_list/job_list.js @@ -73,7 +73,10 @@ export class JobListUi extends Component { } componentDidMount() { - this.interval = setInterval(this.props.refreshJobs, REFRESH_RATE_MS); + this.interval = setInterval( + () => this.props.refreshJobs({ asSystemRequest: true }), + REFRESH_RATE_MS + ); } componentWillUnmount() { diff --git a/x-pack/plugins/rollup/public/crud_app/services/api.js b/x-pack/plugins/rollup/public/crud_app/services/api.js index 66efb6c2f09a0..b12cc62c9daa8 100644 --- a/x-pack/plugins/rollup/public/crud_app/services/api.js +++ b/x-pack/plugins/rollup/public/crud_app/services/api.js @@ -19,8 +19,9 @@ import { trackUserRequest } from './track_ui_metric'; const apiPrefix = '/api/rollup'; -export async function loadJobs() { - const { jobs } = await getHttp().get(`${apiPrefix}/jobs`); +export async function loadJobs({ asSystemRequest } = {}) { + const fetchOptions = { asSystemRequest }; + const { jobs } = await getHttp().get(`${apiPrefix}/jobs`, fetchOptions); return jobs; } diff --git a/x-pack/plugins/rollup/public/crud_app/store/actions/refresh_jobs.js b/x-pack/plugins/rollup/public/crud_app/store/actions/refresh_jobs.js index 37b6e7a893fbe..562341a020523 100644 --- a/x-pack/plugins/rollup/public/crud_app/store/actions/refresh_jobs.js +++ b/x-pack/plugins/rollup/public/crud_app/store/actions/refresh_jobs.js @@ -10,10 +10,10 @@ import { i18n } from '@kbn/i18n'; import { loadJobs as sendLoadJobsRequest, deserializeJobs, showApiWarning } from '../../services'; import { REFRESH_JOBS_SUCCESS } from '../action_types'; -export const refreshJobs = () => async (dispatch) => { +export const refreshJobs = (options) => async (dispatch) => { let jobs; try { - jobs = await sendLoadJobsRequest(); + jobs = await sendLoadJobsRequest(options); } catch (error) { return showApiWarning( error, From d54997041a3a6eb94a6b6c9e8f762b6243033658 Mon Sep 17 00:00:00 2001 From: Joe Portner <5295965+jportner@users.noreply.github.com> Date: Wed, 10 Feb 2021 19:38:24 -0500 Subject: [PATCH 06/12] Fix calls to `/api/cross_cluster_replication/follower_indices` Seen on page: /app/management/data/cross_cluster_replication/follower_indices --- .../cross_cluster_replication/public/app/services/api.js | 3 ++- .../public/app/store/actions/follower_index.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/cross_cluster_replication/public/app/services/api.js b/x-pack/plugins/cross_cluster_replication/public/app/services/api.js index e1be717db221c..8d123c201f7f3 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/services/api.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/services/api.js @@ -100,7 +100,8 @@ export const resumeAutoFollowPattern = (id) => { }; /* Follower Index */ -export const loadFollowerIndices = () => httpClient.get(`${API_BASE_PATH}/follower_indices`); +export const loadFollowerIndices = (asSystemRequest) => + httpClient.get(`${API_BASE_PATH}/follower_indices`, { asSystemRequest }); export const getFollowerIndex = (id) => httpClient.get(`${API_BASE_PATH}/follower_indices/${encodeURIComponent(id)}`); 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 9f8b20622d6ec..7422ba6c84491 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 @@ -40,7 +40,7 @@ export const loadFollowerIndices = (isUpdating = false) => label: t.FOLLOWER_INDEX_LOAD, scope, status: isUpdating ? API_STATUS.UPDATING : API_STATUS.LOADING, - handler: async () => await loadFollowerIndicesRequest(), + handler: async () => await loadFollowerIndicesRequest(isUpdating), }); export const getFollowerIndex = (id) => From 28e1cc6fd9dd2c5d6915a0724186aa572fb4c907 Mon Sep 17 00:00:00 2001 From: Joe Portner <5295965+jportner@users.noreply.github.com> Date: Wed, 10 Feb 2021 19:39:58 -0500 Subject: [PATCH 07/12] Fix calls to `/api/cross_cluster_replication/auto_follow_patterns` Seen on page: /app/management/data/cross_cluster_replication/auto_follow_patterns --- .../cross_cluster_replication/public/app/services/api.js | 3 ++- .../public/app/store/actions/auto_follow_pattern.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/cross_cluster_replication/public/app/services/api.js b/x-pack/plugins/cross_cluster_replication/public/app/services/api.js index 8d123c201f7f3..8067b2cc11b9a 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/services/api.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/services/api.js @@ -48,7 +48,8 @@ export const getHttpClient = () => { const createIdString = (ids) => ids.map((id) => encodeURIComponent(id)).join(','); /* Auto Follow Pattern */ -export const loadAutoFollowPatterns = () => httpClient.get(`${API_BASE_PATH}/auto_follow_patterns`); +export const loadAutoFollowPatterns = (asSystemRequest) => + httpClient.get(`${API_BASE_PATH}/auto_follow_patterns`, { asSystemRequest }); export const getAutoFollowPattern = (id) => httpClient.get(`${API_BASE_PATH}/auto_follow_patterns/${encodeURIComponent(id)}`); 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 e6a9f02b913ca..79d0eeabb817d 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 @@ -39,7 +39,7 @@ export const loadAutoFollowPatterns = (isUpdating = false) => label: t.AUTO_FOLLOW_PATTERN_LOAD, scope, status: isUpdating ? API_STATUS.UPDATING : API_STATUS.LOADING, - handler: async () => await loadAutoFollowPatternsRequest(), + handler: async () => await loadAutoFollowPatternsRequest(isUpdating), }); export const getAutoFollowPattern = (id) => From e756e91eb18d5cd1b9d5120ea8390455a02d0a4b Mon Sep 17 00:00:00 2001 From: Joe Portner <5295965+jportner@users.noreply.github.com> Date: Wed, 10 Feb 2021 19:58:37 -0500 Subject: [PATCH 08/12] Fix calls to `/api/transform/transforms` and `/api/transform/transforms/_stats` Seen on page: /app/management/data/transform --- .../transform/public/app/hooks/use_api.ts | 16 ++++++++++++---- .../public/app/hooks/use_get_transforms.ts | 5 +++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/transform/public/app/hooks/use_api.ts b/x-pack/plugins/transform/public/app/hooks/use_api.ts index 580641cb86bc2..388bc8b432fc4 100644 --- a/x-pack/plugins/transform/public/app/hooks/use_api.ts +++ b/x-pack/plugins/transform/public/app/hooks/use_api.ts @@ -54,6 +54,10 @@ export interface FieldHistogramRequestConfig { type?: KBN_FIELD_TYPES; } +interface FetchOptions { + asSystemRequest?: boolean; +} + export const useApi = () => { const { http } = useAppDependencies(); @@ -68,9 +72,11 @@ export const useApi = () => { return e; } }, - async getTransforms(): Promise { + async getTransforms( + fetchOptions: FetchOptions = {} + ): Promise { try { - return await http.get(`${API_BASE_PATH}transforms`); + return await http.get(`${API_BASE_PATH}transforms`, fetchOptions); } catch (e) { return e; } @@ -84,9 +90,11 @@ export const useApi = () => { return e; } }, - async getTransformsStats(): Promise { + async getTransformsStats( + fetchOptions: FetchOptions = {} + ): Promise { try { - return await http.get(`${API_BASE_PATH}transforms/_stats`); + return await http.get(`${API_BASE_PATH}transforms/_stats`, fetchOptions); } catch (e) { return e; } diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_transforms.ts b/x-pack/plugins/transform/public/app/hooks/use_get_transforms.ts index 919131341cd5b..dbb268b44cfd2 100644 --- a/x-pack/plugins/transform/public/app/hooks/use_get_transforms.ts +++ b/x-pack/plugins/transform/public/app/hooks/use_get_transforms.ts @@ -39,8 +39,9 @@ export const useGetTransforms = ( return; } - const transformConfigs = await api.getTransforms(); - const transformStats = await api.getTransformsStats(); + const fetchOptions = { asSystemRequest: true }; + const transformConfigs = await api.getTransforms(fetchOptions); + const transformStats = await api.getTransformsStats(fetchOptions); if ( !isGetTransformsResponseSchema(transformConfigs) || From ea2193042bffc0691d5b30e09ec9e6b4dd8c8994 Mon Sep 17 00:00:00 2001 From: Joe Portner <5295965+jportner@users.noreply.github.com> Date: Thu, 11 Feb 2021 12:47:29 -0500 Subject: [PATCH 09/12] Fix calls to `/api/console/proxy` Seen on page: /app/dev_tools#/console --- src/plugins/console/public/lib/es/es.ts | 3 ++- src/plugins/console/public/lib/mappings/mappings.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/console/public/lib/es/es.ts b/src/plugins/console/public/lib/es/es.ts index 8053fca91b7d1..2a0065ba69fe5 100644 --- a/src/plugins/console/public/lib/es/es.ts +++ b/src/plugins/console/public/lib/es/es.ts @@ -20,13 +20,14 @@ export function getContentType(body: any) { return 'application/json'; } -export function send(method: string, path: string, data: any) { +export function send(method: string, path: string, data: any, asSystemRequest?: boolean) { const wrappedDfd = $.Deferred(); const options: JQuery.AjaxSettings = { url: '../api/console/proxy?' + stringify({ path, method }, { sort: false }), headers: { 'kbn-xsrf': 'kibana', + ...(asSystemRequest && { 'kbn-system-request': 'true' }), }, data, contentType: getContentType(data), diff --git a/src/plugins/console/public/lib/mappings/mappings.js b/src/plugins/console/public/lib/mappings/mappings.js index 244cc781498a7..d4996f9fd8862 100644 --- a/src/plugins/console/public/lib/mappings/mappings.js +++ b/src/plugins/console/public/lib/mappings/mappings.js @@ -250,7 +250,7 @@ function retrieveSettings(settingsKey, settingsToRetrieve) { // Fetch autocomplete info if setting is set to true, and if user has made changes. if (settingsToRetrieve[settingsKey] === true) { - return es.send('GET', settingKeyToPathMap[settingsKey], null); + return es.send('GET', settingKeyToPathMap[settingsKey], null, true); } else { const settingsPromise = new $.Deferred(); if (settingsToRetrieve[settingsKey] === false) { From 623b447f1514688fd31ea1039152d4d293ae1d98 Mon Sep 17 00:00:00 2001 From: Joe Portner <5295965+jportner@users.noreply.github.com> Date: Thu, 11 Feb 2021 16:55:47 -0500 Subject: [PATCH 10/12] Fix calls to `/api/monitoring/v1/clusters` and `/api/monitoring/v1/elasticsearch_settings/check/cluster` Seen on page: /app/monitoring --- .../checkers/settings_checker.js | 5 ++++- .../monitoring/public/services/clusters.js | 18 +++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/monitoring/public/lib/elasticsearch_settings/checkers/settings_checker.js b/x-pack/plugins/monitoring/public/lib/elasticsearch_settings/checkers/settings_checker.js index 8f19fb6ab87be..4347b70bd549c 100644 --- a/x-pack/plugins/monitoring/public/lib/elasticsearch_settings/checkers/settings_checker.js +++ b/x-pack/plugins/monitoring/public/lib/elasticsearch_settings/checkers/settings_checker.js @@ -44,7 +44,10 @@ export class SettingsChecker { async executeCheck() { try { - const { data } = await this.$http.get(this.getApi()); + console.log('EXECUTE CHECK'); + const { data } = await this.$http.get(this.getApi(), { + headers: { 'kbn-system-request': 'true' }, + }); const { found, reason } = data; return { found, reason }; diff --git a/x-pack/plugins/monitoring/public/services/clusters.js b/x-pack/plugins/monitoring/public/services/clusters.js index 638b3a91b9874..71ae128072b7f 100644 --- a/x-pack/plugins/monitoring/public/services/clusters.js +++ b/x-pack/plugins/monitoring/public/services/clusters.js @@ -38,14 +38,18 @@ export function monitoringClustersProvider($injector) { async function getClusters() { try { - const response = await $http.post(url, { - ccs, - timeRange: { - min: min.toISOString(), - max: max.toISOString(), + const response = await $http.post( + url, + { + ccs, + timeRange: { + min: min.toISOString(), + max: max.toISOString(), + }, + codePaths, }, - codePaths, - }); + { headers: { 'kbn-system-request': 'true' } } + ); return formatClusters(response.data); } catch (err) { const Private = $injector.get('Private'); From 89f3df8469d61431597992124e052c94b86889f0 Mon Sep 17 00:00:00 2001 From: Joe Portner <5295965+jportner@users.noreply.github.com> Date: Mon, 15 Feb 2021 10:23:41 -0500 Subject: [PATCH 11/12] PR review feedback --- src/plugins/console/public/lib/es/es.ts | 11 ++++++++++- .../checkers/settings_checker.js | 1 - 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/plugins/console/public/lib/es/es.ts b/src/plugins/console/public/lib/es/es.ts index 2a0065ba69fe5..03ee218fa2e1d 100644 --- a/src/plugins/console/public/lib/es/es.ts +++ b/src/plugins/console/public/lib/es/es.ts @@ -9,6 +9,10 @@ import $ from 'jquery'; import { stringify } from 'query-string'; +interface SendOptions { + asSystemRequest?: boolean; +} + const esVersion: string[] = []; export function getVersion() { @@ -20,7 +24,12 @@ export function getContentType(body: any) { return 'application/json'; } -export function send(method: string, path: string, data: any, asSystemRequest?: boolean) { +export function send( + method: string, + path: string, + data: any, + { asSystemRequest }: SendOptions = {} +) { const wrappedDfd = $.Deferred(); const options: JQuery.AjaxSettings = { diff --git a/x-pack/plugins/monitoring/public/lib/elasticsearch_settings/checkers/settings_checker.js b/x-pack/plugins/monitoring/public/lib/elasticsearch_settings/checkers/settings_checker.js index 4347b70bd549c..92a172f4ef3df 100644 --- a/x-pack/plugins/monitoring/public/lib/elasticsearch_settings/checkers/settings_checker.js +++ b/x-pack/plugins/monitoring/public/lib/elasticsearch_settings/checkers/settings_checker.js @@ -44,7 +44,6 @@ export class SettingsChecker { async executeCheck() { try { - console.log('EXECUTE CHECK'); const { data } = await this.$http.get(this.getApi(), { headers: { 'kbn-system-request': 'true' }, }); From 1ef7e5a3640b5f2367a478c6c33b0a42bf89e65c Mon Sep 17 00:00:00 2001 From: Joe Portner <5295965+jportner@users.noreply.github.com> Date: Mon, 15 Feb 2021 13:11:18 -0500 Subject: [PATCH 12/12] More PR review feedback --- .../es_ui_shared/public/request/send_request.ts | 4 ++++ .../es_ui_shared/public/request/use_request.ts | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/plugins/es_ui_shared/public/request/send_request.ts b/src/plugins/es_ui_shared/public/request/send_request.ts index 889ec59d91a4b..11ab99cfb6978 100644 --- a/src/plugins/es_ui_shared/public/request/send_request.ts +++ b/src/plugins/es_ui_shared/public/request/send_request.ts @@ -13,6 +13,10 @@ export interface SendRequestConfig { method: 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head'; query?: HttpFetchQuery; body?: any; + /** + * If set, flags this as a "system request" to indicate that this is not a user-initiated request. For more information, see + * HttpFetchOptions#asSystemRequest. + */ asSystemRequest?: boolean; } diff --git a/src/plugins/es_ui_shared/public/request/use_request.ts b/src/plugins/es_ui_shared/public/request/use_request.ts index 7d939141b7969..33085bdbf4478 100644 --- a/src/plugins/es_ui_shared/public/request/use_request.ts +++ b/src/plugins/es_ui_shared/public/request/use_request.ts @@ -77,6 +77,9 @@ export const useRequest = ( // "old" error/data or loading state when a new request is in-flight. setIsLoading(true); + // Any requests that are sent in the background (without user interaction) should be flagged as "system requests". This should not be + // confused with any terminology in Elasticsearch. This is a Kibana-specific construct that allows the server to differentiate between + // user-initiated and requests "system"-initiated requests, for purposes like security features. const requestPayload = { ...requestBody, asSystemRequest }; const response = await sendRequest(httpClient, requestPayload); const { data: serializedResponseData, error: responseError } = response; @@ -111,7 +114,10 @@ export const useRequest = ( clearPollInterval(); if (pollIntervalMs) { - pollIntervalIdRef.current = setTimeout(() => resendRequest(true), pollIntervalMs); + pollIntervalIdRef.current = setTimeout( + () => resendRequest(true), // This is happening on an interval in the background, so we flag it as a "system request". + pollIntervalMs + ); } }, [pollIntervalMs, resendRequest, clearPollInterval]); @@ -141,11 +147,15 @@ export const useRequest = ( }; }, [clearPollInterval]); + const resendRequestForConsumer = useCallback(() => { + return resendRequest(); + }, [resendRequest]); + return { isInitialRequest: isInitialRequestRef.current, isLoading, error, data, - resendRequest, // Gives the user the ability to manually request data + resendRequest: resendRequestForConsumer, // Gives the user the ability to manually request data }; };