backend-app-api,backend-plugin-api: refactor existing service factories and fix type issues
Co-authored-by: blam <ben@blam.sh> Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -18,6 +18,7 @@ import { CacheManager } from '@backstage/backend-common';
|
||||
import {
|
||||
configServiceRef,
|
||||
createServiceFactory,
|
||||
pluginMetadataServiceRef,
|
||||
cacheServiceRef,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
|
||||
@@ -25,13 +26,13 @@ import {
|
||||
export const cacheFactory = createServiceFactory({
|
||||
service: cacheServiceRef,
|
||||
deps: {
|
||||
configFactory: configServiceRef,
|
||||
config: configServiceRef,
|
||||
plugin: pluginMetadataServiceRef,
|
||||
},
|
||||
factory: async ({ configFactory }) => {
|
||||
const config = await configFactory('root');
|
||||
async factory({ config }) {
|
||||
const cacheManager = CacheManager.fromConfig(config);
|
||||
return async (pluginId: string) => {
|
||||
return cacheManager.forPlugin(pluginId);
|
||||
return async ({ plugin }) => {
|
||||
return cacheManager.forPlugin(plugin.getId());
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -19,23 +19,20 @@ import {
|
||||
configServiceRef,
|
||||
createServiceFactory,
|
||||
loggerToWinstonLogger,
|
||||
loggerServiceRef,
|
||||
rootLoggerServiceRef,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
|
||||
/** @public */
|
||||
export const configFactory = createServiceFactory({
|
||||
service: configServiceRef,
|
||||
deps: {
|
||||
loggerFactory: loggerServiceRef,
|
||||
logger: rootLoggerServiceRef,
|
||||
},
|
||||
factory: async ({ loggerFactory }) => {
|
||||
const logger = await loggerFactory('root');
|
||||
async factory({ logger }) {
|
||||
const config = await loadBackendConfig({
|
||||
argv: process.argv,
|
||||
logger: loggerToWinstonLogger(logger),
|
||||
});
|
||||
return async () => {
|
||||
return config;
|
||||
};
|
||||
return config;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -19,19 +19,20 @@ import {
|
||||
configServiceRef,
|
||||
createServiceFactory,
|
||||
databaseServiceRef,
|
||||
pluginMetadataServiceRef,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
|
||||
/** @public */
|
||||
export const databaseFactory = createServiceFactory({
|
||||
service: databaseServiceRef,
|
||||
deps: {
|
||||
configFactory: configServiceRef,
|
||||
config: configServiceRef,
|
||||
plugin: pluginMetadataServiceRef,
|
||||
},
|
||||
factory: async ({ configFactory }) => {
|
||||
const config = await configFactory('root');
|
||||
async factory({ config }) {
|
||||
const databaseManager = DatabaseManager.fromConfig(config);
|
||||
return async (pluginId: string) => {
|
||||
return databaseManager.forPlugin(pluginId);
|
||||
return async ({ plugin }) => {
|
||||
return databaseManager.forPlugin(plugin.getId());
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -25,10 +25,9 @@ import {
|
||||
export const discoveryFactory = createServiceFactory({
|
||||
service: discoveryServiceRef,
|
||||
deps: {
|
||||
configFactory: configServiceRef,
|
||||
config: configServiceRef,
|
||||
},
|
||||
factory: async ({ configFactory }) => {
|
||||
const config = await configFactory('root');
|
||||
async factory({ config }) {
|
||||
const discovery = SingleHostDiscovery.fromConfig(config);
|
||||
return async () => {
|
||||
return discovery;
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
createServiceFactory,
|
||||
httpRouterServiceRef,
|
||||
configServiceRef,
|
||||
pluginMetadataServiceRef,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import Router from 'express-promise-router';
|
||||
import { Handler } from 'express';
|
||||
@@ -27,18 +28,20 @@ import { createServiceBuilder } from '@backstage/backend-common';
|
||||
export const httpRouterFactory = createServiceFactory({
|
||||
service: httpRouterServiceRef,
|
||||
deps: {
|
||||
configFactory: configServiceRef,
|
||||
config: configServiceRef,
|
||||
plugin: pluginMetadataServiceRef,
|
||||
},
|
||||
factory: async ({ configFactory }) => {
|
||||
async factory({ config }) {
|
||||
const rootRouter = Router();
|
||||
|
||||
const service = createServiceBuilder(module)
|
||||
.loadConfig(await configFactory('root'))
|
||||
.loadConfig(config)
|
||||
.addRouter('', rootRouter);
|
||||
|
||||
await service.start();
|
||||
|
||||
return async (pluginId?: string) => {
|
||||
return async ({ plugin }) => {
|
||||
const pluginId = plugin.getId();
|
||||
const path = pluginId ? `/api/${pluginId}` : '';
|
||||
return {
|
||||
use(handler: Handler) {
|
||||
|
||||
@@ -14,38 +14,23 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createRootLogger } from '@backstage/backend-common';
|
||||
import {
|
||||
createServiceFactory,
|
||||
Logger,
|
||||
loggerServiceRef,
|
||||
pluginMetadataServiceRef,
|
||||
rootLoggerServiceRef,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { Logger as WinstonLogger } from 'winston';
|
||||
|
||||
class BackstageLogger implements Logger {
|
||||
static fromWinston(logger: WinstonLogger): BackstageLogger {
|
||||
return new BackstageLogger(logger);
|
||||
}
|
||||
|
||||
private constructor(private readonly winston: WinstonLogger) {}
|
||||
|
||||
info(message: string, ...meta: any[]): void {
|
||||
this.winston.info(message, ...meta);
|
||||
}
|
||||
|
||||
child(fields: { [name: string]: string }): Logger {
|
||||
return new BackstageLogger(this.winston.child(fields));
|
||||
}
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export const loggerFactory = createServiceFactory({
|
||||
service: loggerServiceRef,
|
||||
deps: {},
|
||||
factory: async () => {
|
||||
const root = BackstageLogger.fromWinston(createRootLogger());
|
||||
return async (pluginId: string) => {
|
||||
return root.child({ pluginId });
|
||||
deps: {
|
||||
rootLogger: rootLoggerServiceRef,
|
||||
plugin: pluginMetadataServiceRef,
|
||||
},
|
||||
async factory({ rootLogger }) {
|
||||
return async ({ plugin }) => {
|
||||
return rootLogger.child({ pluginId: plugin.getId() });
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -27,20 +27,16 @@ import { ServerPermissionClient } from '@backstage/plugin-permission-node';
|
||||
export const permissionsFactory = createServiceFactory({
|
||||
service: permissionsServiceRef,
|
||||
deps: {
|
||||
configFactory: configServiceRef,
|
||||
discoveryFactory: discoveryServiceRef,
|
||||
tokenManagerFactory: tokenManagerServiceRef,
|
||||
config: configServiceRef,
|
||||
discovery: discoveryServiceRef,
|
||||
tokenManager: tokenManagerServiceRef,
|
||||
},
|
||||
factory: async ({ configFactory, discoveryFactory, tokenManagerFactory }) => {
|
||||
const config = await configFactory('root');
|
||||
const discovery = await discoveryFactory('root');
|
||||
const tokenManager = await tokenManagerFactory('root');
|
||||
const permissions = ServerPermissionClient.fromConfig(config, {
|
||||
discovery,
|
||||
tokenManager,
|
||||
});
|
||||
return async (_pluginId: string) => {
|
||||
return permissions;
|
||||
async factory({ config }) {
|
||||
return async ({ discovery, tokenManager }) => {
|
||||
return ServerPermissionClient.fromConfig(config, {
|
||||
discovery,
|
||||
tokenManager,
|
||||
});
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2022 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.
|
||||
*/
|
||||
|
||||
import { createRootLogger } from '@backstage/backend-common';
|
||||
import {
|
||||
createServiceFactory,
|
||||
Logger,
|
||||
rootLoggerServiceRef,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { Logger as WinstonLogger } from 'winston';
|
||||
|
||||
class BackstageLogger implements Logger {
|
||||
static fromWinston(logger: WinstonLogger): BackstageLogger {
|
||||
return new BackstageLogger(logger);
|
||||
}
|
||||
|
||||
private constructor(private readonly winston: WinstonLogger) {}
|
||||
|
||||
info(message: string, ...meta: any[]): void {
|
||||
this.winston.info(message, ...meta);
|
||||
}
|
||||
|
||||
child(fields: { [name: string]: string }): Logger {
|
||||
return new BackstageLogger(this.winston.child(fields));
|
||||
}
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export const loggerFactory = createServiceFactory({
|
||||
service: rootLoggerServiceRef,
|
||||
deps: {},
|
||||
async factory() {
|
||||
return BackstageLogger.fromWinston(createRootLogger());
|
||||
},
|
||||
});
|
||||
@@ -17,6 +17,7 @@
|
||||
import {
|
||||
configServiceRef,
|
||||
createServiceFactory,
|
||||
pluginMetadataServiceRef,
|
||||
schedulerServiceRef,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { TaskScheduler } from '@backstage/backend-tasks';
|
||||
@@ -25,13 +26,13 @@ import { TaskScheduler } from '@backstage/backend-tasks';
|
||||
export const schedulerFactory = createServiceFactory({
|
||||
service: schedulerServiceRef,
|
||||
deps: {
|
||||
configFactory: configServiceRef,
|
||||
config: configServiceRef,
|
||||
plugin: pluginMetadataServiceRef,
|
||||
},
|
||||
factory: async ({ configFactory }) => {
|
||||
const config = await configFactory('root');
|
||||
async factory({ config }) {
|
||||
const taskScheduler = TaskScheduler.fromConfig(config);
|
||||
return async (pluginId: string) => {
|
||||
return taskScheduler.forPlugin(pluginId);
|
||||
return async ({ plugin }) => {
|
||||
return taskScheduler.forPlugin(plugin.getId());
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
@@ -27,32 +27,11 @@ import { ServerTokenManager } from '@backstage/backend-common';
|
||||
export const tokenManagerFactory = createServiceFactory({
|
||||
service: tokenManagerServiceRef,
|
||||
deps: {
|
||||
configFactory: configServiceRef,
|
||||
loggerFactory: loggerServiceRef,
|
||||
config: configServiceRef,
|
||||
logger: loggerServiceRef,
|
||||
},
|
||||
factory: async ({ configFactory, loggerFactory }) => {
|
||||
const logger = await loggerFactory('root');
|
||||
const config = await configFactory('root');
|
||||
return async (_pluginId: string) => {
|
||||
// doesn't the logger want to be inferred from the plugin tho here?
|
||||
// maybe ... also why do we recreate it every time otherwise
|
||||
// we should memoize on a per plugin right? so I think it's should be fine to re-use the plugin one
|
||||
// we shouldn't recreate on a per plugin basis.
|
||||
// hm - on the other hand, is this really ever called more than once?
|
||||
// not this function right. should only be called when the plugin requests this serviceRef
|
||||
// yeah so no need to worry about memo probably
|
||||
// but we still want to scope the logger to the ServrTokenmanagfer>?
|
||||
// mm sure maybe
|
||||
// maybe in this case it doesn't provide so much value b
|
||||
// oh hang on - isn't it up to THE MANAGER to make a child internally if it wants to do that
|
||||
// so that it becomes a property intrinsic to that class, no matter how it's constructed
|
||||
// or is that too much responsibility for it - making the constructor complex so to speak, making it harder to tweak that behavior
|
||||
// this is not ultra efficient :)
|
||||
|
||||
// I think the naming here is wrong to be gonest
|
||||
// this isn't like the cache manager or the database manager
|
||||
// the manager name is confusuion i think
|
||||
// aye perhaps
|
||||
async factory() {
|
||||
return async ({ config, logger }) => {
|
||||
return ServerTokenManager.fromConfig(config, {
|
||||
logger: loggerToWinstonLogger(logger),
|
||||
});
|
||||
|
||||
@@ -27,15 +27,14 @@ import {
|
||||
export const urlReaderFactory = createServiceFactory({
|
||||
service: urlReaderServiceRef,
|
||||
deps: {
|
||||
configFactory: configServiceRef,
|
||||
loggerFactory: loggerServiceRef,
|
||||
config: configServiceRef,
|
||||
logger: loggerServiceRef,
|
||||
},
|
||||
factory: async ({ configFactory, loggerFactory }) => {
|
||||
return async (pluginId: string) => {
|
||||
const logger = await loggerFactory(pluginId);
|
||||
async factory() {
|
||||
return async ({ config, logger }) => {
|
||||
return UrlReaders.default({
|
||||
config,
|
||||
logger: loggerToWinstonLogger(logger),
|
||||
config: await configFactory(pluginId),
|
||||
});
|
||||
};
|
||||
},
|
||||
|
||||
@@ -50,11 +50,12 @@ export class BackendInitializer {
|
||||
if (extensionPoint) {
|
||||
result.set(name, extensionPoint);
|
||||
} else {
|
||||
const factory = await this.#serviceHolder.get(
|
||||
const impl = await this.#serviceHolder.get(
|
||||
ref as ServiceRef<unknown>,
|
||||
pluginId,
|
||||
);
|
||||
if (factory) {
|
||||
result.set(name, await factory(pluginId));
|
||||
if (impl) {
|
||||
result.set(name, impl);
|
||||
} else {
|
||||
missingRefs.add(ref);
|
||||
}
|
||||
|
||||
@@ -21,5 +21,6 @@ import { createServiceRef } from '../system/types';
|
||||
* @public
|
||||
*/
|
||||
export const configServiceRef = createServiceRef<Config>({
|
||||
id: 'core.config',
|
||||
id: 'core.root.config',
|
||||
scope: 'root',
|
||||
});
|
||||
|
||||
@@ -26,4 +26,5 @@ export { discoveryServiceRef } from './discoveryServiceRef';
|
||||
export { tokenManagerServiceRef } from './tokenManagerServiceRef';
|
||||
export { permissionsServiceRef } from './permissionsServiceRef';
|
||||
export { schedulerServiceRef } from './schedulerServiceRef';
|
||||
export { rootLoggerServiceRef } from './rootLoggerServiceRef';
|
||||
export { pluginMetadataServiceRef } from './pluginMetadataServiceRef';
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2022 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.
|
||||
*/
|
||||
|
||||
import { createServiceRef } from '../system/types';
|
||||
import { Logger } from './loggerServiceRef';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export const rootLoggerServiceRef = createServiceRef<Logger>({
|
||||
id: 'core.root.logger',
|
||||
scope: 'root',
|
||||
});
|
||||
@@ -14,11 +14,5 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export type {
|
||||
ServiceRef,
|
||||
TypesToServiceRef,
|
||||
DepsToDepFactories,
|
||||
FactoryFunc,
|
||||
ServiceFactory,
|
||||
} from './types';
|
||||
export type { ServiceRef, TypesToServiceRef, ServiceFactory } from './types';
|
||||
export { createServiceRef, createServiceFactory } from './types';
|
||||
|
||||
@@ -116,6 +116,7 @@ export function createServiceRef<T>(options: {
|
||||
};
|
||||
}
|
||||
|
||||
/** @ignore */
|
||||
type ServiceRefsToInstances<
|
||||
T extends { [key in string]: ServiceRef<unknown> },
|
||||
TScope extends 'root' | 'plugin' = 'root' | 'plugin',
|
||||
|
||||
@@ -31,13 +31,11 @@ export const catalogServiceRef = createServiceRef<CatalogApi>({
|
||||
createServiceFactory({
|
||||
service,
|
||||
deps: {
|
||||
discoveryFactory: discoveryServiceRef,
|
||||
discoveryApi: discoveryServiceRef,
|
||||
},
|
||||
factory: async ({ discoveryFactory }) => {
|
||||
const discoveryApi = await discoveryFactory('root');
|
||||
const catalogClient = new CatalogClient({ discoveryApi });
|
||||
return async _pluginId => {
|
||||
return catalogClient;
|
||||
async factory() {
|
||||
return async ({ discoveryApi }) => {
|
||||
return new CatalogClient({ discoveryApi });
|
||||
};
|
||||
},
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user