Skip to content

Commit 9041ea5

Browse files
authored
[Lens] Migrate legacy es client and remove total hits as int (#84340)
1 parent 3ae7365 commit 9041ea5

File tree

6 files changed

+54
-59
lines changed

6 files changed

+54
-59
lines changed

x-pack/plugins/lens/server/routes/existing_fields.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
*/
66

77
import Boom from '@hapi/boom';
8+
import { errors } from '@elastic/elasticsearch';
89
import { schema } from '@kbn/config-schema';
9-
import { ILegacyScopedClusterClient, RequestHandlerContext } from 'src/core/server';
10+
import { RequestHandlerContext, ElasticsearchClient } from 'src/core/server';
1011
import { CoreSetup, Logger } from 'src/core/server';
1112
import { IndexPattern, IndexPatternsService } from 'src/plugins/data/common';
1213
import { BASE_API_URL } from '../../common';
@@ -68,7 +69,7 @@ export async function existingFieldsRoute(setup: CoreSetup<PluginStartContract>,
6869
logger.info(
6970
`Field existence check failed: ${isBoomError(e) ? e.output.payload.message : e.message}`
7071
);
71-
if (e.status === 404) {
72+
if (e instanceof errors.ResponseError && e.statusCode === 404) {
7273
return res.notFound({ body: e.message });
7374
}
7475
if (isBoomError(e)) {
@@ -111,7 +112,7 @@ async function fetchFieldExistence({
111112
fromDate,
112113
toDate,
113114
dslQuery,
114-
client: context.core.elasticsearch.legacy.client,
115+
client: context.core.elasticsearch.client.asCurrentUser,
115116
index: indexPattern.title,
116117
timeFieldName: timeFieldName || indexPattern.timeFieldName,
117118
fields,
@@ -149,7 +150,7 @@ async function fetchIndexPatternStats({
149150
toDate,
150151
fields,
151152
}: {
152-
client: ILegacyScopedClusterClient;
153+
client: ElasticsearchClient;
153154
index: string;
154155
dslQuery: object;
155156
timeFieldName?: string;
@@ -179,7 +180,7 @@ async function fetchIndexPatternStats({
179180
};
180181

181182
const scriptedFields = fields.filter((f) => f.isScript);
182-
const result = await client.callAsCurrentUser('search', {
183+
const { body: result } = await client.search({
183184
index,
184185
body: {
185186
size: SAMPLE_SIZE,

x-pack/plugins/lens/server/routes/field_stats.ts

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
import Boom from '@hapi/boom';
8+
import { errors } from '@elastic/elasticsearch';
89
import DateMath from '@elastic/datemath';
910
import { schema } from '@kbn/config-schema';
1011
import { CoreSetup } from 'src/core/server';
@@ -47,7 +48,7 @@ export async function initFieldsRoute(setup: CoreSetup<PluginStartContract>) {
4748
},
4849
},
4950
async (context, req, res) => {
50-
const requestClient = context.core.elasticsearch.legacy.client;
51+
const requestClient = context.core.elasticsearch.client.asCurrentUser;
5152
const { fromDate, toDate, timeFieldName, field, dslQuery } = req.body;
5253

5354
try {
@@ -71,18 +72,18 @@ export async function initFieldsRoute(setup: CoreSetup<PluginStartContract>) {
7172
},
7273
};
7374

74-
const search = (aggs: unknown) =>
75-
requestClient.callAsCurrentUser('search', {
75+
const search = async (aggs: unknown) => {
76+
const { body: result } = await requestClient.search({
7677
index: req.params.indexPatternTitle,
78+
track_total_hits: true,
7779
body: {
7880
query,
7981
aggs,
8082
},
81-
// The hits total changed in 7.0 from number to object, unless this flag is set
82-
// this is a workaround for elasticsearch response types that are from 6.x
83-
restTotalHitsAsInt: true,
8483
size: 0,
8584
});
85+
return result;
86+
};
8687

8788
if (field.type === 'number') {
8889
return res.ok({
@@ -98,7 +99,7 @@ export async function initFieldsRoute(setup: CoreSetup<PluginStartContract>) {
9899
body: await getStringSamples(search, field),
99100
});
100101
} catch (e) {
101-
if (e.status === 404) {
102+
if (e instanceof errors.ResponseError && e.statusCode === 404) {
102103
return res.notFound();
103104
}
104105
if (e.isBoom) {
@@ -142,8 +143,7 @@ export async function getNumberHistogram(
142143

143144
const minMaxResult = (await aggSearchWithBody(searchBody)) as ESSearchResponse<
144145
unknown,
145-
{ body: { aggs: typeof searchBody } },
146-
{ restTotalHitsAsInt: true }
146+
{ body: { aggs: typeof searchBody } }
147147
>;
148148

149149
const minValue = minMaxResult.aggregations!.sample.min_value.value;
@@ -164,7 +164,7 @@ export async function getNumberHistogram(
164164

165165
if (histogramInterval === 0) {
166166
return {
167-
totalDocuments: minMaxResult.hits.total,
167+
totalDocuments: minMaxResult.hits.total.value,
168168
sampledValues: minMaxResult.aggregations!.sample.sample_count.value!,
169169
sampledDocuments: minMaxResult.aggregations!.sample.doc_count,
170170
topValues: topValuesBuckets,
@@ -187,12 +187,11 @@ export async function getNumberHistogram(
187187
};
188188
const histogramResult = (await aggSearchWithBody(histogramBody)) as ESSearchResponse<
189189
unknown,
190-
{ body: { aggs: typeof histogramBody } },
191-
{ restTotalHitsAsInt: true }
190+
{ body: { aggs: typeof histogramBody } }
192191
>;
193192

194193
return {
195-
totalDocuments: minMaxResult.hits.total,
194+
totalDocuments: minMaxResult.hits.total.value,
196195
sampledDocuments: minMaxResult.aggregations!.sample.doc_count,
197196
sampledValues: minMaxResult.aggregations!.sample.sample_count.value!,
198197
histogram: {
@@ -227,12 +226,11 @@ export async function getStringSamples(
227226
};
228227
const topValuesResult = (await aggSearchWithBody(topValuesBody)) as ESSearchResponse<
229228
unknown,
230-
{ body: { aggs: typeof topValuesBody } },
231-
{ restTotalHitsAsInt: true }
229+
{ body: { aggs: typeof topValuesBody } }
232230
>;
233231

234232
return {
235-
totalDocuments: topValuesResult.hits.total,
233+
totalDocuments: topValuesResult.hits.total.value,
236234
sampledDocuments: topValuesResult.aggregations!.sample.doc_count,
237235
sampledValues: topValuesResult.aggregations!.sample.sample_count.value!,
238236
topValues: {
@@ -275,12 +273,11 @@ export async function getDateHistogram(
275273
};
276274
const results = (await aggSearchWithBody(histogramBody)) as ESSearchResponse<
277275
unknown,
278-
{ body: { aggs: typeof histogramBody } },
279-
{ restTotalHitsAsInt: true }
276+
{ body: { aggs: typeof histogramBody } }
280277
>;
281278

282279
return {
283-
totalDocuments: results.hits.total,
280+
totalDocuments: results.hits.total.value,
284281
histogram: {
285282
buckets: results.aggregations!.histo.buckets.map((bucket) => ({
286283
count: bucket.doc_count,

x-pack/plugins/lens/server/routes/telemetry.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
import Boom from '@hapi/boom';
8+
import { errors } from '@elastic/elasticsearch';
89
import { CoreSetup } from 'src/core/server';
910
import { schema } from '@kbn/config-schema';
1011
import { BASE_API_URL } from '../../common';
@@ -71,7 +72,7 @@ export async function initLensUsageRoute(setup: CoreSetup<PluginStartContract>)
7172

7273
return res.ok({ body: {} });
7374
} catch (e) {
74-
if (e.status === 404) {
75+
if (e instanceof errors.ResponseError && e.statusCode === 404) {
7576
return res.notFound();
7677
}
7778
if (e.isBoom) {

x-pack/plugins/lens/server/usage/task.ts

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
import { LegacyAPICaller, CoreSetup, Logger } from 'kibana/server';
7+
import { CoreSetup, Logger, ElasticsearchClient } from 'kibana/server';
88
import { Observable } from 'rxjs';
99
import { first } from 'rxjs/operators';
1010
import moment from 'moment';
@@ -69,11 +69,12 @@ async function scheduleTasks(logger: Logger, taskManager: TaskManagerStartContra
6969

7070
export async function getDailyEvents(
7171
kibanaIndex: string,
72-
callCluster: LegacyAPICaller
72+
getEsClient: () => Promise<ElasticsearchClient>
7373
): Promise<{
7474
byDate: Record<string, Record<string, number>>;
7575
suggestionsByDate: Record<string, Record<string, number>>;
7676
}> {
77+
const esClient = await getEsClient();
7778
const aggs = {
7879
daily: {
7980
date_histogram: {
@@ -114,15 +115,10 @@ export async function getDailyEvents(
114115
},
115116
};
116117

117-
const metrics: ESSearchResponse<
118-
unknown,
119-
{
120-
body: { aggs: typeof aggs };
121-
},
122-
{ restTotalHitsAsInt: true }
123-
> = await callCluster('search', {
118+
const { body: metrics } = await esClient.search<
119+
ESSearchResponse<unknown, { body: { aggs: typeof aggs } }>
120+
>({
124121
index: kibanaIndex,
125-
rest_total_hits_as_int: true,
126122
body: {
127123
query: {
128124
bool: {
@@ -156,9 +152,9 @@ export async function getDailyEvents(
156152
});
157153

158154
// Always delete old date because we don't report it
159-
await callCluster('deleteByQuery', {
155+
await esClient.deleteByQuery({
160156
index: kibanaIndex,
161-
waitForCompletion: true,
157+
wait_for_completion: true,
162158
body: {
163159
query: {
164160
bool: {
@@ -184,18 +180,18 @@ export function telemetryTaskRunner(
184180
) {
185181
return ({ taskInstance }: RunContext) => {
186182
const { state } = taskInstance;
187-
const callCluster = async (...args: Parameters<LegacyAPICaller>) => {
183+
const getEsClient = async () => {
188184
const [coreStart] = await core.getStartServices();
189-
return coreStart.elasticsearch.legacy.client.callAsInternalUser(...args);
185+
return coreStart.elasticsearch.client.asInternalUser;
190186
};
191187

192188
return {
193189
async run() {
194190
const kibanaIndex = (await config.pipe(first()).toPromise()).kibana.index;
195191

196192
return Promise.all([
197-
getDailyEvents(kibanaIndex, callCluster),
198-
getVisualizationCounts(callCluster, kibanaIndex),
193+
getDailyEvents(kibanaIndex, getEsClient),
194+
getVisualizationCounts(getEsClient, kibanaIndex),
199195
])
200196
.then(([lensTelemetry, lensVisualizations]) => {
201197
return {

x-pack/plugins/lens/server/usage/visualization_counts.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
import { LegacyAPICaller } from 'kibana/server';
7+
import { ElasticsearchClient } from 'kibana/server';
88
import { LensVisualizationUsage } from './types';
99

1010
export async function getVisualizationCounts(
11-
callCluster: LegacyAPICaller,
11+
getEsClient: () => Promise<ElasticsearchClient>,
1212
kibanaIndex: string
1313
): Promise<LensVisualizationUsage> {
14-
const results = await callCluster('search', {
14+
const esClient = await getEsClient();
15+
const { body: results } = await esClient.search({
1516
index: kibanaIndex,
16-
rest_total_hits_as_int: true,
1717
body: {
1818
query: {
1919
bool: {

x-pack/test/api_integration/apis/lens/telemetry.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66

77
import moment from 'moment';
88
import expect from '@kbn/expect';
9-
import { Client, SearchParams } from 'elasticsearch';
10-
import { LegacyAPICaller } from 'kibana/server';
9+
import { Client } from '@elastic/elasticsearch';
1110

1211
import { FtrProviderContext } from '../../ftr_provider_context';
1312

@@ -20,18 +19,17 @@ const COMMON_HEADERS = {
2019

2120
export default ({ getService }: FtrProviderContext) => {
2221
const supertest = getService('supertest');
23-
const es: Client = getService('legacyEs');
24-
const callCluster: LegacyAPICaller = (((path: 'search', searchParams: SearchParams) => {
25-
return es[path].call(es, searchParams);
26-
}) as unknown) as LegacyAPICaller;
22+
const es: Client = getService('es');
2723

2824
async function assertExpectedSavedObjects(num: number) {
2925
// Make sure that new/deleted docs are available to search
3026
await es.indices.refresh({
3127
index: '.kibana',
3228
});
3329

34-
const { count } = await es.count({
30+
const {
31+
body: { count },
32+
} = await es.count({
3533
index: '.kibana',
3634
q: 'type:lens-ui-telemetry',
3735
});
@@ -44,17 +42,19 @@ export default ({ getService }: FtrProviderContext) => {
4442
await es.deleteByQuery({
4543
index: '.kibana',
4644
q: 'type:lens-ui-telemetry',
47-
waitForCompletion: true,
48-
refresh: 'wait_for',
45+
wait_for_completion: true,
46+
refresh: true,
47+
body: {},
4948
});
5049
});
5150

5251
afterEach(async () => {
5352
await es.deleteByQuery({
5453
index: '.kibana',
5554
q: 'type:lens-ui-telemetry',
56-
waitForCompletion: true,
57-
refresh: 'wait_for',
55+
wait_for_completion: true,
56+
refresh: true,
57+
body: {},
5858
});
5959
});
6060

@@ -107,7 +107,7 @@ export default ({ getService }: FtrProviderContext) => {
107107
refresh: 'wait_for',
108108
});
109109

110-
const result = await getDailyEvents('.kibana', callCluster);
110+
const result = await getDailyEvents('.kibana', () => Promise.resolve(es));
111111

112112
expect(result).to.eql({
113113
byDate: {},
@@ -150,7 +150,7 @@ export default ({ getService }: FtrProviderContext) => {
150150
],
151151
});
152152

153-
const result = await getDailyEvents('.kibana', callCluster);
153+
const result = await getDailyEvents('.kibana', () => Promise.resolve(es));
154154

155155
expect(result).to.eql({
156156
byDate: {
@@ -177,7 +177,7 @@ export default ({ getService }: FtrProviderContext) => {
177177

178178
await esArchiver.loadIfNeeded('lens/basic');
179179

180-
const results = await getVisualizationCounts(callCluster, '.kibana');
180+
const results = await getVisualizationCounts(() => Promise.resolve(es), '.kibana');
181181

182182
expect(results).to.have.keys([
183183
'saved_overall',

0 commit comments

Comments
 (0)