Deprecate es API exposed from setup contract (#67596)

* move elasticsearch client under legacy namespace

* update mocks and tests

* update platform code

* update legacy code

* update plugins using elasticsearch setup API

* update request handler context

* update docs

* rename remaining places

* address comments

* fix merge conflict error
This commit is contained in:
Mikhail Shustov 2020-06-01 17:16:44 +03:00 committed by GitHub
parent afbbafb0cf
commit 53b95424fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
50 changed files with 292 additions and 395 deletions

View file

@ -1,27 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [ElasticsearchServiceSetup](./kibana-plugin-core-server.elasticsearchservicesetup.md) &gt; [adminClient](./kibana-plugin-core-server.elasticsearchservicesetup.adminclient.md)
## ElasticsearchServiceSetup.adminClient property
> Warning: This API is now obsolete.
>
> Use [ElasticsearchServiceStart.legacy.client](./kibana-plugin-core-server.elasticsearchservicestart.legacy.md) instead.
>
> A client for the `admin` cluster. All Elasticsearch config value changes are processed under the hood. See [IClusterClient](./kibana-plugin-core-server.iclusterclient.md)<!-- -->.
>
<b>Signature:</b>
```typescript
readonly adminClient: IClusterClient;
```
## Example
```js
const client = core.elasticsearch.adminClient;
```

View file

@ -1,28 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [ElasticsearchServiceSetup](./kibana-plugin-core-server.elasticsearchservicesetup.md) &gt; [createClient](./kibana-plugin-core-server.elasticsearchservicesetup.createclient.md)
## ElasticsearchServiceSetup.createClient property
> Warning: This API is now obsolete.
>
> Use [ElasticsearchServiceStart.legacy.createClient](./kibana-plugin-core-server.elasticsearchservicestart.legacy.md) instead.
>
> Create application specific Elasticsearch cluster API client with customized config. See [IClusterClient](./kibana-plugin-core-server.iclusterclient.md)<!-- -->.
>
<b>Signature:</b>
```typescript
readonly createClient: (type: string, clientConfig?: Partial<ElasticsearchClientConfig>) => ICustomClusterClient;
```
## Example
```js
const client = elasticsearch.createCluster('my-app-name', config);
const data = await client.callAsInternalUser();
```

View file

@ -1,27 +0,0 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [ElasticsearchServiceSetup](./kibana-plugin-core-server.elasticsearchservicesetup.md) &gt; [dataClient](./kibana-plugin-core-server.elasticsearchservicesetup.dataclient.md)
## ElasticsearchServiceSetup.dataClient property
> Warning: This API is now obsolete.
>
> Use [ElasticsearchServiceStart.legacy.client](./kibana-plugin-core-server.elasticsearchservicestart.legacy.md) instead.
>
> A client for the `data` cluster. All Elasticsearch config value changes are processed under the hood. See [IClusterClient](./kibana-plugin-core-server.iclusterclient.md)<!-- -->.
>
<b>Signature:</b>
```typescript
readonly dataClient: IClusterClient;
```
## Example
```js
const client = core.elasticsearch.dataClient;
```

View file

@ -0,0 +1,19 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [ElasticsearchServiceSetup](./kibana-plugin-core-server.elasticsearchservicesetup.md) &gt; [legacy](./kibana-plugin-core-server.elasticsearchservicesetup.legacy.md)
## ElasticsearchServiceSetup.legacy property
> Warning: This API is now obsolete.
>
> Use [ElasticsearchServiceStart.legacy](./kibana-plugin-core-server.elasticsearchservicestart.legacy.md) instead.
>
<b>Signature:</b>
```typescript
legacy: {
readonly createClient: (type: string, clientConfig?: Partial<ElasticsearchClientConfig>) => ICustomClusterClient;
readonly client: IClusterClient;
};
```

View file

@ -15,7 +15,5 @@ export interface ElasticsearchServiceSetup
| Property | Type | Description |
| --- | --- | --- |
| [adminClient](./kibana-plugin-core-server.elasticsearchservicesetup.adminclient.md) | <code>IClusterClient</code> | |
| [createClient](./kibana-plugin-core-server.elasticsearchservicesetup.createclient.md) | <code>(type: string, clientConfig?: Partial&lt;ElasticsearchClientConfig&gt;) =&gt; ICustomClusterClient</code> | |
| [dataClient](./kibana-plugin-core-server.elasticsearchservicesetup.dataclient.md) | <code>IClusterClient</code> | |
| [legacy](./kibana-plugin-core-server.elasticsearchservicesetup.legacy.md) | <code>{</code><br/><code> readonly createClient: (type: string, clientConfig?: Partial&lt;ElasticsearchClientConfig&gt;) =&gt; ICustomClusterClient;</code><br/><code> readonly client: IClusterClient;</code><br/><code> }</code> | |

View file

@ -4,6 +4,11 @@
## ElasticsearchServiceStart.legacy property
> Warning: This API is now obsolete.
>
> Provided for the backward compatibility. Switch to the new elasticsearch client as soon as https://github.com/elastic/kibana/issues/35508 done.
>
<b>Signature:</b>
```typescript

View file

@ -125,7 +125,7 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [PluginConfigDescriptor](./kibana-plugin-core-server.pluginconfigdescriptor.md) | Describes a plugin configuration properties. |
| [PluginInitializerContext](./kibana-plugin-core-server.plugininitializercontext.md) | Context that's available to plugins during initialization stage. |
| [PluginManifest](./kibana-plugin-core-server.pluginmanifest.md) | Describes the set of required and optional properties plugin can define in its mandatory JSON manifest file. |
| [RequestHandlerContext](./kibana-plugin-core-server.requesthandlercontext.md) | Plugin specific context passed to a route handler.<!-- -->Provides the following clients and services: - [savedObjects.client](./kibana-plugin-core-server.savedobjectsclient.md) - Saved Objects client which uses the credentials of the incoming request - [savedObjects.typeRegistry](./kibana-plugin-core-server.isavedobjecttyperegistry.md) - Type registry containing all the registered types. - [elasticsearch.dataClient](./kibana-plugin-core-server.scopedclusterclient.md) - Elasticsearch data client which uses the credentials of the incoming request - [elasticsearch.adminClient](./kibana-plugin-core-server.scopedclusterclient.md) - Elasticsearch admin client which uses the credentials of the incoming request - [uiSettings.client](./kibana-plugin-core-server.iuisettingsclient.md) - uiSettings client which uses the credentials of the incoming request |
| [RequestHandlerContext](./kibana-plugin-core-server.requesthandlercontext.md) | Plugin specific context passed to a route handler.<!-- -->Provides the following clients and services: - [savedObjects.client](./kibana-plugin-core-server.savedobjectsclient.md) - Saved Objects client which uses the credentials of the incoming request - [savedObjects.typeRegistry](./kibana-plugin-core-server.isavedobjecttyperegistry.md) - Type registry containing all the registered types. - [elasticsearch.legacy.client](./kibana-plugin-core-server.scopedclusterclient.md) - Elasticsearch data client which uses the credentials of the incoming request - [uiSettings.client](./kibana-plugin-core-server.iuisettingsclient.md) - uiSettings client which uses the credentials of the incoming request |
| [RouteConfig](./kibana-plugin-core-server.routeconfig.md) | Route specific configuration. |
| [RouteConfigOptions](./kibana-plugin-core-server.routeconfigoptions.md) | Additional route options. |
| [RouteConfigOptionsBody](./kibana-plugin-core-server.routeconfigoptionsbody.md) | Additional body options for a route |

View file

@ -6,7 +6,7 @@
Plugin specific context passed to a route handler.
Provides the following clients and services: - [savedObjects.client](./kibana-plugin-core-server.savedobjectsclient.md) - Saved Objects client which uses the credentials of the incoming request - [savedObjects.typeRegistry](./kibana-plugin-core-server.isavedobjecttyperegistry.md) - Type registry containing all the registered types. - [elasticsearch.dataClient](./kibana-plugin-core-server.scopedclusterclient.md) - Elasticsearch data client which uses the credentials of the incoming request - [elasticsearch.adminClient](./kibana-plugin-core-server.scopedclusterclient.md) - Elasticsearch admin client which uses the credentials of the incoming request - [uiSettings.client](./kibana-plugin-core-server.iuisettingsclient.md) - uiSettings client which uses the credentials of the incoming request
Provides the following clients and services: - [savedObjects.client](./kibana-plugin-core-server.savedobjectsclient.md) - Saved Objects client which uses the credentials of the incoming request - [savedObjects.typeRegistry](./kibana-plugin-core-server.isavedobjecttyperegistry.md) - Type registry containing all the registered types. - [elasticsearch.legacy.client](./kibana-plugin-core-server.scopedclusterclient.md) - Elasticsearch data client which uses the credentials of the incoming request - [uiSettings.client](./kibana-plugin-core-server.iuisettingsclient.md) - uiSettings client which uses the credentials of the incoming request
<b>Signature:</b>

View file

@ -23,12 +23,7 @@ import { IClusterClient, ICustomClusterClient } from './cluster_client';
import { IScopedClusterClient } from './scoped_cluster_client';
import { ElasticsearchConfig } from './elasticsearch_config';
import { ElasticsearchService } from './elasticsearch_service';
import {
InternalElasticsearchServiceSetup,
ElasticsearchServiceSetup,
ElasticsearchServiceStart,
ElasticsearchStatusMeta,
} from './types';
import { InternalElasticsearchServiceSetup, ElasticsearchStatusMeta } from './types';
import { NodesVersionCompatibility } from './version_check/ensure_es_version';
import { ServiceStatus, ServiceStatusLevels } from '../status';
@ -51,32 +46,26 @@ function createClusterClientMock() {
return client;
}
type MockedElasticSearchServiceSetup = jest.Mocked<
ElasticsearchServiceSetup & {
adminClient: jest.Mocked<IClusterClient>;
dataClient: jest.Mocked<IClusterClient>;
}
>;
interface MockedElasticSearchServiceSetup {
legacy: {
createClient: jest.Mock<ICustomClusterClient, any>;
client: jest.Mocked<IClusterClient>;
};
}
const createSetupContractMock = () => {
const setupContract: MockedElasticSearchServiceSetup = {
createClient: jest.fn(),
adminClient: createClusterClientMock(),
dataClient: createClusterClientMock(),
legacy: {
createClient: jest.fn(),
client: createClusterClientMock(),
},
};
setupContract.createClient.mockReturnValue(createCustomClusterClientMock());
setupContract.adminClient.asScoped.mockReturnValue(createScopedClusterClientMock());
setupContract.dataClient.asScoped.mockReturnValue(createScopedClusterClientMock());
setupContract.legacy.createClient.mockReturnValue(createCustomClusterClientMock());
setupContract.legacy.client.asScoped.mockReturnValue(createScopedClusterClientMock());
return setupContract;
};
type MockedElasticSearchServiceStart = {
legacy: jest.Mocked<ElasticsearchServiceStart['legacy']>;
} & {
legacy: {
client: jest.Mocked<IClusterClient>;
};
};
type MockedElasticSearchServiceStart = MockedElasticSearchServiceSetup;
const createStartContractMock = () => {
const startContract: MockedElasticSearchServiceStart = {
@ -92,13 +81,11 @@ const createStartContractMock = () => {
type MockedInternalElasticSearchServiceSetup = jest.Mocked<
InternalElasticsearchServiceSetup & {
adminClient: jest.Mocked<IClusterClient>;
dataClient: jest.Mocked<IClusterClient>;
legacy: { client: jest.Mocked<IClusterClient> };
}
>;
const createInternalSetupContractMock = () => {
const setupContract: MockedInternalElasticSearchServiceSetup = {
...createSetupContractMock(),
esNodesCompatibility$: new BehaviorSubject<NodesVersionCompatibility>({
isCompatible: true,
incompatibleNodes: [],
@ -111,10 +98,10 @@ const createInternalSetupContractMock = () => {
}),
legacy: {
config$: new BehaviorSubject({} as ElasticsearchConfig),
...createSetupContractMock().legacy,
},
};
setupContract.adminClient.asScoped.mockReturnValue(createScopedClusterClientMock());
setupContract.dataClient.asScoped.mockReturnValue(createScopedClusterClientMock());
setupContract.legacy.client.asScoped.mockReturnValue(createScopedClusterClientMock());
return setupContract;
};

View file

@ -74,25 +74,16 @@ describe('#setup', () => {
);
});
it('returns data and admin client as a part of the contract', async () => {
const mockAdminClusterClientInstance = elasticsearchServiceMock.createClusterClient();
const mockDataClusterClientInstance = elasticsearchServiceMock.createClusterClient();
MockClusterClient.mockImplementationOnce(
() => mockAdminClusterClientInstance
).mockImplementationOnce(() => mockDataClusterClientInstance);
it('returns elasticsearch client as a part of the contract', async () => {
const mockClusterClientInstance = elasticsearchServiceMock.createClusterClient();
MockClusterClient.mockImplementationOnce(() => mockClusterClientInstance);
const setupContract = await elasticsearchService.setup(deps);
const client = setupContract.legacy.client;
const adminClient = setupContract.adminClient;
const dataClient = setupContract.dataClient;
expect(mockAdminClusterClientInstance.callAsInternalUser).toHaveBeenCalledTimes(0);
await adminClient.callAsInternalUser('any');
expect(mockAdminClusterClientInstance.callAsInternalUser).toHaveBeenCalledTimes(1);
expect(mockDataClusterClientInstance.callAsInternalUser).toHaveBeenCalledTimes(0);
await dataClient.callAsInternalUser('any');
expect(mockDataClusterClientInstance.callAsInternalUser).toHaveBeenCalledTimes(1);
expect(mockClusterClientInstance.callAsInternalUser).toHaveBeenCalledTimes(0);
await client.callAsInternalUser('any');
expect(mockClusterClientInstance.callAsInternalUser).toHaveBeenCalledTimes(1);
});
describe('#createClient', () => {
@ -103,7 +94,7 @@ describe('#setup', () => {
MockClusterClient.mockImplementation(() => mockClusterClientInstance);
const customConfig = { logQueries: true };
const clusterClient = setupContract.createClient('some-custom-type', customConfig);
const clusterClient = setupContract.legacy.createClient('some-custom-type', customConfig);
expect(clusterClient).toBe(mockClusterClientInstance);
@ -124,7 +115,7 @@ describe('#setup', () => {
logQueries: true,
ssl: { certificate: 'certificate-value' },
};
setupContract.createClient('some-custom-type', customConfig);
setupContract.legacy.createClient('some-custom-type', customConfig);
const config = MockClusterClient.mock.calls[0][0];
expect(config).toMatchInlineSnapshot(`
@ -149,7 +140,7 @@ describe('#setup', () => {
// reset all mocks called during setup phase
MockClusterClient.mockClear();
setupContract.createClient('another-type');
setupContract.legacy.createClient('another-type');
const config = MockClusterClient.mock.calls[0][0];
expect(config).toMatchInlineSnapshot(`
@ -195,7 +186,7 @@ describe('#setup', () => {
logQueries: true,
ssl: { certificate: 'certificate-value' },
};
setupContract.createClient('some-custom-type', customConfig);
setupContract.legacy.createClient('some-custom-type', customConfig);
const config = MockClusterClient.mock.calls[0][0];
expect(config).toMatchInlineSnapshot(`
@ -218,40 +209,34 @@ describe('#setup', () => {
});
it('esNodeVersionCompatibility$ only starts polling when subscribed to', async (done) => {
const mockAdminClusterClientInstance = elasticsearchServiceMock.createClusterClient();
const mockDataClusterClientInstance = elasticsearchServiceMock.createClusterClient();
MockClusterClient.mockImplementationOnce(
() => mockAdminClusterClientInstance
).mockImplementationOnce(() => mockDataClusterClientInstance);
const clusterClientInstance = elasticsearchServiceMock.createClusterClient();
MockClusterClient.mockImplementationOnce(() => clusterClientInstance);
mockAdminClusterClientInstance.callAsInternalUser.mockRejectedValue(new Error());
clusterClientInstance.callAsInternalUser.mockRejectedValue(new Error());
const setupContract = await elasticsearchService.setup(deps);
await delay(10);
expect(mockAdminClusterClientInstance.callAsInternalUser).toHaveBeenCalledTimes(0);
expect(clusterClientInstance.callAsInternalUser).toHaveBeenCalledTimes(0);
setupContract.esNodesCompatibility$.subscribe(() => {
expect(mockAdminClusterClientInstance.callAsInternalUser).toHaveBeenCalledTimes(1);
expect(clusterClientInstance.callAsInternalUser).toHaveBeenCalledTimes(1);
done();
});
});
it('esNodeVersionCompatibility$ stops polling when unsubscribed from', async (done) => {
const mockAdminClusterClientInstance = elasticsearchServiceMock.createClusterClient();
const mockDataClusterClientInstance = elasticsearchServiceMock.createClusterClient();
MockClusterClient.mockImplementationOnce(
() => mockAdminClusterClientInstance
).mockImplementationOnce(() => mockDataClusterClientInstance);
const mockClusterClientInstance = elasticsearchServiceMock.createClusterClient();
MockClusterClient.mockImplementationOnce(() => mockClusterClientInstance);
mockAdminClusterClientInstance.callAsInternalUser.mockRejectedValue(new Error());
mockClusterClientInstance.callAsInternalUser.mockRejectedValue(new Error());
const setupContract = await elasticsearchService.setup(deps);
expect(mockAdminClusterClientInstance.callAsInternalUser).toHaveBeenCalledTimes(0);
expect(mockClusterClientInstance.callAsInternalUser).toHaveBeenCalledTimes(0);
const sub = setupContract.esNodesCompatibility$.subscribe(async () => {
sub.unsubscribe();
await delay(100);
expect(mockAdminClusterClientInstance.callAsInternalUser).toHaveBeenCalledTimes(1);
expect(mockClusterClientInstance.callAsInternalUser).toHaveBeenCalledTimes(1);
done();
});
});
@ -259,38 +244,31 @@ describe('#setup', () => {
describe('#stop', () => {
it('stops both admin and data clients', async () => {
const mockAdminClusterClientInstance = { close: jest.fn() };
const mockDataClusterClientInstance = { close: jest.fn() };
MockClusterClient.mockImplementationOnce(
() => mockAdminClusterClientInstance
).mockImplementationOnce(() => mockDataClusterClientInstance);
const mockClusterClientInstance = { close: jest.fn() };
MockClusterClient.mockImplementationOnce(() => mockClusterClientInstance);
await elasticsearchService.setup(deps);
await elasticsearchService.stop();
expect(mockAdminClusterClientInstance.close).toHaveBeenCalledTimes(1);
expect(mockDataClusterClientInstance.close).toHaveBeenCalledTimes(1);
expect(mockClusterClientInstance.close).toHaveBeenCalledTimes(1);
});
it('stops pollEsNodeVersions even if there are active subscriptions', async (done) => {
expect.assertions(2);
const mockAdminClusterClientInstance = elasticsearchServiceMock.createCustomClusterClient();
const mockDataClusterClientInstance = elasticsearchServiceMock.createCustomClusterClient();
const mockClusterClientInstance = elasticsearchServiceMock.createCustomClusterClient();
MockClusterClient.mockImplementationOnce(
() => mockAdminClusterClientInstance
).mockImplementationOnce(() => mockDataClusterClientInstance);
MockClusterClient.mockImplementationOnce(() => mockClusterClientInstance);
mockAdminClusterClientInstance.callAsInternalUser.mockRejectedValue(new Error());
mockClusterClientInstance.callAsInternalUser.mockRejectedValue(new Error());
const setupContract = await elasticsearchService.setup(deps);
setupContract.esNodesCompatibility$.subscribe(async () => {
expect(mockAdminClusterClientInstance.callAsInternalUser).toHaveBeenCalledTimes(1);
expect(mockClusterClientInstance.callAsInternalUser).toHaveBeenCalledTimes(1);
await elasticsearchService.stop();
await delay(100);
expect(mockAdminClusterClientInstance.callAsInternalUser).toHaveBeenCalledTimes(1);
expect(mockClusterClientInstance.callAsInternalUser).toHaveBeenCalledTimes(1);
done();
});
});

View file

@ -50,8 +50,7 @@ import { calculateStatus$ } from './status';
/** @internal */
interface CoreClusterClients {
config: ElasticsearchConfig;
adminClient: ClusterClient;
dataClient: ClusterClient;
client: ClusterClient;
}
interface SetupDeps {
@ -70,7 +69,7 @@ export class ElasticsearchService
type: string,
clientConfig?: Partial<ElasticsearchClientConfig>
) => ICustomClusterClient;
private adminClient?: IClusterClient;
private client?: IClusterClient;
constructor(private readonly coreContext: CoreContext) {
this.kibanaVersion = coreContext.env.packageInfo.version;
@ -95,21 +94,19 @@ export class ElasticsearchService
switchMap(
(config) =>
new Observable<CoreClusterClients>((subscriber) => {
this.log.debug(`Creating elasticsearch clients`);
this.log.debug('Creating elasticsearch client');
const coreClients = {
config,
adminClient: this.createClusterClient('admin', config),
dataClient: this.createClusterClient('data', config, deps.http.getAuthHeaders),
client: this.createClusterClient('data', config, deps.http.getAuthHeaders),
};
subscriber.next(coreClients);
return () => {
this.log.debug(`Closing elasticsearch clients`);
this.log.debug('Closing elasticsearch client');
coreClients.adminClient.close();
coreClients.dataClient.close();
coreClients.client.close();
};
})
),
@ -120,54 +117,27 @@ export class ElasticsearchService
const config = await this.config$.pipe(first()).toPromise();
const adminClient$ = clients$.pipe(map((clients) => clients.adminClient));
const dataClient$ = clients$.pipe(map((clients) => clients.dataClient));
const client$ = clients$.pipe(map((clients) => clients.client));
this.adminClient = {
const client = {
async callAsInternalUser(
endpoint: string,
clientParams: Record<string, any> = {},
options?: CallAPIOptions
) {
const client = await adminClient$.pipe(take(1)).toPromise();
return await client.callAsInternalUser(endpoint, clientParams, options);
},
asScoped: (request: ScopeableRequest) => {
return {
callAsInternalUser: this.adminClient!.callAsInternalUser,
async callAsCurrentUser(
endpoint: string,
clientParams: Record<string, any> = {},
options?: CallAPIOptions
) {
const client = await adminClient$.pipe(take(1)).toPromise();
return await client
.asScoped(request)
.callAsCurrentUser(endpoint, clientParams, options);
},
};
},
};
const dataClient = {
async callAsInternalUser(
endpoint: string,
clientParams: Record<string, any> = {},
options?: CallAPIOptions
) {
const client = await dataClient$.pipe(take(1)).toPromise();
return await client.callAsInternalUser(endpoint, clientParams, options);
const _client = await client$.pipe(take(1)).toPromise();
return await _client.callAsInternalUser(endpoint, clientParams, options);
},
asScoped(request: ScopeableRequest) {
return {
callAsInternalUser: dataClient.callAsInternalUser,
callAsInternalUser: client.callAsInternalUser,
async callAsCurrentUser(
endpoint: string,
clientParams: Record<string, any> = {},
options?: CallAPIOptions
) {
const client = await dataClient$.pipe(take(1)).toPromise();
return await client
const _client = await client$.pipe(take(1)).toPromise();
return await _client
.asScoped(request)
.callAsCurrentUser(endpoint, clientParams, options);
},
@ -175,8 +145,10 @@ export class ElasticsearchService
},
};
this.client = client;
const esNodesCompatibility$ = pollEsNodesVersion({
callWithInternalUser: this.adminClient.callAsInternalUser,
callWithInternalUser: client.callAsInternalUser,
log: this.log,
ignoreVersionMismatch: config.ignoreVersionMismatch,
esVersionCheckInterval: config.healthCheckDelay.asMilliseconds(),
@ -189,22 +161,22 @@ export class ElasticsearchService
};
return {
legacy: { config$: clients$.pipe(map((clients) => clients.config)) },
legacy: {
config$: clients$.pipe(map((clients) => clients.config)),
client,
createClient: this.createClient,
},
esNodesCompatibility$,
adminClient: this.adminClient,
dataClient,
createClient: this.createClient,
status$: calculateStatus$(esNodesCompatibility$),
};
}
public async start() {
if (typeof this.adminClient === 'undefined' || typeof this.createClient === 'undefined') {
if (typeof this.client === 'undefined' || typeof this.createClient === 'undefined') {
throw new Error('ElasticsearchService needs to be setup before calling start');
} else {
return {
legacy: {
client: this.adminClient,
client: this.client,
createClient: this.createClient,
},
};

View file

@ -30,62 +30,60 @@ import { ServiceStatus } from '../status';
export interface ElasticsearchServiceSetup {
/**
* @deprecated
* Use {@link ElasticsearchServiceStart.legacy | ElasticsearchServiceStart.legacy.createClient} instead.
* Use {@link ElasticsearchServiceStart.legacy} instead.
*
* Create application specific Elasticsearch cluster API client with customized config. See {@link IClusterClient}.
*
* @param type Unique identifier of the client
* @param clientConfig A config consists of Elasticsearch JS client options and
* valid sub-set of Elasticsearch service config.
* We fill all the missing properties in the `clientConfig` using the default
* Elasticsearch config so that we don't depend on default values set and
* controlled by underlying Elasticsearch JS client.
* We don't run validation against the passed config and expect it to be valid.
*
* @example
* ```js
* const client = elasticsearch.createCluster('my-app-name', config);
* const data = await client.callAsInternalUser();
* ```
*/
readonly createClient: (
type: string,
clientConfig?: Partial<ElasticsearchClientConfig>
) => ICustomClusterClient;
* */
legacy: {
/**
* @deprecated
* Use {@link ElasticsearchServiceStart.legacy | ElasticsearchServiceStart.legacy.createClient} instead.
*
* Create application specific Elasticsearch cluster API client with customized config. See {@link IClusterClient}.
*
* @param type Unique identifier of the client
* @param clientConfig A config consists of Elasticsearch JS client options and
* valid sub-set of Elasticsearch service config.
* We fill all the missing properties in the `clientConfig` using the default
* Elasticsearch config so that we don't depend on default values set and
* controlled by underlying Elasticsearch JS client.
* We don't run validation against the passed config and expect it to be valid.
*
* @example
* ```js
* const client = elasticsearch.createCluster('my-app-name', config);
* const data = await client.callAsInternalUser();
* ```
*/
readonly createClient: (
type: string,
clientConfig?: Partial<ElasticsearchClientConfig>
) => ICustomClusterClient;
/**
* @deprecated
* Use {@link ElasticsearchServiceStart.legacy | ElasticsearchServiceStart.legacy.client} instead.
*
* A client for the `admin` cluster. All Elasticsearch config value changes are processed under the hood.
* See {@link IClusterClient}.
*
* @example
* ```js
* const client = core.elasticsearch.adminClient;
* ```
*/
readonly adminClient: IClusterClient;
/**
* @deprecated
* Use {@link ElasticsearchServiceStart.legacy | ElasticsearchServiceStart.legacy.client} instead.
*
* A client for the `data` cluster. All Elasticsearch config value changes are processed under the hood.
* See {@link IClusterClient}.
*
* @example
* ```js
* const client = core.elasticsearch.dataClient;
* ```
*/
readonly dataClient: IClusterClient;
/**
* @deprecated
* Use {@link ElasticsearchServiceStart.legacy | ElasticsearchServiceStart.legacy.client} instead.
*
* All Elasticsearch config value changes are processed under the hood.
* See {@link IClusterClient}.
*
* @example
* ```js
* const client = core.elasticsearch.legacy.client;
* ```
*/
readonly client: IClusterClient;
};
}
/**
* @public
*/
export interface ElasticsearchServiceStart {
/**
* @deprecated
* Provided for the backward compatibility.
* Switch to the new elasticsearch client as soon as https://github.com/elastic/kibana/issues/35508 done.
* */
legacy: {
/**
* Create application specific Elasticsearch cluster API client with customized config. See {@link IClusterClient}.
@ -123,9 +121,9 @@ export interface ElasticsearchServiceStart {
}
/** @internal */
export interface InternalElasticsearchServiceSetup extends ElasticsearchServiceSetup {
export interface InternalElasticsearchServiceSetup {
// Required for the BWC with the legacy Kibana only.
readonly legacy: {
readonly legacy: ElasticsearchServiceSetup['legacy'] & {
readonly config$: Observable<ElasticsearchConfig>;
};
esNodesCompatibility$: Observable<NodesVersionCompatibility>;

View file

@ -383,8 +383,8 @@ describe('http service', () => {
// client contains authHeaders for BWC with legacy platform.
const [client] = clusterClientMock.mock.calls;
const [, , dataClientHeaders] = client;
expect(dataClientHeaders).toEqual(authHeaders);
const [, , clientHeaders] = client;
expect(clientHeaders).toEqual(authHeaders);
});
it('passes request authorization header to Elasticsearch if registerAuth was not set', async () => {
@ -407,8 +407,8 @@ describe('http service', () => {
.expect(200);
const [client] = clusterClientMock.mock.calls;
const [, , dataClientHeaders] = client;
expect(dataClientHeaders).toEqual({ authorization: authorizationHeader });
const [, , clientHeaders] = client;
expect(clientHeaders).toEqual({ authorization: authorizationHeader });
});
});
});

View file

@ -338,10 +338,8 @@ export {
* which uses the credentials of the incoming request
* - {@link ISavedObjectTypeRegistry | savedObjects.typeRegistry} - Type registry containing
* all the registered types.
* - {@link ScopedClusterClient | elasticsearch.dataClient} - Elasticsearch
* - {@link ScopedClusterClient | elasticsearch.legacy.client} - Elasticsearch
* data client which uses the credentials of the incoming request
* - {@link ScopedClusterClient | elasticsearch.adminClient} - Elasticsearch
* admin client which uses the credentials of the incoming request
* - {@link IUiSettingsClient | uiSettings.client} - uiSettings client
* which uses the credentials of the incoming request
*

View file

@ -279,9 +279,10 @@ export class LegacyService implements CoreService {
capabilities: setupDeps.core.capabilities,
context: setupDeps.core.context,
elasticsearch: {
adminClient: setupDeps.core.elasticsearch.adminClient,
dataClient: setupDeps.core.elasticsearch.dataClient,
createClient: setupDeps.core.elasticsearch.createClient,
legacy: {
client: setupDeps.core.elasticsearch.legacy.client,
createClient: setupDeps.core.elasticsearch.legacy.createClient,
},
},
http: {
createCookieSessionStorageFactory: setupDeps.core.http.createCookieSessionStorageFactory,

View file

@ -101,6 +101,7 @@ function pluginInitializerContextMock<T>(config: T = {} as T) {
}
type CoreSetupMockType = MockedKeys<CoreSetup> & {
elasticsearch: ReturnType<typeof elasticsearchServiceMock.createSetup>;
getStartServices: jest.MockedFunction<StartServicesAccessor<any, any>>;
};

View file

@ -147,9 +147,7 @@ export function createPluginSetupContext<TPlugin, TPluginDependencies>(
createContextContainer: deps.context.createContextContainer,
},
elasticsearch: {
adminClient: deps.elasticsearch.adminClient,
dataClient: deps.elasticsearch.dataClient,
createClient: deps.elasticsearch.createClient,
legacy: deps.elasticsearch.legacy,
},
http: {
createCookieSessionStorageFactory: deps.http.createCookieSessionStorageFactory,

View file

@ -67,6 +67,13 @@ describe('SavedObjectsService', () => {
};
};
const createStartDeps = (pluginsInitialized: boolean = true) => {
return {
pluginsInitialized,
elasticsearch: elasticsearchServiceMock.createStart(),
};
};
afterEach(() => {
jest.clearAllMocks();
});
@ -83,7 +90,7 @@ describe('SavedObjectsService', () => {
setup.setClientFactoryProvider(factoryProvider);
await soService.start({});
await soService.start(createStartDeps());
expect(clientProviderInstanceMock.setClientFactory).toHaveBeenCalledWith(factory);
});
@ -117,7 +124,7 @@ describe('SavedObjectsService', () => {
setup.addClientWrapper(1, 'A', wrapperA);
setup.addClientWrapper(2, 'B', wrapperB);
await soService.start({});
await soService.start(createStartDeps());
expect(clientProviderInstanceMock.addClientWrapperFactory).toHaveBeenCalledTimes(2);
expect(clientProviderInstanceMock.addClientWrapperFactory).toHaveBeenCalledWith(
@ -159,9 +166,10 @@ describe('SavedObjectsService', () => {
const soService = new SavedObjectsService(coreContext);
const coreSetup = createSetupDeps();
const coreStart = createStartDeps();
let i = 0;
coreSetup.elasticsearch.adminClient.callAsInternalUser = jest
coreStart.elasticsearch.legacy.client.callAsInternalUser = jest
.fn()
.mockImplementation(() =>
i++ <= 2
@ -170,7 +178,7 @@ describe('SavedObjectsService', () => {
);
await soService.setup(coreSetup);
await soService.start({}, 1);
await soService.start(coreStart, 1);
return expect(KibanaMigratorMock.mock.calls[0][0].callCluster()).resolves.toMatch('success');
});
@ -180,7 +188,7 @@ describe('SavedObjectsService', () => {
const soService = new SavedObjectsService(coreContext);
await soService.setup(createSetupDeps());
await soService.start({ pluginsInitialized: false });
await soService.start(createStartDeps(false));
expect(migratorInstanceMock.runMigrations).not.toHaveBeenCalled();
});
@ -188,7 +196,7 @@ describe('SavedObjectsService', () => {
const coreContext = createCoreContext({ skipMigration: true });
const soService = new SavedObjectsService(coreContext);
await soService.setup(createSetupDeps());
await soService.start({});
await soService.start(createStartDeps());
expect(migratorInstanceMock.runMigrations).not.toHaveBeenCalled();
});
@ -206,7 +214,7 @@ describe('SavedObjectsService', () => {
kibanaVersion: '8.0.0',
});
await soService.setup(setupDeps);
soService.start({});
soService.start(createStartDeps());
expect(migratorInstanceMock.runMigrations).toHaveBeenCalledTimes(0);
((setupDeps.elasticsearch.esNodesCompatibility$ as any) as BehaviorSubject<
NodesVersionCompatibility
@ -228,7 +236,7 @@ describe('SavedObjectsService', () => {
await soService.setup(createSetupDeps());
expect(migratorInstanceMock.runMigrations).toHaveBeenCalledTimes(0);
const startContract = await soService.start({});
const startContract = await soService.start(createStartDeps());
expect(startContract.migrator).toBe(migratorInstanceMock);
expect(migratorInstanceMock.runMigrations).toHaveBeenCalledTimes(1);
});
@ -237,7 +245,7 @@ describe('SavedObjectsService', () => {
const coreContext = createCoreContext({ skipMigration: false });
const soService = new SavedObjectsService(coreContext);
const setup = await soService.setup(createSetupDeps());
await soService.start({});
await soService.start(createStartDeps());
expect(() => {
setup.setClientFactoryProvider(jest.fn());
@ -268,7 +276,7 @@ describe('SavedObjectsService', () => {
const coreContext = createCoreContext({ skipMigration: false });
const soService = new SavedObjectsService(coreContext);
await soService.setup(createSetupDeps());
const { getTypeRegistry } = await soService.start({});
const { getTypeRegistry } = await soService.start(createStartDeps());
expect(getTypeRegistry()).toBe(typeRegistryInstanceMock);
});
@ -280,18 +288,19 @@ describe('SavedObjectsService', () => {
const soService = new SavedObjectsService(coreContext);
const coreSetup = createSetupDeps();
await soService.setup(coreSetup);
const { createScopedRepository } = await soService.start({});
const coreStart = createStartDeps();
const { createScopedRepository } = await soService.start(coreStart);
const req = {} as KibanaRequest;
createScopedRepository(req);
expect(coreSetup.elasticsearch.adminClient.asScoped).toHaveBeenCalledWith(req);
expect(coreStart.elasticsearch.legacy.client.asScoped).toHaveBeenCalledWith(req);
const [
{
value: { callAsCurrentUser },
},
] = coreSetup.elasticsearch.adminClient.asScoped.mock.results;
] = coreStart.elasticsearch.legacy.client.asScoped.mock.results;
const [
[, , , callCluster, includedHiddenTypes],
@ -306,7 +315,8 @@ describe('SavedObjectsService', () => {
const soService = new SavedObjectsService(coreContext);
const coreSetup = createSetupDeps();
await soService.setup(coreSetup);
const { createScopedRepository } = await soService.start({});
const coreStart = createStartDeps();
const { createScopedRepository } = await soService.start(coreStart);
const req = {} as KibanaRequest;
createScopedRepository(req, ['someHiddenType']);
@ -325,7 +335,8 @@ describe('SavedObjectsService', () => {
const soService = new SavedObjectsService(coreContext);
const coreSetup = createSetupDeps();
await soService.setup(coreSetup);
const { createInternalRepository } = await soService.start({});
const coreStart = createStartDeps();
const { createInternalRepository } = await soService.start(coreStart);
createInternalRepository();
@ -333,8 +344,8 @@ describe('SavedObjectsService', () => {
[, , , callCluster, includedHiddenTypes],
] = (SavedObjectsRepository.createRepository as jest.Mocked<any>).mock.calls;
expect(coreSetup.elasticsearch.adminClient.callAsInternalUser).toBe(callCluster);
expect(callCluster).toBe(coreSetup.elasticsearch.adminClient.callAsInternalUser);
expect(coreStart.elasticsearch.legacy.client.callAsInternalUser).toBe(callCluster);
expect(callCluster).toBe(coreStart.elasticsearch.legacy.client.callAsInternalUser);
expect(includedHiddenTypes).toEqual([]);
});
@ -343,7 +354,7 @@ describe('SavedObjectsService', () => {
const soService = new SavedObjectsService(coreContext);
const coreSetup = createSetupDeps();
await soService.setup(coreSetup);
const { createInternalRepository } = await soService.start({});
const { createInternalRepository } = await soService.start(createStartDeps());
createInternalRepository(['someHiddenType']);

View file

@ -29,7 +29,12 @@ import {
import { KibanaMigrator, IKibanaMigrator } from './migrations';
import { CoreContext } from '../core_context';
import { LegacyServiceDiscoverPlugins } from '../legacy';
import { InternalElasticsearchServiceSetup, APICaller } from '../elasticsearch';
import {
APICaller,
ElasticsearchServiceStart,
IClusterClient,
InternalElasticsearchServiceSetup,
} from '../elasticsearch';
import { KibanaConfigType } from '../kibana_config';
import { migrationsRetryCallCluster } from '../elasticsearch/retry_call_cluster';
import {
@ -278,8 +283,8 @@ interface WrappedClientFactoryWrapper {
}
/** @internal */
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface SavedObjectsStartDeps {
elasticsearch: ElasticsearchServiceStart;
pluginsInitialized?: boolean;
}
@ -365,7 +370,7 @@ export class SavedObjectsService
}
public async start(
{ pluginsInitialized = true }: SavedObjectsStartDeps,
{ elasticsearch, pluginsInitialized = true }: SavedObjectsStartDeps,
migrationsRetryDelay?: number
): Promise<InternalSavedObjectsServiceStart> {
if (!this.setupDeps || !this.config) {
@ -378,8 +383,14 @@ export class SavedObjectsService
.atPath<KibanaConfigType>('kibana')
.pipe(first())
.toPromise();
const adminClient = this.setupDeps!.elasticsearch.adminClient;
const migrator = this.createMigrator(kibanaConfig, this.config.migration, migrationsRetryDelay);
const client = elasticsearch.legacy.client;
const migrator = this.createMigrator(
kibanaConfig,
this.config.migration,
client,
migrationsRetryDelay
);
this.migrator$.next(migrator);
@ -435,9 +446,9 @@ export class SavedObjectsService
const repositoryFactory: SavedObjectsRepositoryFactory = {
createInternalRepository: (includedHiddenTypes?: string[]) =>
createRepository(adminClient.callAsInternalUser, includedHiddenTypes),
createRepository(client.callAsInternalUser, includedHiddenTypes),
createScopedRepository: (req: KibanaRequest, includedHiddenTypes?: string[]) =>
createRepository(adminClient.asScoped(req).callAsCurrentUser, includedHiddenTypes),
createRepository(client.asScoped(req).callAsCurrentUser, includedHiddenTypes),
};
const clientProvider = new SavedObjectsClientProvider({
@ -473,10 +484,9 @@ export class SavedObjectsService
private createMigrator(
kibanaConfig: KibanaConfigType,
savedObjectsConfig: SavedObjectsMigrationConfigType,
esClient: IClusterClient,
migrationsRetryDelay?: number
): KibanaMigrator {
const adminClient = this.setupDeps!.elasticsearch.adminClient;
return new KibanaMigrator({
typeRegistry: this.typeRegistry,
logger: this.logger,
@ -485,7 +495,7 @@ export class SavedObjectsService
savedObjectValidations: this.validations,
kibanaConfig,
callCluster: migrationsRetryCallCluster(
adminClient.callAsInternalUser,
esClient.callAsInternalUser,
this.logger,
migrationsRetryDelay
),

View file

@ -823,16 +823,15 @@ export class ElasticsearchErrorHelpers {
// @public (undocumented)
export interface ElasticsearchServiceSetup {
// @deprecated (undocumented)
readonly adminClient: IClusterClient;
// @deprecated (undocumented)
readonly createClient: (type: string, clientConfig?: Partial<ElasticsearchClientConfig>) => ICustomClusterClient;
// @deprecated (undocumented)
readonly dataClient: IClusterClient;
legacy: {
readonly createClient: (type: string, clientConfig?: Partial<ElasticsearchClientConfig>) => ICustomClusterClient;
readonly client: IClusterClient;
};
}
// @public (undocumented)
export interface ElasticsearchServiceStart {
// (undocumented)
// @deprecated (undocumented)
legacy: {
readonly createClient: (type: string, clientConfig?: Partial<ElasticsearchClientConfig>) => ICustomClusterClient;
readonly client: IClusterClient;

View file

@ -195,12 +195,13 @@ export class Server {
public async start() {
this.log.debug('starting server');
const elasticsearchStart = await this.elasticsearch.start();
const savedObjectsStart = await this.savedObjects.start({
elasticsearch: elasticsearchStart,
pluginsInitialized: this.pluginsInitialized,
});
const capabilitiesStart = this.capabilities.start();
const uiSettingsStart = await this.uiSettings.start();
const elasticsearchStart = await this.elasticsearch.start();
this.coreStart = {
capabilities: capabilitiesStart,

View file

@ -34,9 +34,9 @@ export default function (kibana) {
// All methods that ES plugin exposes are synchronous so we should get the first
// value from all observables here to be able to synchronously return and create
// cluster clients afterwards.
const { adminClient, dataClient } = server.newPlatform.setup.core.elasticsearch;
const adminCluster = new Cluster(adminClient);
const dataCluster = new Cluster(dataClient);
const { client } = server.newPlatform.setup.core.elasticsearch.legacy;
const adminCluster = new Cluster(client);
const dataCluster = new Cluster(client);
const esConfig = await server.newPlatform.__internals.elasticsearch.legacy.config$
.pipe(first())
@ -72,7 +72,7 @@ export default function (kibana) {
}
const cluster = new Cluster(
server.newPlatform.setup.core.elasticsearch.createClient(name, clientConfig)
server.newPlatform.setup.core.elasticsearch.legacy.createClient(name, clientConfig)
);
clusters.set(name, cluster);

View file

@ -129,13 +129,6 @@ describe('Saved Objects Mixin', () => {
waitUntilReady: jest.fn(),
},
},
newPlatform: {
__internals: {
elasticsearch: {
adminClient: { callAsInternalUser: mockCallCluster },
},
},
},
};
const coreStart = coreMock.createStart();

View file

@ -82,7 +82,7 @@ export class TelemetryPlugin implements Plugin {
const config$ = this.config$;
const isDev = this.isDev;
registerCollection(telemetryCollectionManager, elasticsearch.dataClient);
registerCollection(telemetryCollectionManager, elasticsearch.legacy.client);
const router = http.createRouter();
registerRoutes({

View file

@ -50,8 +50,10 @@ describe('CSV Execute Job', function () {
let cancellationToken: any;
const mockElasticsearch = {
dataClient: {
asScoped: () => clusterStub,
legacy: {
client: {
asScoped: () => clusterStub,
},
},
};
const mockUiSettingsClient = {

View file

@ -81,7 +81,7 @@ export const executeJobFactory: ExecuteJobFactory<ESQueueWorkerExecuteFn<
raw: { req: { url: '/' } },
} as Hapi.Request);
const { callAsCurrentUser } = elasticsearch.dataClient.asScoped(fakeRequest);
const { callAsCurrentUser } = elasticsearch.legacy.client.asScoped(fakeRequest);
const callEndpoint = (endpoint: string, clientParams = {}, options = {}) =>
callAsCurrentUser(endpoint, clientParams, options);

View file

@ -149,7 +149,7 @@ export async function generateCsvSearch(
const config = reporting.getConfig();
const elasticsearch = await reporting.getElasticsearchService();
const { callAsCurrentUser } = elasticsearch.dataClient.asScoped(req);
const { callAsCurrentUser } = elasticsearch.legacy.client.asScoped(req);
const callCluster = (...params: [string, object]) => callAsCurrentUser(...params);
const uiSettings = await getUiSettings(uiConfig);

View file

@ -59,8 +59,10 @@ beforeEach(async () => {
mockReporting = await createMockReportingCore(mockReportingConfig);
const mockElasticsearch = {
dataClient: {
asScoped: () => ({ callAsCurrentUser: jest.fn() }),
legacy: {
client: {
asScoped: () => ({ callAsCurrentUser: jest.fn() }),
},
},
};
const mockGetElasticsearch = jest.fn();

View file

@ -57,8 +57,10 @@ beforeEach(async () => {
mockReporting = await createMockReportingCore(mockReportingConfig);
const mockElasticsearch = {
dataClient: {
asScoped: () => ({ callAsCurrentUser: jest.fn() }),
legacy: {
client: {
asScoped: () => ({ callAsCurrentUser: jest.fn() }),
},
},
};
const mockGetElasticsearch = jest.fn();

View file

@ -52,7 +52,7 @@ export async function createQueueFactory<JobParamsType, JobPayloadType>(
interval: queueIndexInterval,
timeout: queueTimeout,
dateSeparator: '.',
client: elasticsearch.dataClient,
client: elasticsearch.legacy.client,
logger: createTaggedLogger(logger, ['esqueue', 'queue-worker']),
};

View file

@ -47,7 +47,7 @@ export function jobsQueryFactory(
elasticsearch: ElasticsearchServiceSetup
) {
const index = config.get('index');
const { callAsInternalUser } = elasticsearch.adminClient;
const { callAsInternalUser } = elasticsearch.legacy.client;
function execQuery(queryType: string, body: QueryBody) {
const defaultBody: Record<string, object> = {

View file

@ -12,14 +12,16 @@ const ONE_HUNDRED_MEGABYTES = 104857600;
describe('Reporting: Validate Max Content Length', () => {
const elasticsearch = {
dataClient: {
callAsInternalUser: () => ({
defaults: {
http: {
max_content_length: '100mb',
legacy: {
client: {
callAsInternalUser: () => ({
defaults: {
http: {
max_content_length: '100mb',
},
},
},
}),
}),
},
},
};
@ -34,14 +36,16 @@ describe('Reporting: Validate Max Content Length', () => {
it('should log warning messages when reporting has a higher max-size than elasticsearch', async () => {
const config = { get: sinon.stub().returns(FIVE_HUNDRED_MEGABYTES) };
const elasticsearch = {
dataClient: {
callAsInternalUser: () => ({
defaults: {
http: {
max_content_length: '100mb',
legacy: {
client: {
callAsInternalUser: () => ({
defaults: {
http: {
max_content_length: '100mb',
},
},
},
}),
}),
},
},
};

View file

@ -18,7 +18,7 @@ export async function validateMaxContentLength(
elasticsearch: ElasticsearchServiceSetup,
logger: LevelLogger
) {
const { callAsInternalUser } = elasticsearch.dataClient;
const { callAsInternalUser } = elasticsearch.legacy.client;
const elasticClusterSettingsResponse = await callAsInternalUser('cluster.getSettings', {
includeDefaults: true,

View file

@ -51,7 +51,9 @@ describe('POST /api/reporting/generate', () => {
({ server, httpSetup } = await setupServer());
const mockDeps = ({
elasticsearch: {
adminClient: { callAsInternalUser: jest.fn() },
legacy: {
client: { callAsInternalUser: jest.fn() },
},
},
security: {
authc: {

View file

@ -43,7 +43,7 @@ describe('GET /api/reporting/jobs/download', () => {
({ server, httpSetup } = await setupServer());
core = await createMockReportingCore(config, ({
elasticsearch: {
adminClient: { callAsInternalUser: jest.fn() },
legacy: { client: { callAsInternalUser: jest.fn() } },
},
security: {
authc: {
@ -89,7 +89,7 @@ describe('GET /api/reporting/jobs/download', () => {
it('fails on malformed download IDs', async () => {
// @ts-ignore
core.pluginSetupDeps.elasticsearch.adminClient = {
core.pluginSetupDeps.elasticsearch.legacy.client = {
callAsInternalUser: jest.fn().mockReturnValue(Promise.resolve(getHits())),
};
registerJobInfoRoutes(core);
@ -158,7 +158,7 @@ describe('GET /api/reporting/jobs/download', () => {
it('returns 404 if job not found', async () => {
// @ts-ignore
core.pluginSetupDeps.elasticsearch.adminClient = {
core.pluginSetupDeps.elasticsearch.legacy.client = {
callAsInternalUser: jest.fn().mockReturnValue(Promise.resolve(getHits())),
};
@ -171,7 +171,7 @@ describe('GET /api/reporting/jobs/download', () => {
it('returns a 401 if not a valid job type', async () => {
// @ts-ignore
core.pluginSetupDeps.elasticsearch.adminClient = {
core.pluginSetupDeps.elasticsearch.legacy.client = {
callAsInternalUser: jest
.fn()
.mockReturnValue(Promise.resolve(getHits({ jobtype: 'invalidJobType' }))),
@ -185,7 +185,7 @@ describe('GET /api/reporting/jobs/download', () => {
it('when a job is incomplete', async () => {
// @ts-ignore
core.pluginSetupDeps.elasticsearch.adminClient = {
core.pluginSetupDeps.elasticsearch.legacy.client = {
callAsInternalUser: jest
.fn()
.mockReturnValue(
@ -205,7 +205,7 @@ describe('GET /api/reporting/jobs/download', () => {
it('when a job fails', async () => {
// @ts-ignore
core.pluginSetupDeps.elasticsearch.adminClient = {
core.pluginSetupDeps.elasticsearch.legacy.client = {
callAsInternalUser: jest.fn().mockReturnValue(
Promise.resolve(
getHits({
@ -248,7 +248,7 @@ describe('GET /api/reporting/jobs/download', () => {
it('when a known job-type is complete', async () => {
const hits = getCompleteHits();
// @ts-ignore
core.pluginSetupDeps.elasticsearch.adminClient = {
core.pluginSetupDeps.elasticsearch.legacy.client = {
callAsInternalUser: jest.fn().mockReturnValue(Promise.resolve(hits)),
};
registerJobInfoRoutes(core);
@ -264,7 +264,7 @@ describe('GET /api/reporting/jobs/download', () => {
it('succeeds when security is not there or disabled', async () => {
const hits = getCompleteHits();
// @ts-ignore
core.pluginSetupDeps.elasticsearch.adminClient = {
core.pluginSetupDeps.elasticsearch.legacy.client = {
callAsInternalUser: jest.fn().mockReturnValue(Promise.resolve(hits)),
};
@ -288,7 +288,7 @@ describe('GET /api/reporting/jobs/download', () => {
outputContent: 'test',
});
// @ts-ignore
core.pluginSetupDeps.elasticsearch.adminClient = {
core.pluginSetupDeps.elasticsearch.legacy.client = {
callAsInternalUser: jest.fn().mockReturnValue(Promise.resolve(hits)),
};
registerJobInfoRoutes(core);
@ -308,7 +308,7 @@ describe('GET /api/reporting/jobs/download', () => {
outputContentType: 'application/pdf',
});
// @ts-ignore
core.pluginSetupDeps.elasticsearch.adminClient = {
core.pluginSetupDeps.elasticsearch.legacy.client = {
callAsInternalUser: jest.fn().mockReturnValue(Promise.resolve(hits)),
};
registerJobInfoRoutes(core);
@ -329,7 +329,7 @@ describe('GET /api/reporting/jobs/download', () => {
outputContentType: 'application/html',
});
// @ts-ignore
core.pluginSetupDeps.elasticsearch.adminClient = {
core.pluginSetupDeps.elasticsearch.legacy.client = {
callAsInternalUser: jest.fn().mockReturnValue(Promise.resolve(hits)),
};
registerJobInfoRoutes(core);

View file

@ -107,7 +107,7 @@ export class LicensingPlugin implements Plugin<LicensingPluginSetup, LicensingPl
return await client.callAsInternalUser(...args);
}
const dataClient: IClusterClient = {
const client: IClusterClient = {
callAsInternalUser,
asScoped(request?: ScopeableRequest): IScopedClusterClient {
return {
@ -115,8 +115,8 @@ export class LicensingPlugin implements Plugin<LicensingPluginSetup, LicensingPl
...args: Parameters<IScopedClusterClient['callAsCurrentUser']>
): ReturnType<IScopedClusterClient['callAsCurrentUser']> {
const [coreStart] = await core.getStartServices();
const client = coreStart.elasticsearch.legacy.client;
return await client.asScoped(request).callAsCurrentUser(...args);
const _client = coreStart.elasticsearch.legacy.client;
return await _client.asScoped(request).callAsCurrentUser(...args);
},
callAsInternalUser,
};
@ -124,7 +124,7 @@ export class LicensingPlugin implements Plugin<LicensingPluginSetup, LicensingPl
};
const { refresh, license$ } = this.createLicensePoller(
dataClient,
client,
pollingFrequency.asMilliseconds()
);

View file

@ -133,7 +133,7 @@ export class MlServerPlugin implements Plugin<MlPluginSetup, MlPluginStart, Plug
setupCapabilitiesSwitcher(coreSetup, plugins.licensing.license$, this.log);
// Can access via router's handler function 'context' parameter - context.ml.mlClient
const mlClient = coreSetup.elasticsearch.createClient(PLUGIN_ID, {
const mlClient = coreSetup.elasticsearch.legacy.createClient(PLUGIN_ID, {
plugins: [elasticsearchJsPlugin],
});

View file

@ -50,15 +50,15 @@ export class BulkUploader {
this._usageInterval = TELEMETRY_COLLECTION_INTERVAL;
this._log = log;
this._cluster = elasticsearch.createClient('admin', {
this._cluster = elasticsearch.legacy.createClient('admin', {
plugins: [monitoringBulk],
});
if (hasMonitoringCluster(config.elasticsearch)) {
this._log.info(`Detected direct connection to monitoring cluster`);
this._hasDirectConnectionToMonitoringCluster = true;
this._cluster = elasticsearch.createClient('monitoring-direct', config.elasticsearch);
elasticsearch.adminClient.callAsInternalUser('info').then((data) => {
this._cluster = elasticsearch.legacy.createClient('monitoring-direct', config.elasticsearch);
elasticsearch.legacy.client.callAsInternalUser('info').then((data) => {
this._productionClusterUuid = get(data, 'cluster_uuid');
});
}

View file

@ -131,7 +131,7 @@ export class Plugin {
this.legacyShimDependencies = {
router: core.http.createRouter(),
instanceUuid: core.uuid.getInstanceUuid(),
esDataClient: core.elasticsearch.dataClient,
esDataClient: core.elasticsearch.legacy.client,
kibanaStatsCollector: plugins.usageCollection?.getCollectorByType(
KIBANA_STATS_TYPE_MONITORING
),
@ -142,7 +142,7 @@ export class Plugin {
const cluster = (this.cluster = instantiateClient(
config.ui.elasticsearch,
this.log,
core.elasticsearch.createClient
core.elasticsearch.legacy.createClient
));
// Start our license service which will ensure

View file

@ -28,7 +28,7 @@ describe('ADD remote clusters', () => {
{ licenseCheckResult = { valid: true }, apiResponses = [], asserts, payload }: TestOptions
) => {
test(description, async () => {
const { adminClient: elasticsearchMock } = elasticsearchServiceMock.createSetup();
const elasticsearchMock = elasticsearchServiceMock.createClusterClient();
const mockRouteDependencies = {
router: httpServiceMock.createRouter(),

View file

@ -30,7 +30,7 @@ describe('DELETE remote clusters', () => {
{ licenseCheckResult = { valid: true }, apiResponses = [], asserts, params }: TestOptions
) => {
test(description, async () => {
const { adminClient: elasticsearchMock } = elasticsearchServiceMock.createSetup();
const elasticsearchMock = elasticsearchServiceMock.createClusterClient();
const mockRouteDependencies = {
router: httpServiceMock.createRouter(),

View file

@ -29,7 +29,7 @@ describe('GET remote clusters', () => {
{ licenseCheckResult = { valid: true }, apiResponses = [], asserts }: TestOptions
) => {
test(description, async () => {
const { adminClient: elasticsearchMock } = elasticsearchServiceMock.createSetup();
const elasticsearchMock = elasticsearchServiceMock.createClusterClient();
const mockRouteDependencies = {
router: httpServiceMock.createRouter(),

View file

@ -37,7 +37,7 @@ describe('UPDATE remote clusters', () => {
}: TestOptions
) => {
test(description, async () => {
const { adminClient: elasticsearchMock } = elasticsearchServiceMock.createSetup();
const elasticsearchMock = elasticsearchServiceMock.createClusterClient();
const mockRouteDependencies = {
router: httpServiceMock.createRouter(),

View file

@ -39,9 +39,7 @@ describe('Security Plugin', () => {
mockCoreSetup.http.isTlsEnabled = true;
mockClusterClient = elasticsearchServiceMock.createCustomClusterClient();
mockCoreSetup.elasticsearch.createClient.mockReturnValue(
(mockClusterClient as unknown) as jest.Mocked<ICustomClusterClient>
);
mockCoreSetup.elasticsearch.legacy.createClient.mockReturnValue(mockClusterClient);
mockDependencies = { licensing: { license$: of({}) } } as PluginSetupDependencies;
});
@ -114,8 +112,8 @@ describe('Security Plugin', () => {
it('properly creates cluster client instance', async () => {
await plugin.setup(mockCoreSetup, mockDependencies);
expect(mockCoreSetup.elasticsearch.createClient).toHaveBeenCalledTimes(1);
expect(mockCoreSetup.elasticsearch.createClient).toHaveBeenCalledWith('security', {
expect(mockCoreSetup.elasticsearch.legacy.createClient).toHaveBeenCalledTimes(1);
expect(mockCoreSetup.elasticsearch.legacy.createClient).toHaveBeenCalledWith('security', {
plugins: [elasticsearchClientPlugin],
});
});

View file

@ -109,7 +109,7 @@ export class Plugin {
.pipe(first())
.toPromise();
this.clusterClient = core.elasticsearch.createClient('security', {
this.clusterClient = core.elasticsearch.legacy.createClient('security', {
plugins: [elasticsearchClientPlugin],
});

View file

@ -18,7 +18,7 @@ export class TelemetryCollectionXpackPlugin implements Plugin {
public setup(core: CoreSetup, { telemetryCollectionManager }: TelemetryCollectionXpackDepsSetup) {
telemetryCollectionManager.setCollection({
esCluster: core.elasticsearch.dataClient,
esCluster: core.elasticsearch.legacy.client,
title: 'local_xpack',
priority: 1,
statsGetter: getStatsWithXpack,

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { CoreSetup } from 'kibana/server';
import { CoreSetup } from 'src/core/server';
import { schema } from '@kbn/config-schema';
import { FixtureStartDeps, FixtureSetupDeps } from './plugin';
import { ActionType, ActionTypeExecutorOptions } from '../../../../../../../plugins/actions/server';
@ -13,7 +13,7 @@ export function defineActionTypes(
core: CoreSetup<FixtureStartDeps>,
{ actions }: Pick<FixtureSetupDeps, 'actions'>
) {
const clusterClient = core.elasticsearch.adminClient;
const clusterClient = core.elasticsearch.legacy.client;
// Action types
const noopActionType: ActionType = {

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { CoreSetup } from 'kibana/server';
import { CoreSetup } from 'src/core/server';
import { schema } from '@kbn/config-schema';
import { times } from 'lodash';
import { FixtureStartDeps, FixtureSetupDeps } from './plugin';
@ -14,7 +14,7 @@ export function defineAlertTypes(
core: CoreSetup<FixtureStartDeps>,
{ alerting }: Pick<FixtureSetupDeps, 'alerting'>
) {
const clusterClient = core.elasticsearch.adminClient;
const clusterClient = core.elasticsearch.legacy.client;
const alwaysFiringAlertType: AlertType = {
id: 'test.always-firing',
name: 'Test: Always Firing',

View file

@ -11,7 +11,7 @@ import {
IKibanaResponse,
IRouter,
CoreSetup,
} from 'kibana/server';
} from 'src/core/server';
import { EventEmitter } from 'events';
import { TaskManagerStartContract } from '../../../../../plugins/task_manager/server';
@ -39,7 +39,7 @@ export function initRoutes(
taskTestingEvents: EventEmitter
) {
async function ensureIndexIsRefreshed() {
return await core.elasticsearch.adminClient.callAsInternalUser('indices.refresh', {
return await core.elasticsearch.legacy.client.callAsInternalUser('indices.refresh', {
index: '.kibana_task_manager',
});
}

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { Plugin, CoreSetup, CoreStart } from 'kibana/server';
import { Plugin, CoreSetup, CoreStart } from 'src/core/server';
import { EventEmitter } from 'events';
import { Subject } from 'rxjs';
import { first } from 'rxjs/operators';
@ -64,7 +64,7 @@ export class SampleTaskManagerFixturePlugin
}
}
await core.elasticsearch.adminClient.callAsInternalUser('index', {
await core.elasticsearch.legacy.client.callAsInternalUser('index', {
index: '.kibana_task_manager_test_result',
body: {
type: 'task',