Skip to content

Commit

Permalink
[8.x] Check for indices before enabling get search profile in serverl…
Browse files Browse the repository at this point in the history
…ess (#201630) (#202972)

# Backport

This will backport the following commits from `main` to `8.x`:
- [Check for indices before enabling get search profile in serverless
(#201630)](#201630)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Sonia Sanz
Vivas","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-12-04T15:53:36Z","message":"Check
for indices before enabling get search profile in serverless
(#201630)\n\nCloses
[#195342](https://github.com/elastic/kibana/issues/195342)\r\n\r\n##
Summary\r\nIn serverless, the default query for the search profiler
fails if there\r\nis not indices. For avoiding this error, when there
are no indices\r\npresent, this PR disabled the \"Profile\" button and
add a tooltip\r\nexplaining why it is disabled.\r\n\r\n### New
strings\r\nThis is the tooltip for string verification
@kibana-docs\r\n[[Code](https://github.com/elastic/kibana/pull/201630/commits/5832a76683ad0cf55558655ca5981d623f344b72?diff=unified&w=0#diff-bf48cd9834b39a2a1634680225fc63c9a4ddb3ca881d9120f648006ad0277046R154-R1552?diff=unified&w=0#diff-bf48cd9834b39a2a1634680225fc63c9a4ddb3ca881d9120f648006ad0277046R155)]:\r\n<img
width=\"460\" alt=\"Screenshot 2024-11-25 at 16 15
08\"\r\nsrc=\"https://github.com/user-attachments/assets/a3395cfb-fc5e-4c22-9dd8-954a60fd1b5d\">\r\n\r\n###
How to test\r\n* Run Kibana in serverless\r\n* Go to Index Management
and verify you haven't indices (or delete them\r\nif you do have
indices).\r\n* Go to Dev Tools and click the Search Profiler tab. Verify
that the\r\nbutton is disabled and the tooltip displayed if you hover
over it.\r\n* Go back to Index Management and create one or more
indices.\r\n* Go back to Dev Tools > Search Profiler. Now the button
should be\r\nenabled and the profile should be created if you click
it.\r\n\r\n###
Demo\r\n\r\n\r\nhttps://github.com/user-attachments/assets/9bda072e-7897-4418-a906-14807e736c44\r\n\r\n\r\n###
Checklist\r\n\r\nCheck the PR satisfies following conditions.
\r\n\r\nReviewers should verify this PR satisfies this list as
well.\r\n\r\n- [ ] Any text added follows [EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[
]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas
added for features that require explanation or tutorials\r\n- [ ] [Unit
or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n- [ ] If a plugin
configuration key changed, check if it needs to be\r\nallowlisted in the
cloud and added to the
[docker\r\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\r\n-
[ ] This was checked for breaking HTTP API changes, and any
breaking\r\nchanges have been approved by the breaking-change committee.
The\r\n`release_note:breaking` label should be applied in these
situations.\r\n- [ ] [Flaky
Test\r\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1)
was\r\nused on any tests changed\r\n- [ ] The PR description includes
the appropriate Release Notes section,\r\nand the correct
`release_note:*` label is applied per
the\r\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\r\n\r\n---------\r\n\r\nCo-authored-by:
Elastic Machine
<[email protected]>","sha":"41bd2af9f142b97ab6a5deef2444330a8e93f7ed","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:Kibana
Management","release_note:skip","Feature:Search
Profiler","v9.0.0","backport:prev-minor"],"title":"Check for indices
before enabling get search profile in
serverless","number":201630,"url":"https://github.com/elastic/kibana/pull/201630","mergeCommit":{"message":"Check
for indices before enabling get search profile in serverless
(#201630)\n\nCloses
[#195342](https://github.com/elastic/kibana/issues/195342)\r\n\r\n##
Summary\r\nIn serverless, the default query for the search profiler
fails if there\r\nis not indices. For avoiding this error, when there
are no indices\r\npresent, this PR disabled the \"Profile\" button and
add a tooltip\r\nexplaining why it is disabled.\r\n\r\n### New
strings\r\nThis is the tooltip for string verification
@kibana-docs\r\n[[Code](https://github.com/elastic/kibana/pull/201630/commits/5832a76683ad0cf55558655ca5981d623f344b72?diff=unified&w=0#diff-bf48cd9834b39a2a1634680225fc63c9a4ddb3ca881d9120f648006ad0277046R154-R1552?diff=unified&w=0#diff-bf48cd9834b39a2a1634680225fc63c9a4ddb3ca881d9120f648006ad0277046R155)]:\r\n<img
width=\"460\" alt=\"Screenshot 2024-11-25 at 16 15
08\"\r\nsrc=\"https://github.com/user-attachments/assets/a3395cfb-fc5e-4c22-9dd8-954a60fd1b5d\">\r\n\r\n###
How to test\r\n* Run Kibana in serverless\r\n* Go to Index Management
and verify you haven't indices (or delete them\r\nif you do have
indices).\r\n* Go to Dev Tools and click the Search Profiler tab. Verify
that the\r\nbutton is disabled and the tooltip displayed if you hover
over it.\r\n* Go back to Index Management and create one or more
indices.\r\n* Go back to Dev Tools > Search Profiler. Now the button
should be\r\nenabled and the profile should be created if you click
it.\r\n\r\n###
Demo\r\n\r\n\r\nhttps://github.com/user-attachments/assets/9bda072e-7897-4418-a906-14807e736c44\r\n\r\n\r\n###
Checklist\r\n\r\nCheck the PR satisfies following conditions.
\r\n\r\nReviewers should verify this PR satisfies this list as
well.\r\n\r\n- [ ] Any text added follows [EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[
]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas
added for features that require explanation or tutorials\r\n- [ ] [Unit
or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n- [ ] If a plugin
configuration key changed, check if it needs to be\r\nallowlisted in the
cloud and added to the
[docker\r\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\r\n-
[ ] This was checked for breaking HTTP API changes, and any
breaking\r\nchanges have been approved by the breaking-change committee.
The\r\n`release_note:breaking` label should be applied in these
situations.\r\n- [ ] [Flaky
Test\r\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1)
was\r\nused on any tests changed\r\n- [ ] The PR description includes
the appropriate Release Notes section,\r\nand the correct
`release_note:*` label is applied per
the\r\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\r\n\r\n---------\r\n\r\nCo-authored-by:
Elastic Machine
<[email protected]>","sha":"41bd2af9f142b97ab6a5deef2444330a8e93f7ed"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/201630","number":201630,"mergeCommit":{"message":"Check
for indices before enabling get search profile in serverless
(#201630)\n\nCloses
[#195342](https://github.com/elastic/kibana/issues/195342)\r\n\r\n##
Summary\r\nIn serverless, the default query for the search profiler
fails if there\r\nis not indices. For avoiding this error, when there
are no indices\r\npresent, this PR disabled the \"Profile\" button and
add a tooltip\r\nexplaining why it is disabled.\r\n\r\n### New
strings\r\nThis is the tooltip for string verification
@kibana-docs\r\n[[Code](https://github.com/elastic/kibana/pull/201630/commits/5832a76683ad0cf55558655ca5981d623f344b72?diff=unified&w=0#diff-bf48cd9834b39a2a1634680225fc63c9a4ddb3ca881d9120f648006ad0277046R154-R1552?diff=unified&w=0#diff-bf48cd9834b39a2a1634680225fc63c9a4ddb3ca881d9120f648006ad0277046R155)]:\r\n<img
width=\"460\" alt=\"Screenshot 2024-11-25 at 16 15
08\"\r\nsrc=\"https://github.com/user-attachments/assets/a3395cfb-fc5e-4c22-9dd8-954a60fd1b5d\">\r\n\r\n###
How to test\r\n* Run Kibana in serverless\r\n* Go to Index Management
and verify you haven't indices (or delete them\r\nif you do have
indices).\r\n* Go to Dev Tools and click the Search Profiler tab. Verify
that the\r\nbutton is disabled and the tooltip displayed if you hover
over it.\r\n* Go back to Index Management and create one or more
indices.\r\n* Go back to Dev Tools > Search Profiler. Now the button
should be\r\nenabled and the profile should be created if you click
it.\r\n\r\n###
Demo\r\n\r\n\r\nhttps://github.com/user-attachments/assets/9bda072e-7897-4418-a906-14807e736c44\r\n\r\n\r\n###
Checklist\r\n\r\nCheck the PR satisfies following conditions.
\r\n\r\nReviewers should verify this PR satisfies this list as
well.\r\n\r\n- [ ] Any text added follows [EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[
]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas
added for features that require explanation or tutorials\r\n- [ ] [Unit
or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n- [ ] If a plugin
configuration key changed, check if it needs to be\r\nallowlisted in the
cloud and added to the
[docker\r\nlist](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)\r\n-
[ ] This was checked for breaking HTTP API changes, and any
breaking\r\nchanges have been approved by the breaking-change committee.
The\r\n`release_note:breaking` label should be applied in these
situations.\r\n- [ ] [Flaky
Test\r\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1)
was\r\nused on any tests changed\r\n- [ ] The PR description includes
the appropriate Release Notes section,\r\nand the correct
`release_note:*` label is applied per
the\r\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\r\n\r\n---------\r\n\r\nCo-authored-by:
Elastic Machine
<[email protected]>","sha":"41bd2af9f142b97ab6a5deef2444330a8e93f7ed"}}]}]
BACKPORT-->

Co-authored-by: Sonia Sanz Vivas <[email protected]>
  • Loading branch information
kibanamachine and SoniaSanzV authored Dec 4, 2024
1 parent 47e5d3c commit a692f65
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 14 deletions.
2 changes: 2 additions & 0 deletions x-pack/plugins/searchprofiler/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { LicenseType } from '@kbn/licensing-plugin/common/types';

const basicLicense: LicenseType = 'basic';

export const API_BASE_PATH = '/api/searchprofiler';

/** @internal */
export const PLUGIN = Object.freeze({
id: 'searchprofiler',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ import {
EuiFlexGroup,
EuiSpacer,
EuiFlexItem,
EuiToolTip,
} from '@elastic/eui';

import { decompressFromEncodedURIComponent } from 'lz-string';

import { useRequestProfile } from '../../hooks';
import { useHasIndices, useRequestProfile } from '../../hooks';
import { useAppContext } from '../../contexts/app_context';
import { useProfilerActionContext } from '../../contexts/profiler_context';
import { Editor, type EditorProps } from './editor';
Expand All @@ -46,6 +47,8 @@ export const ProfileQueryEditor = memo(() => {

const { getLicenseStatus, notifications, location } = useAppContext();

const { data: indicesData, isLoading, error: indicesDataError } = useHasIndices();

const queryParams = new URLSearchParams(location.search);
const indexName = queryParams.get('index');
const searchProfilerQueryURI = queryParams.get('load_from');
Expand Down Expand Up @@ -86,6 +89,32 @@ export const ProfileQueryEditor = memo(() => {
);
const licenseEnabled = getLicenseStatus().valid;

const hasIndices = isLoading || indicesDataError ? false : indicesData?.hasIndices;

const isDisabled = !licenseEnabled || !hasIndices;
const tooltipContent = !licenseEnabled
? i18n.translate('xpack.searchProfiler.formProfileButton.noLicenseTooltip', {
defaultMessage: 'You need an active license to use Search Profiler',
})
: i18n.translate('xpack.searchProfiler.formProfileButton.noIndicesTooltip', {
defaultMessage: 'You must have at least one index to use Search Profiler',
});

const button = (
<EuiButton
data-test-subj={isDisabled ? 'disabledProfileButton' : 'profileButton'}
fill
disabled={isDisabled}
onClick={!isDisabled ? handleProfileClick : undefined}
>
<EuiText>
{i18n.translate('xpack.searchProfiler.formProfileButtonLabel', {
defaultMessage: 'Profile',
})}
</EuiText>
</EuiButton>
);

return (
<EuiFlexGroup responsive={false} gutterSize="none" direction="column">
{/* Form */}
Expand Down Expand Up @@ -135,18 +164,13 @@ export const ProfileQueryEditor = memo(() => {
<EuiSpacer size="s" />
</EuiFlexItem>
<EuiFlexItem grow={5}>
<EuiButton
data-test-subj="profileButton"
fill
disabled={!licenseEnabled}
onClick={() => handleProfileClick()}
>
<EuiText>
{i18n.translate('xpack.searchProfiler.formProfileButtonLabel', {
defaultMessage: 'Profile',
})}
</EuiText>
</EuiButton>
{isDisabled ? (
<EuiToolTip position="top" content={tooltipContent}>
{button}
</EuiToolTip>
) : (
button
)}
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
*/

export { useRequestProfile } from './use_request_profile';
export { useHasIndices } from './use_has_indices';
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { useRequest } from '@kbn/es-ui-shared-plugin/public';
import { API_BASE_PATH } from '../../../common/constants';
import { useAppContext } from '../contexts/app_context';

interface ReturnValue {
hasIndices: boolean;
}

export const useHasIndices = () => {
const { http } = useAppContext();
return useRequest<ReturnValue>(http, {
path: `${API_BASE_PATH}/has_indices`,
method: 'get',
});
};
45 changes: 44 additions & 1 deletion x-pack/plugins/searchprofiler/server/routes/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
*/

import { schema } from '@kbn/config-schema';
import { API_BASE_PATH } from '../../common/constants';
import { RouteDependencies } from '../types';

export const register = ({ router, getLicenseStatus, log }: RouteDependencies) => {
router.post(
{
path: '/api/searchprofiler/profile',
path: `${API_BASE_PATH}/profile`,
validate: {
body: schema.object({
query: schema.object({}, { unknowns: 'allow' }),
Expand Down Expand Up @@ -56,6 +57,48 @@ export const register = ({ router, getLicenseStatus, log }: RouteDependencies) =
log.error(err);
const { statusCode, body: errorBody } = err;

return response.customError({
statusCode: statusCode || 500,
body: errorBody
? {
message: errorBody.error?.reason,
attributes: errorBody,
}
: err,
});
}
}
);
router.get(
{
path: `${API_BASE_PATH}/has_indices`,
validate: false,
},
async (ctx, _request, response) => {
const currentLicenseStatus = getLicenseStatus();
if (!currentLicenseStatus.valid) {
return response.forbidden({
body: {
message: currentLicenseStatus.message!,
},
});
}

try {
const client = (await ctx.core).elasticsearch.client.asCurrentUser;
const resp = await client.cat.indices({ format: 'json' });

const hasIndices = resp.length > 0;

return response.ok({
body: {
hasIndices,
},
});
} catch (err) {
log.error(err);
const { statusCode, body: errorBody } = err;

return response.customError({
statusCode: statusCode || 500,
body: errorBody
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ export default function ({ loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./enrich_policies'));
loadTestFile(require.resolve('./create_enrich_policy'));
loadTestFile(require.resolve('./data_enrichers'));
loadTestFile(require.resolve('./searchprofiler'));
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import expect from 'expect';
import { FtrProviderContext } from '../../../ftr_provider_context';

const API_BASE_PATH = '/api/searchprofiler';

export default function ({ getService }: FtrProviderContext) {
const supertest = getService('supertest');

describe('Searchprofiler', function () {
it('Can retrive has indices', async () => {
const { body } = await supertest.get(`${API_BASE_PATH}/has_indices`).expect(200);
expect(body).toStrictEqual({ hasIndices: true });
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
const PageObjects = getPageObjects(['svlCommonPage', 'common', 'searchProfiler']);
const retry = getService('retry');
const es = getService('es');
const browser = getService('browser');

describe('Search Profiler Editor', () => {
before(async () => {
Expand Down Expand Up @@ -81,6 +82,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
});

it('profiles a simple query', async () => {
await browser.refresh();
await PageObjects.searchProfiler.setIndexName(indexName);
await PageObjects.searchProfiler.setQuery(testQuery);

Expand Down

0 comments on commit a692f65

Please sign in to comment.