Skip to content

Commit ce45647

Browse files
authored
block SO setup API calls after startup (#58718)
1 parent 913afb3 commit ce45647

File tree

4 files changed

+54
-1
lines changed

4 files changed

+54
-1
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ export interface SavedObjectsServiceSetup
1616

1717
When plugins access the Saved Objects client, a new client is created using the factory provided to `setClientFactory` and wrapped by all wrappers registered through `addClientWrapper`<!-- -->.
1818

19+
All the setup APIs will throw if called after the service has started, and therefor cannot be used from legacy plugin code. Legacy plugins should use the legacy savedObject service until migrated.
20+
1921
## Example 1
2022

2123

src/core/MIGRATION_EXAMPLES.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -917,4 +917,10 @@ Would be converted to:
917917
918918
```typescript
919919
const migration: SavedObjectMigrationFn = (doc, { log }) => {...}
920-
```
920+
```
921+
922+
### Remarks
923+
924+
The `registerType` API will throw if called after the service has started, and therefor cannot be used from
925+
legacy plugin code. Legacy plugins should use the legacy savedObjects service and the legacy way to register
926+
saved object types until migrated.

src/core/server/saved_objects/saved_objects_service.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,36 @@ describe('SavedObjectsService', () => {
232232
expect(migratorInstanceMock.runMigrations).toHaveBeenCalledTimes(1);
233233
});
234234

235+
it('throws when calling setup APIs once started', async () => {
236+
const coreContext = createCoreContext({ skipMigration: false });
237+
const soService = new SavedObjectsService(coreContext);
238+
const setup = await soService.setup(createSetupDeps());
239+
await soService.start({});
240+
241+
expect(() => {
242+
setup.setClientFactoryProvider(jest.fn());
243+
}).toThrowErrorMatchingInlineSnapshot(
244+
`"cannot call \`setClientFactoryProvider\` after service startup."`
245+
);
246+
247+
expect(() => {
248+
setup.addClientWrapper(0, 'dummy', jest.fn());
249+
}).toThrowErrorMatchingInlineSnapshot(
250+
`"cannot call \`addClientWrapper\` after service startup."`
251+
);
252+
253+
expect(() => {
254+
setup.registerType({
255+
name: 'someType',
256+
hidden: false,
257+
namespaceAgnostic: false,
258+
mappings: { properties: {} },
259+
});
260+
}).toThrowErrorMatchingInlineSnapshot(
261+
`"cannot call \`registerType\` after service startup."`
262+
);
263+
});
264+
235265
describe('#getTypeRegistry', () => {
236266
it('returns the internal type registry of the service', async () => {
237267
const coreContext = createCoreContext({ skipMigration: false });

src/core/server/saved_objects/saved_objects_service.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ import { registerRoutes } from './routes';
6161
* the factory provided to `setClientFactory` and wrapped by all wrappers
6262
* registered through `addClientWrapper`.
6363
*
64+
* All the setup APIs will throw if called after the service has started, and therefor cannot be used
65+
* from legacy plugin code. Legacy plugins should use the legacy savedObject service until migrated.
66+
*
6467
* @example
6568
* ```ts
6669
* import { SavedObjectsClient, CoreSetup } from 'src/core/server';
@@ -275,6 +278,7 @@ export class SavedObjectsService
275278
private migrator$ = new Subject<KibanaMigrator>();
276279
private typeRegistry = new SavedObjectTypeRegistry();
277280
private validations: PropertyValidators = {};
281+
private started = false;
278282

279283
constructor(private readonly coreContext: CoreContext) {
280284
this.logger = coreContext.logger.get('savedobjects-service');
@@ -316,19 +320,28 @@ export class SavedObjectsService
316320

317321
return {
318322
setClientFactoryProvider: provider => {
323+
if (this.started) {
324+
throw new Error('cannot call `setClientFactoryProvider` after service startup.');
325+
}
319326
if (this.clientFactoryProvider) {
320327
throw new Error('custom client factory is already set, and can only be set once');
321328
}
322329
this.clientFactoryProvider = provider;
323330
},
324331
addClientWrapper: (priority, id, factory) => {
332+
if (this.started) {
333+
throw new Error('cannot call `addClientWrapper` after service startup.');
334+
}
325335
this.clientFactoryWrappers.push({
326336
priority,
327337
id,
328338
factory,
329339
});
330340
},
331341
registerType: type => {
342+
if (this.started) {
343+
throw new Error('cannot call `registerType` after service startup.');
344+
}
332345
this.typeRegistry.registerType(type);
333346
},
334347
};
@@ -415,6 +428,8 @@ export class SavedObjectsService
415428
clientProvider.addClientWrapperFactory(priority, id, factory);
416429
});
417430

431+
this.started = true;
432+
418433
return {
419434
migrator,
420435
clientProvider,

0 commit comments

Comments
 (0)