add back the alpha entrypoint and update new service to Root...

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>
This commit is contained in:
aramissennyeydd
2025-10-22 12:26:39 -04:00
parent 3bdbba8c00
commit 4e245210fb
7 changed files with 95 additions and 36 deletions
@@ -40,8 +40,8 @@ import { DependencyGraph } from '../lib/DependencyGraph';
import { ServiceRegistry } from './ServiceRegistry';
import { createInitializationLogger } from './createInitializationLogger';
import { deepFreeze, unwrapFeature } from './helpers';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import type { InstanceMetadataServicePluginInfo } from '../../../backend-plugin-api/src/services/definitions/InstanceMetadataService';
import type { RootInstanceMetadataServicePluginInfo } from '@backstage/backend-plugin-api';
import { instanceMetadataServiceRef } from '@backstage/backend-plugin-api/alpha';
export interface BackendRegisterInit {
consumes: Set<ServiceOrExtensionPoint>;
@@ -99,31 +99,30 @@ const instanceRegistry = new (class InstanceRegistry {
};
})();
function createInstanceMetadataServiceFactory(
function createRootInstanceMetadataServiceFactory(
registrations: InternalBackendRegistrations[],
) {
const installedPlugins: {
[pluginId: string]: InstanceMetadataServicePluginInfo;
} = {};
const installedPlugins: Map<string, RootInstanceMetadataServicePluginInfo> =
new Map();
for (const registration of registrations) {
if (registration.featureType === 'registrations') {
for (const feature of registration.getRegistrations()) {
if (feature.type === 'plugin') {
if (!installedPlugins[feature.pluginId]) {
installedPlugins[feature.pluginId] = {
if (!installedPlugins.get(feature.pluginId)) {
installedPlugins.set(feature.pluginId, {
pluginId: feature.pluginId,
modules: [],
};
});
}
} else if (feature.type === 'module') {
if (!installedPlugins[feature.pluginId]) {
installedPlugins[feature.pluginId] = {
if (!installedPlugins.get(feature.pluginId)) {
installedPlugins.set(feature.pluginId, {
pluginId: feature.pluginId,
modules: [],
};
});
}
(
installedPlugins[feature.pluginId].modules as Array<{
installedPlugins.get(feature.pluginId)!.modules as Array<{
moduleId: string;
}>
).push({
@@ -134,11 +133,9 @@ function createInstanceMetadataServiceFactory(
}
}
return createServiceFactory({
service: coreServices.instanceMetadata,
deps: {
logger: coreServices.rootLogger,
},
factory: async ({ logger }) => {
service: coreServices.rootInstanceMetadata,
deps: {},
factory: async () => {
const readonlyInstalledPlugins = deepFreeze(
Object.values(installedPlugins),
);
@@ -146,18 +143,29 @@ function createInstanceMetadataServiceFactory(
getInstalledPlugins: () => Promise.resolve(readonlyInstalledPlugins),
};
const plugins = await instanceMetadata.getInstalledPlugins();
logger.info(
`Installed plugins on this instance: ${plugins
.map(p => p.pluginId)
.join(', ')}`,
);
return instanceMetadata;
},
});
}
function createDeprecatedInstanceMetadataServiceFactory() {
return createServiceFactory({
service: instanceMetadataServiceRef,
deps: {
instanceMetadata: coreServices.rootInstanceMetadata,
},
factory: async ({ instanceMetadata }) => {
const plugins = await instanceMetadata.getInstalledPlugins();
const service = {
getInstalledFeatures: () =>
plugins.map(e => ({ type: 'plugin' as const, pluginId: e.pluginId })),
};
return service;
},
});
}
export class BackendInitializer {
#startPromise?: Promise<void>;
#stopPromise?: Promise<void>;
@@ -259,8 +267,9 @@ export class BackendInitializer {
await this.#applyBackendFeatureLoaders(this.#registeredFeatureLoaders);
this.#serviceRegistry.add(
createInstanceMetadataServiceFactory(this.#registrations),
createRootInstanceMetadataServiceFactory(this.#registrations),
);
this.#serviceRegistry.add(createDeprecatedInstanceMetadataServiceFactory());
// This makes sure that any uncaught errors or unhandled rejections are
// caught and logged, rather than terminating the process. We register these
@@ -0,0 +1,32 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed 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.
*/
/** @alpha */
export type BackendFeatureMeta =
| {
type: 'plugin';
pluginId: string;
}
| {
type: 'module';
pluginId: string;
moduleId: string;
};
/** @alpha */
export interface InstanceMetadataService {
getInstalledFeatures: () => BackendFeatureMeta[];
}
+10 -1
View File
@@ -14,6 +14,11 @@
* limitations under the License.
*/
export type {
BackendFeatureMeta,
InstanceMetadataService,
} from './InstanceMetadataService';
export type {
ActionsRegistryService,
ActionsRegistryActionOptions,
@@ -22,4 +27,8 @@ export type {
export type { ActionsService, ActionsServiceAction } from './ActionsService';
export { actionsRegistryServiceRef, actionsServiceRef } from './refs';
export {
actionsRegistryServiceRef,
actionsServiceRef,
instanceMetadataServiceRef,
} from './refs';
@@ -16,6 +16,15 @@
import { createServiceRef } from '@backstage/backend-plugin-api';
/**
* @alpha
*/
export const instanceMetadataServiceRef = createServiceRef<
import('./InstanceMetadataService').InstanceMetadataService
>({
id: 'core.instanceMetadata',
});
/**
* Service for calling distributed actions
*
@@ -15,7 +15,7 @@
*/
/** @public */
export interface InstanceMetadataServicePluginInfo {
export interface RootInstanceMetadataServicePluginInfo {
readonly pluginId: string;
readonly modules: ReadonlyArray<{
moduleId: string;
@@ -23,8 +23,8 @@ export interface InstanceMetadataServicePluginInfo {
}
/** @public */
export interface InstanceMetadataService {
export interface RootInstanceMetadataService {
getInstalledPlugins: () => Promise<
ReadonlyArray<InstanceMetadataServicePluginInfo>
ReadonlyArray<RootInstanceMetadataServicePluginInfo>
>;
}
@@ -283,9 +283,9 @@ export namespace coreServices {
*
* @public
*/
export const instanceMetadata = createServiceRef<
import('./InstanceMetadataService').InstanceMetadataService
export const rootInstanceMetadata = createServiceRef<
import('./RootInstanceMetadataService').RootInstanceMetadataService
>({
id: 'core.instanceMetadata',
id: 'core.rootInstanceMetadata',
});
}
@@ -86,7 +86,7 @@ export type {
} from './UrlReaderService';
export type { BackstageUserInfo, UserInfoService } from './UserInfoService';
export type {
InstanceMetadataService,
InstanceMetadataServicePluginInfo,
} from './InstanceMetadataService';
RootInstanceMetadataService,
RootInstanceMetadataServicePluginInfo,
} from './RootInstanceMetadataService';
export { coreServices } from './coreServices';