Skip to content

Commit

Permalink
move ui settings routes to NP
Browse files Browse the repository at this point in the history
  • Loading branch information
mshustov committed Oct 16, 2019
1 parent e086282 commit 27af6eb
Show file tree
Hide file tree
Showing 21 changed files with 249 additions and 157 deletions.
6 changes: 5 additions & 1 deletion src/core/server/http/router/response_adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,11 @@ export class HapiResponseAdapter {
});

error.output.payload.message = getErrorMessage(payload);
error.output.payload.attributes = getErrorAttributes(payload);

const attributes = getErrorAttributes(payload);
if (attributes) {
error.output.payload.attributes = attributes;
}

const headers = kibanaResponse.options.headers;
if (headers) {
Expand Down
61 changes: 61 additions & 0 deletions src/core/server/ui_settings/routes/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { schema } from '@kbn/config-schema';

import { IRouter } from '../../http';
import { SavedObjectsErrorHelpers } from '../../saved_objects';
import { CannotOverrideError } from '../ui_settings_errors';

const validate = {
params: schema.object({
key: schema.string(),
}),
};

export function registerDeleteRoute(router: IRouter) {
router.delete(
{ path: '/api/kibana/settings/{key}', validate },
async (context, request, response) => {
try {
const uiSettingsClient = context.core.uiSettings.client;

await uiSettingsClient.remove(request.params.key);

return response.ok({
body: {
settings: await uiSettingsClient.getUserProvided(),
},
});
} catch (error) {
if (SavedObjectsErrorHelpers.isSavedObjectsClientError(error)) {
return response.customError({
body: error,
statusCode: error.output.statusCode,
});
}

if (error instanceof CannotOverrideError) {
return response.badRequest({ body: error });
}

throw error;
}
}
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,30 @@
* specific language governing permissions and limitations
* under the License.
*/
import { Legacy } from 'kibana';
import { IRouter } from '../../http';
import { SavedObjectsErrorHelpers } from '../../saved_objects';

async function handleRequest(request: Legacy.Request) {
const { key } = request.params;
const uiSettings = request.getUiSettingsService();
export function registerGetRoute(router: IRouter) {
router.get(
{ path: '/api/kibana/settings', validate: false },
async (context, request, response) => {
try {
const uiSettingsClient = context.core.uiSettings.client;
return response.ok({
body: {
settings: await uiSettingsClient.getUserProvided(),
},
});
} catch (error) {
if (SavedObjectsErrorHelpers.isSavedObjectsClientError(error)) {
return response.customError({
body: error,
statusCode: error.output.statusCode,
});
}

await uiSettings.remove(key);
return {
settings: await uiSettings.getUserProvided(),
};
throw error;
}
}
);
}

export const deleteRoute = {
path: '/api/kibana/settings/{key}',
method: 'DELETE',
handler: async (request: Legacy.Request) => {
return await handleRequest(request);
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,16 @@
* specific language governing permissions and limitations
* under the License.
*/
import { Legacy } from 'kibana';
import { IRouter } from 'src/core/server';

async function handleRequest(request: Legacy.Request) {
const uiSettings = request.getUiSettingsService();
return {
settings: await uiSettings.getUserProvided(),
};
}
import { registerDeleteRoute } from './delete';
import { registerGetRoute } from './get';
import { registerSetManyRoute } from './set_many';
import { registerSetRoute } from './set';

export const getRoute = {
path: '/api/kibana/settings',
method: 'GET',
handler(request: Legacy.Request) {
return handleRequest(request);
},
};
export function registerRoutes(router: IRouter) {
registerGetRoute(router);
registerDeleteRoute(router);
registerSetRoute(router);
registerSetManyRoute(router);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import { UnwrapPromise } from '@kbn/utility-types';
import { SavedObjectsClientContract, IUiSettingsClient } from 'src/core/server';

import KbnServer from '../../../../../server/kbn_server';
import KbnServer from '../../../../../../legacy/server/kbn_server';
import { createTestServers } from '../../../../../../test_utils/kbn_server';
import { CallCluster } from '../../../../../../legacy/core_plugins/elasticsearch';

Expand Down
67 changes: 67 additions & 0 deletions src/core/server/ui_settings/routes/set.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { schema } from '@kbn/config-schema';

import { IRouter } from '../../http';
import { SavedObjectsErrorHelpers } from '../../saved_objects';
import { CannotOverrideError } from '../ui_settings_errors';

const validate = {
params: schema.object({
key: schema.string(),
}),
body: schema.object({
value: schema.any(),
}),
};

export function registerSetRoute(router: IRouter) {
router.post(
{ path: '/api/kibana/settings/{key}', validate },
async (context, request, response) => {
try {
const uiSettingsClient = context.core.uiSettings.client;

const { key } = request.params;
const { value } = request.body;

await uiSettingsClient.set(key, value);

return response.ok({
body: {
settings: await uiSettingsClient.getUserProvided(),
},
});
} catch (error) {
if (SavedObjectsErrorHelpers.isSavedObjectsClientError(error)) {
return response.customError({
body: error,
statusCode: error.output.statusCode,
});
}

if (error instanceof CannotOverrideError) {
return response.badRequest({ body: error });
}

throw error;
}
}
);
}
60 changes: 60 additions & 0 deletions src/core/server/ui_settings/routes/set_many.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { schema } from '@kbn/config-schema';

import { IRouter } from '../../http';
import { SavedObjectsErrorHelpers } from '../../saved_objects';
import { CannotOverrideError } from '../ui_settings_errors';

const validate = {
body: schema.object({
changes: schema.object({}, { allowUnknowns: true }),
}),
};

export function registerSetManyRoute(router: IRouter) {
router.post({ path: '/api/kibana/settings', validate }, async (context, request, response) => {
try {
const uiSettingsClient = context.core.uiSettings.client;

const { changes } = request.body;

await uiSettingsClient.setMany(changes);

return response.ok({
body: {
settings: await uiSettingsClient.getUserProvided(),
},
});
} catch (error) {
if (SavedObjectsErrorHelpers.isSavedObjectsClientError(error)) {
return response.customError({
body: error,
statusCode: error.output.statusCode,
});
}

if (error instanceof CannotOverrideError) {
return response.badRequest({ body: error });
}

throw error;
}
});
}
6 changes: 3 additions & 3 deletions src/core/server/ui_settings/ui_settings_client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import sinon from 'sinon';
import { loggingServiceMock } from '../logging/logging_service.mock';

import { UiSettingsClient } from './ui_settings_client';
import { CannotOverrideError } from './ui_settings_errors';
import * as createOrUpgradeSavedConfigNS from './create_or_upgrade_saved_config/create_or_upgrade_saved_config';
import { createObjectsClientStub, savedObjectsClientErrors } from './create_objects_client_stub';

Expand Down Expand Up @@ -551,15 +552,14 @@ describe('ui settings', () => {
const { uiSettings } = setup();
expect(uiSettings.assertUpdateAllowed('foo')).to.be(undefined);
});
it('throws 400 Boom error when keys is overridden', () => {
it('throws CannotOverrideError when key is overridden', () => {
const { uiSettings } = setup({ overrides: { foo: true } });
expect(() => uiSettings.assertUpdateAllowed('foo')).to.throwError(error => {
expect(error).to.be.a(CannotOverrideError);
expect(error).to.have.property(
'message',
'Unable to update "foo" because it is overridden'
);
expect(error).to.have.property('isBoom', true);
expect(error.output).to.have.property('statusCode', 400);
});
});
});
Expand Down
4 changes: 2 additions & 2 deletions src/core/server/ui_settings/ui_settings_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
* under the License.
*/
import { defaultsDeep } from 'lodash';
import Boom from 'boom';

import { SavedObjectsClientContract, SavedObjectAttribute } from '../saved_objects/types';
import { Logger } from '../logging';
import { createOrUpgradeSavedConfig } from './create_or_upgrade_saved_config';
import { IUiSettingsClient, UiSettingsParams } from './types';
import { CannotOverrideError } from './ui_settings_errors';

export interface UiSettingsServiceOptions {
type: string;
Expand Down Expand Up @@ -149,7 +149,7 @@ export class UiSettingsClient implements IUiSettingsClient {
// NOTE: should be private method
assertUpdateAllowed(key: string) {
if (this.isOverridden(key)) {
throw Boom.badRequest(`Unable to update "${key}" because it is overridden`);
throw new CannotOverrideError(`Unable to update "${key}" because it is overridden`);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@
* under the License.
*/

export { deleteRoute } from './delete';
export { getRoute } from './get';
export { setManyRoute } from './set_many';
export { setRoute } from './set';
export class CannotOverrideError extends Error {
public cause?: Error;

constructor(message: string, cause?: Error) {
super(message);
this.cause = cause;

// Set the prototype explicitly, see:
// https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
Object.setPrototypeOf(this, CannotOverrideError.prototype);
}
}
3 changes: 3 additions & 0 deletions src/core/server/ui_settings/ui_settings_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import { UiSettingsClient } from './ui_settings_client';
import { InternalUiSettingsServiceSetup, UiSettingsParams } from './types';
import { mapToObject } from '../../utils/';

import { registerRoutes } from './routes';

interface SetupDeps {
http: InternalHttpServiceSetup;
}
Expand All @@ -46,6 +48,7 @@ export class UiSettingsService implements CoreService<InternalUiSettingsServiceS
}

public async setup(deps: SetupDeps): Promise<InternalUiSettingsServiceSetup> {
registerRoutes(deps.http.createRouter(''));
this.log.debug('Setting up ui settings service');
const overrides = await this.getOverrides(deps);
const { version, buildNum } = this.coreContext.env.packageInfo;
Expand Down
Loading

0 comments on commit 27af6eb

Please sign in to comment.