Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Maps] Implement searchSessionId in MapEmbeddable #89342

Merged
merged 11 commits into from
Jan 29, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export type MapFilters = {
filters: Filter[];
query?: MapQuery;
refreshTimerLastTriggeredAt?: string;
searchSessionId?: string;
timeFilters: TimeRange;
zoom: number;
};
Expand Down
20 changes: 20 additions & 0 deletions x-pack/plugins/maps/public/actions/map_actions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ describe('map_actions', () => {
$state: { store: 'appState' },
},
];
const searchSessionId = '1234';

beforeEach(() => {
//Mocks the "previous" state
Expand All @@ -272,6 +273,9 @@ describe('map_actions', () => {
require('../selectors/map_selectors').getFilters = () => {
return filters;
};
require('../selectors/map_selectors').getSearchSessionId = () => {
return searchSessionId;
};
require('../selectors/map_selectors').getMapSettings = () => {
return {
autoFitToDataBounds: false,
Expand All @@ -288,12 +292,14 @@ describe('map_actions', () => {
const setQueryAction = await setQuery({
query: newQuery,
filters,
searchSessionId,
});
await setQueryAction(dispatchMock, getStoreMock);

expect(dispatchMock.mock.calls).toEqual([
[
{
searchSessionId,
timeFilters,
query: newQuery,
filters,
Expand All @@ -304,11 +310,25 @@ describe('map_actions', () => {
]);
});

it('should dispatch query action when searchSessionId changes', async () => {
const setQueryAction = await setQuery({
timeFilters,
query,
filters,
searchSessionId: '5678',
});
await setQueryAction(dispatchMock, getStoreMock);

// dispatchMock calls: dispatch(SET_QUERY) and dispatch(syncDataForAllLayers())
expect(dispatchMock.mock.calls.length).toEqual(2);
});

it('should not dispatch query action when nothing changes', async () => {
const setQueryAction = await setQuery({
timeFilters,
query,
filters,
searchSessionId,
});
await setQueryAction(dispatchMock, getStoreMock);

Expand Down
5 changes: 5 additions & 0 deletions x-pack/plugins/maps/public/actions/map_actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
getQuery,
getTimeFilters,
getLayerList,
getSearchSessionId,
} from '../selectors/map_selectors';
import {
CLEAR_GOTO,
Expand Down Expand Up @@ -225,11 +226,13 @@ export function setQuery({
timeFilters,
filters = [],
forceRefresh = false,
searchSessionId,
}: {
filters?: Filter[];
query?: Query;
timeFilters?: TimeRange;
forceRefresh?: boolean;
searchSessionId?: string;
}) {
return async (
dispatch: ThunkDispatch<MapStoreState, void, AnyAction>,
Expand All @@ -249,12 +252,14 @@ export function setQuery({
queryLastTriggeredAt: forceRefresh ? generateQueryTimestamp() : prevTriggeredAt,
},
filters: filters ? filters : getFilters(getState()),
searchSessionId,
};

const prevQueryContext = {
timeFilters: getTimeFilters(getState()),
query: getQuery(getState()),
filters: getFilters(getState()),
searchSessionId: getSearchSessionId(getState()),
};

if (_.isEqual(nextQueryContext, prevQueryContext)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,10 @@ export class BlendedVectorLayer extends VectorLayer implements IVectorLayer {
const abortController = new AbortController();
syncContext.registerCancelCallback(requestToken, () => abortController.abort());
const searchSource = await this._documentSource.makeSearchSource(searchFilters, 0);
const resp = await searchSource.fetch({ abortSignal: abortController.signal });
const resp = await searchSource.fetch({
abortSignal: abortController.signal,
sessionId: syncContext.dataFilters.searchSessionId,
});
const maxResultWindow = await this._documentSource.getMaxResultWindow();
isSyncClustered = resp.hits.total > maxResultWindow;
const countData = { isSyncClustered } as CountData;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,7 @@ export class VectorLayer extends AbstractLayer {
sourceQuery,
isTimeAware: this.getCurrentStyle().isTimeAware() && (await source.isTimeAware()),
timeFilters: dataFilters.timeFilters,
searchSessionId: dataFilters.searchSessionId,
} as VectorStyleRequestMeta;
const prevDataRequest = this.getDataRequest(dataRequestId);
const canSkipFetch = canSkipStyleMetaUpdate({ prevDataRequest, nextMeta });
Expand All @@ -635,6 +636,7 @@ export class VectorLayer extends AbstractLayer {
registerCancelCallback: registerCancelCallback.bind(null, requestToken),
sourceQuery: nextMeta.sourceQuery,
timeFilters: nextMeta.timeFilters,
searchSessionId: dataFilters.searchSessionId,
});
stopLoading(dataRequestId, requestToken, styleMeta, nextMeta);
} catch (error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ export class ESGeoGridSource extends AbstractESAggSource implements ITiledSingle

async _compositeAggRequest({
searchSource,
searchSessionId,
indexPattern,
precision,
layerName,
Expand All @@ -204,6 +205,7 @@ export class ESGeoGridSource extends AbstractESAggSource implements ITiledSingle
bufferedExtent,
}: {
searchSource: ISearchSource;
searchSessionId?: string;
indexPattern: IndexPattern;
precision: number;
layerName: string;
Expand Down Expand Up @@ -280,6 +282,7 @@ export class ESGeoGridSource extends AbstractESAggSource implements ITiledSingle
values: { requestId },
}
),
searchSessionId,
});

features.push(...convertCompositeRespToGeoJson(esResponse, this._descriptor.requestType));
Expand Down Expand Up @@ -325,13 +328,15 @@ export class ESGeoGridSource extends AbstractESAggSource implements ITiledSingle
// see https://github.com/elastic/kibana/pull/57875#issuecomment-590515482 for explanation on using separate code paths
async _nonCompositeAggRequest({
searchSource,
searchSessionId,
indexPattern,
precision,
layerName,
registerCancelCallback,
bufferedExtent,
}: {
searchSource: ISearchSource;
searchSessionId?: string;
indexPattern: IndexPattern;
precision: number;
layerName: string;
Expand All @@ -348,6 +353,7 @@ export class ESGeoGridSource extends AbstractESAggSource implements ITiledSingle
requestDescription: i18n.translate('xpack.maps.source.esGrid.inspectorDescription', {
defaultMessage: 'Elasticsearch geo grid aggregation request',
}),
searchSessionId,
});

return convertRegularRespToGeoJson(esResponse, this._descriptor.requestType);
Expand All @@ -373,6 +379,7 @@ export class ESGeoGridSource extends AbstractESAggSource implements ITiledSingle
bucketsPerGrid === 1
? await this._nonCompositeAggRequest({
searchSource,
searchSessionId: searchFilters.searchSessionId,
indexPattern,
precision: searchFilters.geogridPrecision || 0,
layerName,
Expand All @@ -381,6 +388,7 @@ export class ESGeoGridSource extends AbstractESAggSource implements ITiledSingle
})
: await this._compositeAggRequest({
searchSource,
searchSessionId: searchFilters.searchSessionId,
indexPattern,
precision: searchFilters.geogridPrecision || 0,
layerName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ export class ESGeoLineSource extends AbstractESAggSource {
requestDescription: i18n.translate('xpack.maps.source.esGeoLine.entityRequestDescription', {
defaultMessage: 'Elasticsearch terms request to fetch entities within map buffer.',
}),
searchSessionId: searchFilters.searchSessionId,
});
const entityBuckets: Array<{ key: string; doc_count: number }> = _.get(
entityResp,
Expand Down Expand Up @@ -282,6 +283,7 @@ export class ESGeoLineSource extends AbstractESAggSource {
defaultMessage:
'Elasticsearch geo_line request to fetch tracks for entities. Tracks are not filtered by map buffer.',
}),
searchSessionId: searchFilters.searchSessionId,
});
const { featureCollection, numTrimmedTracks } = convertToGeoJson(
tracksResp,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ export class ESPewPewSource extends AbstractESAggSource {
requestDescription: i18n.translate('xpack.maps.source.pewPew.inspectorDescription', {
defaultMessage: 'Source-destination connections request',
}),
searchSessionId: searchFilters.searchSessionId,
});

const { featureCollection } = convertToLines(esResponse);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye
searchSource,
registerCancelCallback,
requestDescription: 'Elasticsearch document top hits request',
searchSessionId: searchFilters.searchSessionId,
});

const allHits: any[] = [];
Expand Down Expand Up @@ -391,6 +392,7 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye
searchSource,
registerCancelCallback,
requestDescription: 'Elasticsearch document request',
searchSessionId: searchFilters.searchSessionId,
});

return {
Expand Down
21 changes: 16 additions & 5 deletions x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,15 @@ export interface IESSource extends IVectorSource {
registerCancelCallback,
sourceQuery,
timeFilters,
searchSessionId,
}: {
layerName: string;
style: IVectorStyle;
dynamicStyleProps: Array<IDynamicStyleProperty<DynamicStylePropertyOptions>>;
registerCancelCallback: (callback: () => void) => void;
sourceQuery?: MapQuery;
timeFilters: TimeRange;
searchSessionId?: string;
}): Promise<object>;
}

Expand Down Expand Up @@ -151,17 +153,19 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource
}

async _runEsQuery({
registerCancelCallback,
requestDescription,
requestId,
requestName,
requestDescription,
searchSessionId,
searchSource,
registerCancelCallback,
}: {
registerCancelCallback: (callback: () => void) => void;
requestDescription: string;
requestId: string;
requestName: string;
requestDescription: string;
searchSessionId?: string;
searchSource: ISearchSource;
registerCancelCallback: (callback: () => void) => void;
}): Promise<any> {
const abortController = new AbortController();
registerCancelCallback(() => abortController.abort());
Expand All @@ -172,6 +176,7 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource
inspectorRequest = inspectorAdapters.requests.start(requestName, {
id: requestId,
description: requestDescription,
searchSessionId,
});
}

Expand All @@ -186,7 +191,10 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource
}
});
}
resp = await searchSource.fetch({ abortSignal: abortController.signal });
resp = await searchSource.fetch({
abortSignal: abortController.signal,
sessionId: searchSessionId,
});
if (inspectorRequest) {
const responseStats = search.getResponseInspectorStats(resp, searchSource);
inspectorRequest.stats(responseStats).ok({ json: resp });
Expand Down Expand Up @@ -404,13 +412,15 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource
registerCancelCallback,
sourceQuery,
timeFilters,
searchSessionId,
}: {
layerName: string;
style: IVectorStyle;
dynamicStyleProps: Array<IDynamicStyleProperty<DynamicStylePropertyOptions>>;
registerCancelCallback: (callback: () => void) => void;
sourceQuery?: MapQuery;
timeFilters: TimeRange;
searchSessionId?: string;
}): Promise<object> {
const promises = dynamicStyleProps.map((dynamicStyleProp) => {
return dynamicStyleProp.getFieldMetaRequest();
Expand Down Expand Up @@ -456,6 +466,7 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource
'Elasticsearch request retrieving field metadata used for calculating symbolization bands.',
}
),
searchSessionId,
});

