mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[ftr/savedObjects] add simple saved object api client to ftr s… (#45856)
* [ftr/savedObjects] add simple saved object api client to ftr services
* fix typo
* use consistent spacing
* fix types and TS-ify the rest of kibanaServer service
* expose server urls with better API
* tweak status api response types
* fix http body param name
* second arg to axios post is the post data
* use standardized error handling behavior
* Revert "use standardized error handling behavior"
This reverts commit 7e9a7f8dc5
.
* revert unnecessary changes
This commit is contained in:
parent
eed848ab2e
commit
fc186e57d5
5 changed files with 185 additions and 13 deletions
11
packages/kbn-test/types/ftr.d.ts
vendored
11
packages/kbn-test/types/ftr.d.ts
vendored
|
@ -20,6 +20,8 @@
|
|||
import { ToolingLog } from '@kbn/dev-utils';
|
||||
import { Config, Lifecycle } from '../src/functional_test_runner/lib';
|
||||
|
||||
export { Lifecycle, Config };
|
||||
|
||||
interface AsyncInstance<T> {
|
||||
/**
|
||||
* Services that are initialized async are not ready before the tests execute, so you might need
|
||||
|
@ -36,14 +38,17 @@ interface AsyncInstance<T> {
|
|||
*/
|
||||
type MaybeAsyncInstance<T> = T extends Promise<infer X> ? AsyncInstance<X> & X : T;
|
||||
|
||||
/**
|
||||
* Covert a Provider type to the instance type it provides
|
||||
*/
|
||||
export type ProvidedType<T extends (...args: any[]) => any> = MaybeAsyncInstance<ReturnType<T>>;
|
||||
|
||||
/**
|
||||
* Convert a map of providers to a map of the instance types they provide, also converting
|
||||
* promise types into the async instances that other providers will receive.
|
||||
*/
|
||||
type ProvidedTypeMap<T extends {}> = {
|
||||
[K in keyof T]: T[K] extends (...args: any[]) => any
|
||||
? MaybeAsyncInstance<ReturnType<T[K]>>
|
||||
: unknown;
|
||||
[K in keyof T]: T[K] extends (...args: any[]) => any ? ProvidedType<T[K]> : unknown;
|
||||
};
|
||||
|
||||
export interface GenericFtrProviderContext<
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
import { EsProvider } from './es';
|
||||
import { EsArchiverProvider } from './es_archiver';
|
||||
// @ts-ignore not TS yet
|
||||
import { KibanaServerProvider } from './kibana_server';
|
||||
import { RetryProvider } from './retry';
|
||||
|
||||
|
|
|
@ -18,4 +18,5 @@
|
|||
*/
|
||||
|
||||
export { KibanaServerProvider } from './kibana_server';
|
||||
// @ts-ignore
|
||||
export { extendEsArchiver } from './extend_es_archiver';
|
|
@ -17,23 +17,37 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { format as formatUrl } from 'url';
|
||||
import Url from 'url';
|
||||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
// @ts-ignore not ts yet
|
||||
import { KibanaServerStatus } from './status';
|
||||
// @ts-ignore not ts yet
|
||||
import { KibanaServerUiSettings } from './ui_settings';
|
||||
// @ts-ignore not ts yet
|
||||
import { KibanaServerVersion } from './version';
|
||||
import { KibanaServerSavedObjects } from './saved_objects';
|
||||
|
||||
export function KibanaServerProvider({ getService }) {
|
||||
export function KibanaServerProvider({ getService }: FtrProviderContext) {
|
||||
const log = getService('log');
|
||||
const config = getService('config');
|
||||
const lifecycle = getService('lifecycle');
|
||||
|
||||
return new class KibanaServer {
|
||||
constructor() {
|
||||
const url = formatUrl(config.get('servers.kibana'));
|
||||
this.status = new KibanaServerStatus(url);
|
||||
this.version = new KibanaServerVersion(this.status);
|
||||
this.uiSettings = new KibanaServerUiSettings(url, log, config.get('uiSettings.defaults'), lifecycle);
|
||||
const url = Url.format(config.get('servers.kibana'));
|
||||
|
||||
return new (class KibanaServer {
|
||||
public readonly status = new KibanaServerStatus(url);
|
||||
public readonly version = new KibanaServerVersion(this.status);
|
||||
public readonly savedObjects = new KibanaServerSavedObjects(url, log);
|
||||
public readonly uiSettings = new KibanaServerUiSettings(
|
||||
url,
|
||||
log,
|
||||
config.get('uiSettings.defaults'),
|
||||
lifecycle
|
||||
);
|
||||
|
||||
public resolveUrl(path = '/') {
|
||||
return Url.resolve(url, path);
|
||||
}
|
||||
};
|
||||
})();
|
||||
}
|
153
test/common/services/kibana_server/saved_objects.ts
Normal file
153
test/common/services/kibana_server/saved_objects.ts
Normal file
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* 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 Url from 'url';
|
||||
|
||||
import Axios, { AxiosRequestConfig } from 'axios';
|
||||
import { ToolingLog } from '@kbn/dev-utils';
|
||||
|
||||
const joinPath = (...components: Array<string | undefined>) =>
|
||||
`/${components
|
||||
.filter((s): s is string => !!s)
|
||||
.map(c => encodeURIComponent(c))
|
||||
.join('/')}`;
|
||||
|
||||
type MigrationVersion = Record<string, string>;
|
||||
|
||||
interface Reference {
|
||||
id: string;
|
||||
name: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
interface SavedObjectResponse<Attributes extends Record<string, any>> {
|
||||
attributes: Attributes;
|
||||
id: string;
|
||||
migrationVersion?: MigrationVersion;
|
||||
references: Reference[];
|
||||
type: string;
|
||||
updated_at?: string;
|
||||
version?: string;
|
||||
}
|
||||
|
||||
interface GetOptions {
|
||||
type: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
interface IndexOptions<Attributes> {
|
||||
type: string;
|
||||
attributes: Attributes;
|
||||
id?: string;
|
||||
overwrite?: boolean;
|
||||
migrationVersion?: MigrationVersion;
|
||||
references?: Reference[];
|
||||
}
|
||||
|
||||
interface UpdateOptions<Attributes> extends IndexOptions<Attributes> {
|
||||
id: string;
|
||||
}
|
||||
|
||||
export class KibanaServerSavedObjects {
|
||||
private readonly x = Axios.create({
|
||||
baseURL: Url.resolve(this.url, '/api/saved_objects/'),
|
||||
headers: {
|
||||
'kbn-xsrf': 'KibanaServerSavedObjects',
|
||||
},
|
||||
});
|
||||
|
||||
constructor(private readonly url: string, private readonly log: ToolingLog) {}
|
||||
|
||||
/**
|
||||
* Get an object
|
||||
*/
|
||||
public async get<Attributes extends Record<string, any>>(options: GetOptions) {
|
||||
this.log.debug('Gettings saved object: %j', options);
|
||||
|
||||
return await this.request<SavedObjectResponse<Attributes>>('get saved object', {
|
||||
url: joinPath(options.type, options.id),
|
||||
method: 'GET',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a saved object
|
||||
*/
|
||||
public async create<Attributes extends Record<string, any>>(options: IndexOptions<Attributes>) {
|
||||
this.log.debug('Creating saved object: %j', options);
|
||||
|
||||
return await this.request<SavedObjectResponse<Attributes>>('update saved object', {
|
||||
url: joinPath(options.type, options.id),
|
||||
params: {
|
||||
overwrite: options.overwrite,
|
||||
},
|
||||
method: 'POST',
|
||||
data: {
|
||||
attributes: options.attributes,
|
||||
migrationVersion: options.migrationVersion,
|
||||
references: options.references,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a saved object
|
||||
*/
|
||||
public async update<Attributes extends Record<string, any>>(options: UpdateOptions<Attributes>) {
|
||||
this.log.debug('Updating saved object: %j', options);
|
||||
|
||||
return await this.request<SavedObjectResponse<Attributes>>('update saved object', {
|
||||
url: joinPath(options.type, options.id),
|
||||
params: {
|
||||
overwrite: options.overwrite,
|
||||
},
|
||||
method: 'PUT',
|
||||
data: {
|
||||
attributes: options.attributes,
|
||||
migrationVersion: options.migrationVersion,
|
||||
references: options.references,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an object
|
||||
*/
|
||||
public async delete(options: GetOptions) {
|
||||
this.log.debug('Deleting saved object %s/%s', options);
|
||||
|
||||
return await this.request('delete saved object', {
|
||||
url: joinPath(options.type, options.id),
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
|
||||
private async request<T>(desc: string, options: AxiosRequestConfig) {
|
||||
try {
|
||||
const resp = await this.x.request<T>(options);
|
||||
return resp.data;
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
throw new Error(`Failed to ${desc}:\n${JSON.stringify(error.response.data, null, 2)}`);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue