Skip to content

Commit a3d593b

Browse files
Merge branch '7.x' into backport/7.x/pr-88675
2 parents 5cbfd2b + c7b900b commit a3d593b

51 files changed

Lines changed: 763 additions & 391 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/developer/plugin-list.asciidoc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -555,10 +555,6 @@ in their infrastructure.
555555
|NOTE: This plugin contains implementation of URL drilldown. For drilldowns infrastructure code refer to ui_actions_enhanced plugin.
556556
557557
558-
|{kib-repo}blob/{branch}/x-pack/plugins/vis_type_timeseries_enhanced/README.md[visTypeTimeseriesEnhanced]
559-
|The vis_type_timeseries_enhanced plugin is the x-pack counterpart to the OSS vis_type_timeseries plugin.
560-
561-
562558
|{kib-repo}blob/{branch}/x-pack/plugins/watcher/README.md[watcher]
563559
|This plugins adopts some conventions in addition to or in place of conventions in Kibana (at the time of the plugin's creation):
564560

docs/development/core/server/kibana-plugin-core-server.plugininitializercontext.config.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@
44

55
## PluginInitializerContext.config property
66

7+
Accessors for the plugin's configuration
8+
79
<b>Signature:</b>
810

911
```typescript
1012
config: {
1113
legacy: {
1214
globalConfig$: Observable<SharedGlobalConfig>;
15+
get: () => SharedGlobalConfig;
1316
};
1417
create: <T = ConfigSchema>() => Observable<T>;
15-
createIfExists: <T = ConfigSchema>() => Observable<T | undefined>;
18+
get: <T = ConfigSchema>() => T;
1619
};
1720
```

docs/development/core/server/kibana-plugin-core-server.plugininitializercontext.logger.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,29 @@
44

55
## PluginInitializerContext.logger property
66

7+
instance already bound to the plugin's logging context
8+
79
<b>Signature:</b>
810

911
```typescript
1012
logger: LoggerFactory;
1113
```
14+
15+
## Example
16+
17+
18+
```typescript
19+
// plugins/my-plugin/server/plugin.ts
20+
// "id: myPlugin" in `plugins/my-plugin/kibana.yaml`
21+
22+
export class MyPlugin implements Plugin {
23+
constructor(private readonly initContext: PluginInitializerContext) {
24+
this.logger = initContext.logger.get();
25+
// `logger` context: `plugins.myPlugin`
26+
this.mySubLogger = initContext.logger.get('sub'); // or this.logger.get('sub');
27+
// `mySubLogger` context: `plugins.myPlugin.sub`
28+
}
29+
}
30+
31+
```
32+

docs/development/core/server/kibana-plugin-core-server.plugininitializercontext.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ export interface PluginInitializerContext<ConfigSchema = unknown>
1616

1717
| Property | Type | Description |
1818
| --- | --- | --- |
19-
| [config](./kibana-plugin-core-server.plugininitializercontext.config.md) | <code>{</code><br/><code> legacy: {</code><br/><code> globalConfig$: Observable&lt;SharedGlobalConfig&gt;;</code><br/><code> };</code><br/><code> create: &lt;T = ConfigSchema&gt;() =&gt; Observable&lt;T&gt;;</code><br/><code> createIfExists: &lt;T = ConfigSchema&gt;() =&gt; Observable&lt;T &#124; undefined&gt;;</code><br/><code> }</code> | |
19+
| [config](./kibana-plugin-core-server.plugininitializercontext.config.md) | <code>{</code><br/><code> legacy: {</code><br/><code> globalConfig$: Observable&lt;SharedGlobalConfig&gt;;</code><br/><code> get: () =&gt; SharedGlobalConfig;</code><br/><code> };</code><br/><code> create: &lt;T = ConfigSchema&gt;() =&gt; Observable&lt;T&gt;;</code><br/><code> get: &lt;T = ConfigSchema&gt;() =&gt; T;</code><br/><code> }</code> | Accessors for the plugin's configuration |
2020
| [env](./kibana-plugin-core-server.plugininitializercontext.env.md) | <code>{</code><br/><code> mode: EnvironmentMode;</code><br/><code> packageInfo: Readonly&lt;PackageInfo&gt;;</code><br/><code> instanceUuid: string;</code><br/><code> }</code> | |
21-
| [logger](./kibana-plugin-core-server.plugininitializercontext.logger.md) | <code>LoggerFactory</code> | |
21+
| [logger](./kibana-plugin-core-server.plugininitializercontext.logger.md) | <code>LoggerFactory</code> | instance already bound to the plugin's logging context |
2222
| [opaqueId](./kibana-plugin-core-server.plugininitializercontext.opaqueid.md) | <code>PluginOpaqueId</code> | |
2323

packages/kbn-config/src/config_service.mock.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ const createConfigServiceMock = ({
1717
}: { atPath?: Record<string, any>; getConfig$?: Record<string, any> } = {}) => {
1818
const mocked: jest.Mocked<IConfigService> = {
1919
atPath: jest.fn(),
20+
atPathSync: jest.fn(),
2021
getConfig$: jest.fn(),
21-
optionalAtPath: jest.fn(),
2222
getUsedPaths: jest.fn(),
2323
getUnusedPaths: jest.fn(),
2424
isEnabledAtPath: jest.fn(),
@@ -27,6 +27,7 @@ const createConfigServiceMock = ({
2727
validate: jest.fn(),
2828
};
2929
mocked.atPath.mockReturnValue(new BehaviorSubject(atPath));
30+
mocked.atPathSync.mockReturnValue(atPath);
3031
mocked.getConfig$.mockReturnValue(new BehaviorSubject(new ObjectToConfigAdapter(getConfig$)));
3132
mocked.getUsedPaths.mockResolvedValue([]);
3233
mocked.getUnusedPaths.mockResolvedValue([]);

packages/kbn-config/src/config_service.test.ts

Lines changed: 66 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -105,27 +105,6 @@ test('re-validate config when updated', async () => {
105105
`);
106106
});
107107

108-
test("returns undefined if fetching optional config at a path that doesn't exist", async () => {
109-
const rawConfig = getRawConfigProvider({});
110-
const configService = new ConfigService(rawConfig, defaultEnv, logger);
111-
112-
const value$ = configService.optionalAtPath('unique-name');
113-
const value = await value$.pipe(first()).toPromise();
114-
115-
expect(value).toBeUndefined();
116-
});
117-
118-
test('returns observable config at optional path if it exists', async () => {
119-
const rawConfig = getRawConfigProvider({ value: 'bar' });
120-
const configService = new ConfigService(rawConfig, defaultEnv, logger);
121-
await configService.setSchema('value', schema.string());
122-
123-
const value$ = configService.optionalAtPath('value');
124-
const value: any = await value$.pipe(first()).toPromise();
125-
126-
expect(value).toBe('bar');
127-
});
128-
129108
test("does not push new configs when reloading if config at path hasn't changed", async () => {
130109
const rawConfig$ = new BehaviorSubject<Record<string, any>>({ key: 'value' });
131110
const rawConfigProvider = rawConfigServiceMock.create({ rawConfig$ });
@@ -209,34 +188,38 @@ test('flags schema paths as handled when registering a schema', async () => {
209188

210189
test('tracks unhandled paths', async () => {
211190
const initialConfig = {
212-
bar: {
213-
deep1: {
214-
key: '123',
215-
},
216-
deep2: {
217-
key: '321',
218-
},
191+
service: {
192+
string: 'str',
193+
number: 42,
219194
},
220-
foo: 'value',
221-
quux: {
222-
deep1: {
223-
key: 'hello',
224-
},
225-
deep2: {
226-
key: 'world',
227-
},
195+
plugin: {
196+
foo: 'bar',
197+
},
198+
unknown: {
199+
hello: 'dolly',
200+
number: 9000,
228201
},
229202
};
230203

231204
const rawConfigProvider = rawConfigServiceMock.create({ rawConfig: initialConfig });
232205
const configService = new ConfigService(rawConfigProvider, defaultEnv, logger);
233-
234-
configService.atPath('foo');
235-
configService.atPath(['bar', 'deep2']);
206+
await configService.setSchema(
207+
'service',
208+
schema.object({
209+
string: schema.string(),
210+
number: schema.number(),
211+
})
212+
);
213+
await configService.setSchema(
214+
'plugin',
215+
schema.object({
216+
foo: schema.string(),
217+
})
218+
);
236219

237220
const unused = await configService.getUnusedPaths();
238221

239-
expect(unused).toEqual(['bar.deep1.key', 'quux.deep1.key', 'quux.deep2.key']);
222+
expect(unused).toEqual(['unknown.hello', 'unknown.number']);
240223
});
241224

242225
test('correctly passes context', async () => {
@@ -339,22 +322,18 @@ test('does not throw if schema does not define "enabled" schema', async () => {
339322

340323
const rawConfigProvider = rawConfigServiceMock.create({ rawConfig: initialConfig });
341324
const configService = new ConfigService(rawConfigProvider, defaultEnv, logger);
342-
await expect(
325+
expect(
343326
configService.setSchema(
344327
'pid',
345328
schema.object({
346329
file: schema.string(),
347330
})
348331
)
349-
).resolves.toBeUndefined();
332+
).toBeUndefined();
350333

351334
const value$ = configService.atPath('pid');
352335
const value: any = await value$.pipe(first()).toPromise();
353336
expect(value.enabled).toBe(undefined);
354-
355-
const valueOptional$ = configService.optionalAtPath('pid');
356-
const valueOptional: any = await valueOptional$.pipe(first()).toPromise();
357-
expect(valueOptional.enabled).toBe(undefined);
358337
});
359338

360339
test('treats config as enabled if config path is not present in config', async () => {
@@ -457,3 +436,44 @@ test('logs deprecation warning during validation', async () => {
457436
]
458437
`);
459438
});
439+
440+
describe('atPathSync', () => {
441+
test('returns the value at path', async () => {
442+
const rawConfig = getRawConfigProvider({ key: 'foo' });
443+
const configService = new ConfigService(rawConfig, defaultEnv, logger);
444+
const stringSchema = schema.string();
445+
await configService.setSchema('key', stringSchema);
446+
447+
await configService.validate();
448+
449+
const value = configService.atPathSync('key');
450+
expect(value).toBe('foo');
451+
});
452+
453+
test('throws if called before `validate`', async () => {
454+
const rawConfig = getRawConfigProvider({ key: 'foo' });
455+
const configService = new ConfigService(rawConfig, defaultEnv, logger);
456+
const stringSchema = schema.string();
457+
await configService.setSchema('key', stringSchema);
458+
459+
expect(() => configService.atPathSync('key')).toThrowErrorMatchingInlineSnapshot(
460+
`"\`atPathSync\` called before config was validated"`
461+
);
462+
});
463+
464+
test('returns the last config value', async () => {
465+
const rawConfig$ = new BehaviorSubject<Record<string, any>>({ key: 'value' });
466+
const rawConfigProvider = rawConfigServiceMock.create({ rawConfig$ });
467+
468+
const configService = new ConfigService(rawConfigProvider, defaultEnv, logger);
469+
await configService.setSchema('key', schema.string());
470+
471+
await configService.validate();
472+
473+
expect(configService.atPathSync('key')).toEqual('value');
474+
475+
rawConfig$.next({ key: 'new-value' });
476+
477+
expect(configService.atPathSync('key')).toEqual('new-value');
478+
});
479+
});

0 commit comments

Comments
 (0)