return resp.aggregations;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ export class ESTermSource extends AbstractESAggSource {
rightSource: `${this._descriptor.indexPatternTitle}:${this._termField.getName()}`,
},
}),
searchSessionId: searchFilters.searchSessionId,
});

const countPropertyName = this.getAggKey(AGG_TYPE.COUNT);
Expand Down
17 changes: 15 additions & 2 deletions x-pack/plugins/maps/public/classes/util/can_skip_fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export async function canSkipSourceUpdate({
if (isQueryAware) {
updateDueToApplyGlobalQuery = prevMeta.applyGlobalQuery !== nextMeta.applyGlobalQuery;
updateDueToSourceQuery = !_.isEqual(prevMeta.sourceQuery, nextMeta.sourceQuery);

if (nextMeta.applyGlobalQuery) {
updateDueToQuery = !_.isEqual(prevMeta.query, nextMeta.query);
updateDueToFilters = !_.isEqual(prevMeta.filters, nextMeta.filters);
Expand All @@ -123,6 +124,11 @@ export async function canSkipSourceUpdate({
}
}

let updateDueToSearchSessionId = false;
if (timeAware || isQueryAware) {
updateDueToSearchSessionId = prevMeta.searchSessionId !== nextMeta.searchSessionId;
}

let updateDueToPrecisionChange = false;
if (isGeoGridPrecisionAware) {
updateDueToPrecisionChange = !_.isEqual(prevMeta.geogridPrecision, nextMeta.geogridPrecision);
Expand All @@ -146,7 +152,8 @@ export async function canSkipSourceUpdate({
!updateDueToSourceQuery &&
!updateDueToApplyGlobalQuery &&
!updateDueToPrecisionChange &&
!updateDueToSourceMetaChange
!updateDueToSourceMetaChange &&
!updateDueToSearchSessionId
);
}

Expand Down Expand Up @@ -174,8 +181,14 @@ export function canSkipStyleMetaUpdate({
? !_.isEqual(prevMeta.timeFilters, nextMeta.timeFilters)
: false;

const updateDueToSearchSessionId = prevMeta.searchSessionId !== nextMeta.searchSessionId;

return (
!updateDueToFields && !updateDueToSourceQuery && !updateDueToIsTimeAware && !updateDueToTime
!updateDueToFields &&
!updateDueToSourceQuery &&
!updateDueToIsTimeAware &&
!updateDueToTime &&
!updateDueToSearchSessionId
);
}

Expand Down
Loading