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

[Painless Lab] Update server to use new es-js client #88704

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,24 @@ import { IKibanaResponse, KibanaResponseFactory } from 'kibana/server';
interface EsErrorHandlerParams {
error: ApiError;
response: KibanaResponseFactory;
handleCustomError?: () => IKibanaResponse<any>;
}

/*
* For errors returned by the new elasticsearch js client.
*/
export const handleEsError = ({ error, response }: EsErrorHandlerParams): IKibanaResponse => {
export const handleEsError = ({
error,
response,
handleCustomError,
}: EsErrorHandlerParams): IKibanaResponse => {
// error.name is slightly better in terms of performance, since all errors now have name property
if (error.name === 'ResponseError') {
// The consumer may sometimes want to provide a custom response
if (typeof handleCustomError === 'function') {
return handleCustomError();
}

const { statusCode, body } = error as ResponseError;
return response.customError({
statusCode,
Expand Down
23 changes: 12 additions & 11 deletions x-pack/plugins/painless_lab/server/routes/api/execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { schema } from '@kbn/config-schema';

import { API_BASE_PATH } from '../../../common/constants';
import { RouteDependencies } from '../../types';
import { isEsError } from '../../shared_imports';
import { handleEsError } from '../../shared_imports';

const bodySchema = schema.string();

Expand All @@ -23,23 +23,24 @@ export function registerExecuteRoute({ router, license }: RouteDependencies) {
const body = req.body;

try {
const callAsCurrentUser = ctx.core.elasticsearch.legacy.client.callAsCurrentUser;
const response = await callAsCurrentUser('scriptsPainlessExecute', {
const client = ctx.core.elasticsearch.client.asCurrentUser;
const response = await client.scriptsPainlessExecute({
body,
});

return res.ok({
body: response,
body: response.body,
});
} catch (e) {
if (isEsError(e)) {
// Assume invalid painless script was submitted
// Return 200 with error object
} catch (error) {
// Assume invalid painless script was submitted
// Return 200 with error object
const handleCustomError = () => {
return res.ok({
body: e.body,
body: error.body,
});
}
return res.internalError({ body: e });
};

return handleEsError({ error, response: res, handleCustomError });
}
})
);
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/painless_lab/server/shared_imports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
* you may not use this file except in compliance with the Elastic License.
*/

export { isEsError } from '../../../../src/plugins/es_ui_shared/server';
export { handleEsError } from '../../../../src/plugins/es_ui_shared/server';
1 change: 1 addition & 0 deletions x-pack/test/api_integration/apis/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,6 @@ export default function ({ loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./lists'));
loadTestFile(require.resolve('./upgrade_assistant'));
loadTestFile(require.resolve('./searchprofiler'));
loadTestFile(require.resolve('./painless_lab'));
});
}
13 changes: 13 additions & 0 deletions x-pack/test/api_integration/apis/painless_lab/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

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

export default function ({ loadTestFile }: FtrProviderContext) {
describe('Painless Lab', () => {
loadTestFile(require.resolve('./painless_lab'));
});
}
49 changes: 49 additions & 0 deletions x-pack/test/api_integration/apis/painless_lab/painless_lab.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';

const API_BASE_PATH = '/api/painless_lab';

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

describe('Painless Lab', function () {
describe('Execute', () => {
it('should execute a valid painless script', async () => {
const script =
'"{\\n \\"script\\": {\\n \\"source\\": \\"return true;\\",\\n \\"params\\": {\\n \\"string_parameter\\": \\"string value\\",\\n \\"number_parameter\\": 1.5,\\n \\"boolean_parameter\\": true\\n}\\n }\\n}"';

const { body } = await supertest
.post(`${API_BASE_PATH}/execute`)
.set('kbn-xsrf', 'xxx')
.set('Content-Type', 'application/json;charset=UTF-8')
.send(script)
.expect(200);

expect(body).to.eql({
result: 'true',
});
});

it('should return error response for invalid painless script', async () => {
const invalidScript =
'"{\\n \\"script\\": {\\n \\"source\\": \\"foobar\\",\\n \\"params\\": {\\n \\"string_parameter\\": \\"string value\\",\\n \\"number_parameter\\": 1.5,\\n \\"boolean_parameter\\": true\\n}\\n }\\n}"';

const { body } = await supertest
.post(`${API_BASE_PATH}/execute`)
.set('kbn-xsrf', 'xxx')
.set('Content-Type', 'application/json;charset=UTF-8')
.send(invalidScript)
.expect(200);

expect(body.error).to.not.be(undefined);
expect(body.error.reason).to.eql('compile error');
});
});
});
}