Skip to content

NP server setup APIs requiring access to start APIs #54886

@pgayvallet

Description

@pgayvallet

(this is probably the server-side counterpart of #49691)

This ticket is to discuss with @elastic/kibana-platform the possible solutions around the issue of setup API's requiring access to start API's to register logic that should be executed after startup.

Issue

In NP, lifecycle is split in two steps: setup and start. We ask plugins to perform all configuration/registration during setup.

However in some cases, the registered objects are meant to be using start API, which are not yet accessible.

First exemple that comes to mind is the telemetry usage collector:

export function createCollectorFetch(server: Server) {
return async function fetchUsageStats(): Promise<UsageStats> {
const internalRepo = server.newPlatform.setup.core.savedObjects.createInternalRepository();
const uiSettingsClient = server.newPlatform.start.core.uiSettings.asScopedToClient(
new SavedObjectsClient(internalRepo)
);
const user = await uiSettingsClient.getUserProvided();
const modifiedEntries = Object.keys(user)
.filter((key: string) => key !== 'buildNum')
.reduce((obj: any, key: string) => {
obj[key] = user[key].userValue;
return obj;
}, {});
return modifiedEntries;
};
}
export function registerManagementUsageCollector(
usageCollection: UsageCollectionSetup,
server: any
) {
const collector = usageCollection.makeUsageCollector({
type: KIBANA_MANAGEMENT_STATS_TYPE,
isReady: () => true,
fetch: createCollectorFetch(server),
});
usageCollection.registerCollector(collector);
}

The collector creation requires to access a uiSettingClient, which is only accessible via a core's start API.

    const internalRepo = server.newPlatform.setup.core.savedObjects.createInternalRepository();
    const uiSettingsClient = server.newPlatform.start.core.uiSettings.asScopedToClient(
      new SavedObjectsClient(internalRepo)
    );

but the registration is then done with a usageCollection'ssetup API:

  usageCollectionSetup.registerCollector(collector);

This code works in legacy, as the plugin got access to both setup and start at the same time, but cannot currently be migrated (therefor the blocker label).

Proposal

#49691 address this issue on the client-side by adding the getStartServices API, and at this time we did not see any need to do the same on server-side, but I think we now have a valid reason to do the same.

By implementing getStartServices to the server-side, the previous code could then be properly migrated to NP and be executed during setup:

export function createCollectorFetch(core: CoreSetup) {
  return async function fetchUsageStats(): Promise<UsageStats> {
    const internalRepo = core.savedObjects.createInternalRepository();
    const uiSettingsClient = (await core.getStartService()).uiSettings.asScopedToClient(
      new SavedObjectsClient(internalRepo)
    );
    const user = await uiSettingsClient.getUserProvided();
    const modifiedEntries = Object.keys(user)
      .filter((key: string) => key !== 'buildNum')
      .reduce((obj: any, key: string) => {
        obj[key] = user[key].userValue;
        return obj;
      }, {});

    return modifiedEntries;
  };
}

export function registerManagementUsageCollector(
  core: CoreSetup,
  usageCollection: UsageCollectionSetup,
) {
  const collector = usageCollection.makeUsageCollector({
    type: KIBANA_MANAGEMENT_STATS_TYPE,
    isReady: () => true,
    fetch: createCollectorFetch(core),
  });

  usageCollection.registerCollector(collector);
}

Metadata

Metadata

Assignees

Labels

Feature:New PlatformTeam:CorePlatform Core services: plugins, logging, config, saved objects, http, ES client, i18n, etc t//blockerdiscuss

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions