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

Migrate data folder creation from legacy to KP #75527

Merged
merged 15 commits into from
Aug 26, 2020
Merged
Show file tree
Hide file tree
Changes from 11 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
@@ -1,13 +1,13 @@
<!-- 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; [CoreSetup](./kibana-plugin-core-server.coresetup.md) &gt; [uuid](./kibana-plugin-core-server.coresetup.uuid.md)
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [CoreSetup](./kibana-plugin-core-server.coresetup.md) &gt; [environment](./kibana-plugin-core-server.coresetup.environment.md)

## CoreSetup.uuid property
## CoreSetup.environment property

[UuidServiceSetup](./kibana-plugin-core-server.uuidservicesetup.md)
[EnvironmentServiceSetup](./kibana-plugin-core-server.environmentservicesetup.md)

<b>Signature:</b>

```typescript
uuid: UuidServiceSetup;
environment: EnvironmentServiceSetup;
```
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ export interface CoreSetup<TPluginsStart extends object = object, TStart = unkno
| [capabilities](./kibana-plugin-core-server.coresetup.capabilities.md) | <code>CapabilitiesSetup</code> | [CapabilitiesSetup](./kibana-plugin-core-server.capabilitiessetup.md) |
| [context](./kibana-plugin-core-server.coresetup.context.md) | <code>ContextSetup</code> | [ContextSetup](./kibana-plugin-core-server.contextsetup.md) |
| [elasticsearch](./kibana-plugin-core-server.coresetup.elasticsearch.md) | <code>ElasticsearchServiceSetup</code> | [ElasticsearchServiceSetup](./kibana-plugin-core-server.elasticsearchservicesetup.md) |
| [environment](./kibana-plugin-core-server.coresetup.environment.md) | <code>EnvironmentServiceSetup</code> | [EnvironmentServiceSetup](./kibana-plugin-core-server.environmentservicesetup.md) |
| [getStartServices](./kibana-plugin-core-server.coresetup.getstartservices.md) | <code>StartServicesAccessor&lt;TPluginsStart, TStart&gt;</code> | [StartServicesAccessor](./kibana-plugin-core-server.startservicesaccessor.md) |
| [http](./kibana-plugin-core-server.coresetup.http.md) | <code>HttpServiceSetup &amp; {</code><br/><code> resources: HttpResources;</code><br/><code> }</code> | [HttpServiceSetup](./kibana-plugin-core-server.httpservicesetup.md) |
| [logging](./kibana-plugin-core-server.coresetup.logging.md) | <code>LoggingServiceSetup</code> | [LoggingServiceSetup](./kibana-plugin-core-server.loggingservicesetup.md) |
| [savedObjects](./kibana-plugin-core-server.coresetup.savedobjects.md) | <code>SavedObjectsServiceSetup</code> | [SavedObjectsServiceSetup](./kibana-plugin-core-server.savedobjectsservicesetup.md) |
| [status](./kibana-plugin-core-server.coresetup.status.md) | <code>StatusServiceSetup</code> | [StatusServiceSetup](./kibana-plugin-core-server.statusservicesetup.md) |
| [uiSettings](./kibana-plugin-core-server.coresetup.uisettings.md) | <code>UiSettingsServiceSetup</code> | [UiSettingsServiceSetup](./kibana-plugin-core-server.uisettingsservicesetup.md) |
| [uuid](./kibana-plugin-core-server.coresetup.uuid.md) | <code>UuidServiceSetup</code> | [UuidServiceSetup](./kibana-plugin-core-server.uuidservicesetup.md) |

Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<!-- 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; [UuidServiceSetup](./kibana-plugin-core-server.uuidservicesetup.md) &gt; [getInstanceUuid](./kibana-plugin-core-server.uuidservicesetup.getinstanceuuid.md)
[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [EnvironmentServiceSetup](./kibana-plugin-core-server.environmentservicesetup.md) &gt; [getInstanceUuid](./kibana-plugin-core-server.environmentservicesetup.getinstanceuuid.md)

## UuidServiceSetup.getInstanceUuid() method
## EnvironmentServiceSetup.getInstanceUuid() method

Retrieve the Kibana instance uuid.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!-- 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; [EnvironmentServiceSetup](./kibana-plugin-core-server.environmentservicesetup.md)

## EnvironmentServiceSetup interface

APIs to access the application's environment information.

<b>Signature:</b>

```typescript
export interface EnvironmentServiceSetup
```

## Methods

| Method | Description |
| --- | --- |
| [getInstanceUuid()](./kibana-plugin-core-server.environmentservicesetup.getinstanceuuid.md) | Retrieve the Kibana instance uuid. |

2 changes: 1 addition & 1 deletion docs/development/core/server/kibana-plugin-core-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [ElasticsearchServiceStart](./kibana-plugin-core-server.elasticsearchservicestart.md) | |
| [ElasticsearchStatusMeta](./kibana-plugin-core-server.elasticsearchstatusmeta.md) | |
| [EnvironmentMode](./kibana-plugin-core-server.environmentmode.md) | |
| [EnvironmentServiceSetup](./kibana-plugin-core-server.environmentservicesetup.md) | APIs to access the application's environment information. |
| [ErrorHttpResponseOptions](./kibana-plugin-core-server.errorhttpresponseoptions.md) | HTTP response parameters |
| [Explanation](./kibana-plugin-core-server.explanation.md) | |
| [FakeRequest](./kibana-plugin-core-server.fakerequest.md) | Fake request object created manually by Kibana plugins. |
Expand Down Expand Up @@ -214,7 +215,6 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [UiSettingsServiceStart](./kibana-plugin-core-server.uisettingsservicestart.md) | |
| [URLMeaningfulParts](./kibana-plugin-core-server.urlmeaningfulparts.md) | We define our own typings because the current version of @<!-- -->types/node declares properties to be optional "hostname?: string". Although, parse call returns "hostname: null \| string". |
| [UserProvidedValues](./kibana-plugin-core-server.userprovidedvalues.md) | Describes the values explicitly set by user. |
| [UuidServiceSetup](./kibana-plugin-core-server.uuidservicesetup.md) | APIs to access the application's instance uuid. |

## Variables

Expand Down

This file was deleted.

79 changes: 79 additions & 0 deletions src/core/server/environment/create_data_folder.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* 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 { PathConfigType } from '../path';
import { createDataFolder } from './create_data_folder';
import { mkdir } from './fs';
import { loggingSystemMock } from '../logging/logging_system.mock';

jest.mock('./fs', () => ({
mkdir: jest.fn(() => Promise.resolve('')),
}));

const mkdirMock = mkdir as jest.Mock;

describe('createDataFolder', () => {
let logger: ReturnType<typeof loggingSystemMock.createLogger>;
let pathConfig: PathConfigType;

beforeEach(() => {
logger = loggingSystemMock.createLogger();
pathConfig = {
data: '/path/to/data/folder',
};
mkdirMock.mockResolvedValue(undefined);
});

afterEach(() => {
jest.clearAllMocks();
});

it('calls `mkdir` with the correct parameters', async () => {
await createDataFolder({ pathConfig, logger });
expect(mkdirMock).toHaveBeenCalledTimes(1);
expect(mkdirMock).toHaveBeenCalledWith(pathConfig.data, { recursive: true });
});

it('does not log error if the `mkdir` call is successful', async () => {
await createDataFolder({ pathConfig, logger });
expect(logger.error).not.toHaveBeenCalled();
});

it('throws an error if the `mkdir` call fails', async () => {
mkdirMock.mockRejectedValue('some-error');
await expect(() => createDataFolder({ pathConfig, logger })).rejects.toMatchInlineSnapshot(
`"some-error"`
);
});

it('logs an error message if the `mkdir` call fails', async () => {
mkdirMock.mockRejectedValue('some-error');
try {
await createDataFolder({ pathConfig, logger });
} catch (e) {
/* trap */
}
expect(logger.error).toHaveBeenCalledTimes(1);
expect(logger.error.mock.calls[0]).toMatchInlineSnapshot(`
Array [
"Error trying to create data folder at /path/to/data/folder: some-error",
]
`);
});
});
40 changes: 40 additions & 0 deletions src/core/server/environment/create_data_folder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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 { mkdir } from './fs';
import { Logger } from '../logging';
import { PathConfigType } from '../path';

export async function createDataFolder({
pathConfig,
logger,
}: {
pathConfig: PathConfigType;
logger: Logger;
}): Promise<void> {
const dataFolder = pathConfig.data;
try {
// Create the data directory (recursively, if the a parent dir doesn't exist).
// If it already exists, does nothing.
await mkdir(dataFolder, { recursive: true });
} catch (e) {
logger.error(`Error trying to create data folder at ${dataFolder}: ${e}`);
throw e;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,25 @@
* under the License.
*/

import { UuidService, UuidServiceSetup } from './uuid_service';
import { EnvironmentService, EnvironmentServiceSetup } from './environment_service';

const createSetupContractMock = () => {
const setupContract: jest.Mocked<UuidServiceSetup> = {
const setupContract: jest.Mocked<EnvironmentServiceSetup> = {
getInstanceUuid: jest.fn().mockImplementation(() => 'uuid'),
};
return setupContract;
};

type UuidServiceContract = PublicMethodsOf<UuidService>;
type EnvironmentServiceContract = PublicMethodsOf<EnvironmentService>;
const createMock = () => {
const mocked: jest.Mocked<UuidServiceContract> = {
const mocked: jest.Mocked<EnvironmentServiceContract> = {
setup: jest.fn(),
};
mocked.setup.mockResolvedValue(createSetupContractMock());
return mocked;
};

export const uuidServiceMock = {
export const environmentServiceMock = {
create: createMock,
createSetupContract: createSetupContractMock,
};
Original file line number Diff line number Diff line change
Expand Up @@ -17,40 +17,81 @@
* under the License.
*/

import { UuidService } from './uuid_service';
import { BehaviorSubject } from 'rxjs';
import { EnvironmentService } from './environment_service';
import { resolveInstanceUuid } from './resolve_uuid';
import { createDataFolder } from './create_data_folder';
import { CoreContext } from '../core_context';

import { configServiceMock } from '../config/config_service.mock';
import { loggingSystemMock } from '../logging/logging_system.mock';
import { mockCoreContext } from '../core_context.mock';

jest.mock('./resolve_uuid', () => ({
resolveInstanceUuid: jest.fn().mockResolvedValue('SOME_UUID'),
}));

jest.mock('./create_data_folder', () => ({
createDataFolder: jest.fn(),
}));

const pathConfig = {
data: 'data-folder',
};
const serverConfig = {
uuid: 'SOME_UUID',
};

const getConfigService = () => {
const configService = configServiceMock.create();
configService.atPath.mockImplementation((path) => {
if (path === 'path') {
return new BehaviorSubject(pathConfig);
}
if (path === 'server') {
return new BehaviorSubject(serverConfig);
}
return new BehaviorSubject({});
});
return configService;
};

describe('UuidService', () => {
let logger: ReturnType<typeof loggingSystemMock.create>;
let configService: ReturnType<typeof configServiceMock.create>;
let coreContext: CoreContext;

beforeEach(() => {
jest.clearAllMocks();
logger = loggingSystemMock.create();
coreContext = mockCoreContext.create({ logger });
configService = getConfigService();
coreContext = mockCoreContext.create({ logger, configService });
});

describe('#setup()', () => {
it('calls resolveInstanceUuid with core configuration service', async () => {
const service = new UuidService(coreContext);
it('calls resolveInstanceUuid with correct parameters', async () => {
const service = new EnvironmentService(coreContext);
await service.setup();
expect(resolveInstanceUuid).toHaveBeenCalledTimes(1);
expect(resolveInstanceUuid).toHaveBeenCalledWith({
configService: coreContext.configService,
pathConfig,
serverConfig,
logger: logger.get('uuid'),
});
});

it('calls createDataFolder with correct parameters', async () => {
const service = new EnvironmentService(coreContext);
await service.setup();
expect(createDataFolder).toHaveBeenCalledTimes(1);
expect(createDataFolder).toHaveBeenCalledWith({
pathConfig,
logger: logger.get('uuid'),
});
});

it('returns the uuid resolved from resolveInstanceUuid', async () => {
const service = new UuidService(coreContext);
const service = new EnvironmentService(coreContext);
const setup = await service.setup();
expect(setup.getInstanceUuid()).toEqual('SOME_UUID');
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,29 @@
* under the License.
*/

import { resolveInstanceUuid } from './resolve_uuid';
import { take } from 'rxjs/operators';
import { CoreContext } from '../core_context';
import { Logger } from '../logging';
import { IConfigService } from '../config';
import { PathConfigType, config as pathConfigDef } from '../path';
import { HttpConfigType, config as httpConfigDef } from '../http';
import { resolveInstanceUuid } from './resolve_uuid';
import { createDataFolder } from './create_data_folder';

/**
* APIs to access the application's instance uuid.
* APIs to access the application's environment information.
*
* @public
*/
export interface UuidServiceSetup {
export interface EnvironmentServiceSetup {
/**
* Retrieve the Kibana instance uuid.
*/
getInstanceUuid(): string;
}

/** @internal */
export class UuidService {
export class EnvironmentService {
private readonly log: Logger;
private readonly configService: IConfigService;
private uuid: string = '';
Expand All @@ -46,8 +50,16 @@ export class UuidService {
}

public async setup() {
const [pathConfig, serverConfig] = await Promise.all([
this.configService.atPath<PathConfigType>(pathConfigDef.path).pipe(take(1)).toPromise(),
this.configService.atPath<HttpConfigType>(httpConfigDef.path).pipe(take(1)).toPromise(),
]);

await createDataFolder({ pathConfig, logger: this.log });

this.uuid = await resolveInstanceUuid({
configService: this.configService,
pathConfig,
serverConfig,
logger: this.log,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ import { promisify } from 'util';

export const readFile = promisify(Fs.readFile);
export const writeFile = promisify(Fs.writeFile);
export const mkdir = promisify(Fs.mkdir);
Loading