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. ' +
+ '
' +
+ '- sessionId: restricts operations to execute all search requests on the same shards. ' +
+ 'This has the benefit of reusing shard caches across requests. ' +
+ '
- custom: allows you to define a your own preference. ' +
+ 'Use courier:customRequestPreference to customize your preference value. ' +
+ '
- none: means do not set a preference. ' +
+ 'This might provide better performance because requests can be spread across all shard copies. ' +
+ 'However, results might be inconsistent because different shards might be in different refresh states.' +
+ '
'
+ },
+ '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)
);
}