diff --git a/src/core_plugins/kibana/ui_setting_defaults.js b/src/core_plugins/kibana/ui_setting_defaults.js index fa4f05720ecfc..7168c0a835f35 100644 --- a/src/core_plugins/kibana/ui_setting_defaults.js +++ b/src/core_plugins/kibana/ui_setting_defaults.js @@ -115,6 +115,27 @@ export function getUiSettingDefaults() { 'When set to true, filter(s) will be ignored for a visualization ' + 'when the visualization\'s index does not contain the filtering field.' }, + 'courier:setRequestPreference': { + value: 'sessionId', + options: ['sessionId', 'custom', 'none'], + type: 'select', + description: 'Allows you to set which shards handle your search requests. ' + + '' + }, + 'courier:customRequestPreference': { + value: '_local', + type: 'string', + description: 'Request Preference ' + + ' used when courier:setRequestPreference is set to "custom".' + }, 'fields:popularLimit': { value: 10, description: 'The top N most popular fields to show', diff --git a/src/ui/public/courier/fetch/request/request_fetch_params_to_body.js b/src/ui/public/courier/fetch/request/request_fetch_params_to_body.js index cb7787a0f0cb1..efecfe4b5c4b9 100644 --- a/src/ui/public/courier/fetch/request/request_fetch_params_to_body.js +++ b/src/ui/public/courier/fetch/request/request_fetch_params_to_body.js @@ -30,7 +30,8 @@ export function requestFetchParamsToBody( Promise, timeFilter, kbnIndex, - sessionId) { + sessionId, + config) { const indexToListMapping = {}; const timeBounds = timeFilter.getActiveBounds(); const promises = requestsFetchParams.map(function (fetchParams) { @@ -68,15 +69,19 @@ export function requestFetchParamsToBody( index = indexList; } - return JSON.stringify({ + const header = { index, type: fetchParams.type, search_type: fetchParams.search_type, ignore_unavailable: true, - preference: sessionId, - }) - + '\n' - + toJson(body, JSON.stringify); + }; + if (config.get('courier:setRequestPreference') === 'sessionId') { + header.preference = sessionId; + } else if (config.get('courier:setRequestPreference') === 'custom') { + header.preference = config.get('courier:customRequestPreference'); + } + + return `${JSON.stringify(header)}\n${toJson(body, JSON.stringify)}`; }); }); diff --git a/src/ui/public/courier/fetch/request/request_fetch_params_to_body.test.js b/src/ui/public/courier/fetch/request/request_fetch_params_to_body.test.js index 7028c5764ffce..e289ed82c9131 100644 --- a/src/ui/public/courier/fetch/request/request_fetch_params_to_body.test.js +++ b/src/ui/public/courier/fetch/request/request_fetch_params_to_body.test.js @@ -1,6 +1,8 @@ import { requestFetchParamsToBody } from './request_fetch_params_to_body'; import _ from 'lodash'; +const DEFAULT_SESSION_ID = '1'; + function requestFetchParamsToBodyWithDefaults(paramOverrides) { const paramDefaults = { requestFetchParams: [], @@ -9,7 +11,12 @@ function requestFetchParamsToBodyWithDefaults(paramOverrides) { getActiveBounds: () => undefined, }, kbnIndex: '.kibana', - sessionId: '1', + sessionId: DEFAULT_SESSION_ID, + config: { + get: () => { + return 'sessionId'; + } + } }; const params = { ...paramDefaults, ...paramOverrides }; @@ -19,6 +26,7 @@ function requestFetchParamsToBodyWithDefaults(paramOverrides) { params.timeFilter, params.kbnIndex, params.sessionId, + params.config, ); } @@ -73,10 +81,68 @@ describe('when indexList is empty', () => { } ]; - it('queries the kibana index (.kibana) with a must_not match_all boolean', () => { + test('queries the kibana index (.kibana) with a must_not match_all boolean', () => { return requestFetchParamsToBodyWithDefaults({ requestFetchParams }).then(value => { expect(_.includes(value, '"index":[".kibana"]')).toBe(true); expect(_.includes(value, emptyMustNotQuery)).toBe(true); }); }); }); + +describe('headers', () => { + + const requestFetchParams = [ + { + index: ['logstash-123'], + type: 'blah', + search_type: 'blah2', + body: { foo: 'bar' } + } + ]; + + const getHeader = async (paramOverrides) => { + const request = await requestFetchParamsToBodyWithDefaults(paramOverrides); + const requestParts = request.split('\n'); + if (requestParts.length < 2) { + throw new Error('fetch Body does not contain expected format header newline body.'); + } + return JSON.parse(requestParts[0]); + }; + + describe('search request preference', async () => { + test('should be set to sessionId when courier:setRequestPreference is "sessionId"', async () => { + const config = { + get: () => { + return 'sessionId'; + } + }; + const header = await getHeader({ requestFetchParams, config }); + expect(header.preference).toBe(DEFAULT_SESSION_ID); + }); + + test('should be set to custom string when courier:setRequestPreference is "custom"', async () => { + const CUSTOM_PREFERENCE = '_local'; + const config = { + get: (key) => { + if (key === 'courier:setRequestPreference') { + return 'custom'; + } else if (key === 'courier:customRequestPreference') { + return CUSTOM_PREFERENCE; + } + } + }; + const header = await getHeader({ requestFetchParams, config }); + expect(header.preference).toBe(CUSTOM_PREFERENCE); + }); + + test('should not be set when courier:setRequestPreference is "none"', async () => { + const config = { + get: () => { + return 'none'; + } + }; + const header = await getHeader({ requestFetchParams, config }); + expect(header.preference).toBe(undefined); + }); + }); +}); diff --git a/src/ui/public/courier/fetch/request/request_fetch_params_to_body_provider.js b/src/ui/public/courier/fetch/request/request_fetch_params_to_body_provider.js index 169d7cc6711f1..4e3f1fdf5110e 100644 --- a/src/ui/public/courier/fetch/request/request_fetch_params_to_body_provider.js +++ b/src/ui/public/courier/fetch/request/request_fetch_params_to_body_provider.js @@ -1,12 +1,13 @@ import { requestFetchParamsToBody } from './request_fetch_params_to_body'; -export function RequestFetchParamsToBodyProvider(Promise, timefilter, kbnIndex, sessionId) { +export function RequestFetchParamsToBodyProvider(Promise, timefilter, kbnIndex, sessionId, config) { return (requestsFetchParams) => ( requestFetchParamsToBody( requestsFetchParams, Promise, timefilter, kbnIndex, - sessionId) + sessionId, + config) ); }