inject catalog client where possible in the new backend system

Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
Fredrik Adelöw
2024-09-02 17:13:58 +02:00
parent 61e1632dda
commit 5edd344c98
18 changed files with 66 additions and 47 deletions
+8
View File
@@ -0,0 +1,8 @@
---
'@backstage/plugin-notifications-backend-module-email': patch
'@backstage/plugin-catalog-backend-module-github': patch
'@backstage/plugin-notifications-backend': patch
'@backstage/plugin-techdocs-backend': patch
---
Refactor to use injected catalog client in the new backend system
@@ -5,6 +5,7 @@
```ts
import { AnalyzeOptions } from '@backstage/plugin-catalog-node';
import { AuthService } from '@backstage/backend-plugin-api';
import { CatalogApi } from '@backstage/catalog-client';
import { CatalogProcessor } from '@backstage/plugin-catalog-node';
import { CatalogProcessorEmit } from '@backstage/plugin-catalog-node';
import { Config } from '@backstage/config';
@@ -129,6 +130,7 @@ export type GithubLocationAnalyzerOptions = {
tokenManager?: TokenManager;
auth?: AuthService;
githubCredentialsProvider?: GithubCredentialsProvider;
catalog?: CatalogApi;
};
// @public
@@ -44,6 +44,7 @@ export type GithubLocationAnalyzerOptions = {
tokenManager?: TokenManager;
auth?: AuthService;
githubCredentialsProvider?: GithubCredentialsProvider;
catalog?: CatalogApi;
};
/** @public */
@@ -54,7 +55,8 @@ export class GithubLocationAnalyzer implements ScmLocationAnalyzer {
private readonly auth: AuthService;
constructor(options: GithubLocationAnalyzerOptions) {
this.catalogClient = new CatalogClient({ discoveryApi: options.discovery });
this.catalogClient =
options.catalog ?? new CatalogClient({ discoveryApi: options.discovery });
this.integrations = ScmIntegrations.fromConfig(options.config);
this.githubCredentialsProvider =
options.githubCredentialsProvider ||
@@ -21,6 +21,7 @@ import {
import {
catalogAnalysisExtensionPoint,
catalogProcessingExtensionPoint,
catalogServiceRef,
} from '@backstage/plugin-catalog-node/alpha';
import { eventsServiceRef } from '@backstage/plugin-events-node';
import { GithubEntityProvider } from '../providers/GithubEntityProvider';
@@ -37,34 +38,37 @@ export const githubCatalogModule = createBackendModule({
register(env) {
env.registerInit({
deps: {
analyzers: catalogAnalysisExtensionPoint,
catalogAnalyzers: catalogAnalysisExtensionPoint,
auth: coreServices.auth,
catalog: catalogProcessingExtensionPoint,
catalogProcessing: catalogProcessingExtensionPoint,
config: coreServices.rootConfig,
discovery: coreServices.discovery,
events: eventsServiceRef,
logger: coreServices.logger,
scheduler: coreServices.scheduler,
catalog: catalogServiceRef,
},
async init({
catalog,
catalogProcessing,
config,
events,
logger,
scheduler,
analyzers,
catalogAnalyzers,
discovery,
auth,
catalog,
}) {
analyzers.addScmLocationAnalyzer(
catalogAnalyzers.addScmLocationAnalyzer(
new GithubLocationAnalyzer({
discovery,
config,
auth,
catalog,
}),
);
catalog.addEntityProvider(
catalogProcessing.addEntityProvider(
GithubEntityProvider.fromConfig(config, {
events,
logger,
@@ -42,6 +42,7 @@
"@backstage/catalog-model": "workspace:^",
"@backstage/config": "workspace:^",
"@backstage/integration-aws-node": "workspace:^",
"@backstage/plugin-catalog-node": "workspace:^",
"@backstage/plugin-notifications-common": "workspace:^",
"@backstage/plugin-notifications-node": "workspace:^",
"@backstage/types": "workspace:^",
@@ -17,7 +17,7 @@ import {
coreServices,
createBackendModule,
} from '@backstage/backend-plugin-api';
import { CatalogClient } from '@backstage/catalog-client';
import { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';
import { notificationsProcessingExtensionPoint } from '@backstage/plugin-notifications-node';
import { NotificationsEmailProcessor } from './processor';
import {
@@ -46,21 +46,17 @@ export const notificationsModuleEmail = createBackendModule({
deps: {
config: coreServices.rootConfig,
notifications: notificationsProcessingExtensionPoint,
discovery: coreServices.discovery,
logger: coreServices.logger,
auth: coreServices.auth,
cache: coreServices.cache,
catalog: catalogServiceRef,
},
async init({ config, notifications, discovery, logger, auth, cache }) {
const catalogClient = new CatalogClient({
discoveryApi: discovery,
});
async init({ config, notifications, logger, auth, cache, catalog }) {
notifications.addProcessor(
new NotificationsEmailProcessor(
logger,
config,
catalogClient,
catalog,
auth,
cache,
templateRenderer,
@@ -24,10 +24,7 @@ import {
} from '@backstage/backend-plugin-api';
import { Config, readDurationFromConfig } from '@backstage/config';
import { durationToMilliseconds } from '@backstage/types';
import {
CATALOG_FILTER_EXISTS,
CatalogClient,
} from '@backstage/catalog-client';
import { CATALOG_FILTER_EXISTS, CatalogApi } from '@backstage/catalog-client';
import {
getProcessorFiltersFromConfig,
Notification,
@@ -63,7 +60,7 @@ export class NotificationsEmailProcessor implements NotificationProcessor {
constructor(
private readonly logger: LoggerService,
private readonly config: Config,
private readonly catalog: CatalogClient,
private readonly catalog: CatalogApi,
private readonly auth: AuthService,
private readonly cache?: CacheService,
private readonly templateRenderer?: NotificationTemplateRenderer,
@@ -45,6 +45,7 @@
"@backstage/config": "workspace:^",
"@backstage/errors": "workspace:^",
"@backstage/plugin-auth-node": "workspace:^",
"@backstage/plugin-catalog-node": "workspace:^",
"@backstage/plugin-events-node": "workspace:^",
"@backstage/plugin-notifications-common": "workspace:^",
"@backstage/plugin-notifications-node": "workspace:^",
+4 -3
View File
@@ -25,6 +25,7 @@ import {
notificationsProcessingExtensionPoint,
NotificationsProcessingExtensionPoint,
} from '@backstage/plugin-notifications-node';
import { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';
class NotificationsProcessingExtensionPointImpl
implements NotificationsProcessingExtensionPoint
@@ -65,9 +66,9 @@ export const notificationsPlugin = createBackendPlugin({
httpRouter: coreServices.httpRouter,
logger: coreServices.logger,
database: coreServices.database,
discovery: coreServices.discovery,
signals: signalsServiceRef,
config: coreServices.rootConfig,
catalog: catalogServiceRef,
},
async init({
auth,
@@ -76,9 +77,9 @@ export const notificationsPlugin = createBackendPlugin({
httpRouter,
logger,
database,
discovery,
signals,
config,
catalog,
}) {
httpRouter.use(
await createRouter({
@@ -88,7 +89,7 @@ export const notificationsPlugin = createBackendPlugin({
logger,
config,
database,
discovery,
catalog,
signals,
processors: processingExtensions.processors,
}),
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
DatabaseManager,
PluginDatabaseManager,
@@ -25,6 +26,7 @@ import { ConfigReader } from '@backstage/config';
import { SignalsService } from '@backstage/plugin-signals-node';
import { mockCredentials, mockServices } from '@backstage/backend-test-utils';
import { NotificationSendOptions } from '@backstage/plugin-notifications-node';
import { CatalogClient } from '@backstage/catalog-client';
function createDatabase(): PluginDatabaseManager {
return DatabaseManager.fromConfig(
@@ -46,7 +48,6 @@ describe('createRouter', () => {
publish: jest.fn(),
};
const discovery = mockServices.discovery();
const userInfo = mockServices.userInfo();
const httpAuth = mockServices.httpAuth({
defaultCredentials: mockCredentials.service(),
@@ -55,17 +56,20 @@ describe('createRouter', () => {
const config = mockServices.rootConfig({
data: { app: { baseUrl: 'http://localhost' } },
});
const catalog = new CatalogClient({
discoveryApi: mockServices.discovery.mock(),
});
beforeAll(async () => {
const router = await createRouter({
logger: mockServices.logger.mock(),
database: createDatabase(),
discovery,
signals: signalService,
userInfo,
config,
httpAuth,
auth,
catalog,
});
app = express().use(router);
});
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { errorHandler, PluginDatabaseManager } from '@backstage/backend-common';
import express, { Request } from 'express';
import Router from 'express-promise-router';
@@ -22,7 +23,7 @@ import {
NotificationGetOptions,
} from '../database';
import { v4 as uuid } from 'uuid';
import { CatalogApi, CatalogClient } from '@backstage/catalog-client';
import { CatalogApi } from '@backstage/catalog-client';
import {
NotificationProcessor,
NotificationSendOptions,
@@ -30,7 +31,6 @@ import {
import { InputError } from '@backstage/errors';
import {
AuthService,
DiscoveryService,
HttpAuthService,
LoggerService,
UserInfoService,
@@ -53,12 +53,11 @@ export interface RouterOptions {
logger: LoggerService;
config: Config;
database: PluginDatabaseManager;
discovery: DiscoveryService;
auth: AuthService;
httpAuth: HttpAuthService;
userInfo: UserInfoService;
signals?: SignalsService;
catalog?: CatalogApi;
catalog: CatalogApi;
processors?: NotificationProcessor[];
}
@@ -73,14 +72,11 @@ export async function createRouter(
auth,
httpAuth,
userInfo,
discovery,
catalog,
processors = [],
signals,
} = options;
const catalogClient =
catalog ?? new CatalogClient({ discoveryApi: discovery });
const store = await DatabaseNotificationsStore.create({ database });
const frontendBaseUrl = config.getString('app.baseUrl');
@@ -474,7 +470,7 @@ export async function createRouter(
users = await getUsersForEntityRef(
entityRef,
recipients.excludeEntityRef ?? [],
{ auth, catalogClient },
{ auth, catalogClient: catalog },
);
} catch (e) {
logger.error(`Failed to resolve notification receivers: ${e}`);
+2 -3
View File
@@ -5,7 +5,6 @@
```ts
import { AuthService } from '@backstage/backend-plugin-api';
import { CatalogApi } from '@backstage/catalog-client';
import { CatalogClient } from '@backstage/catalog-client';
import { Config } from '@backstage/config';
import { DefaultTechDocsCollatorFactory as DefaultTechDocsCollatorFactory_2 } from '@backstage/plugin-search-backend-module-techdocs';
import { DiscoveryService } from '@backstage/backend-plugin-api';
@@ -66,7 +65,7 @@ export type OutOfTheBoxDeploymentOptions = {
cache: PluginCacheManager;
docsBuildStrategy?: DocsBuildStrategy_2;
buildLogTransport?: winston.transport;
catalogClient?: CatalogClient;
catalogClient?: CatalogApi;
httpAuth?: HttpAuthService;
auth?: AuthService;
};
@@ -80,7 +79,7 @@ export type RecommendedDeploymentOptions = {
cache: PluginCacheManager;
docsBuildStrategy?: DocsBuildStrategy_2;
buildLogTransport?: winston.transport;
catalogClient?: CatalogClient;
catalogClient?: CatalogApi;
httpAuth?: HttpAuthService;
auth?: AuthService;
};
+1
View File
@@ -66,6 +66,7 @@
"@backstage/errors": "workspace:^",
"@backstage/integration": "workspace:^",
"@backstage/plugin-catalog-common": "workspace:^",
"@backstage/plugin-catalog-node": "workspace:^",
"@backstage/plugin-permission-common": "workspace:^",
"@backstage/plugin-search-backend-module-techdocs": "workspace:^",
"@backstage/plugin-techdocs-common": "workspace:^",
+4 -1
View File
@@ -22,7 +22,6 @@ import {
coreServices,
createBackendPlugin,
} from '@backstage/backend-plugin-api';
import {
DocsBuildStrategy,
Generators,
@@ -39,6 +38,7 @@ import {
techdocsPublisherExtensionPoint,
} from '@backstage/plugin-techdocs-node';
import { createRouter } from '@backstage/plugin-techdocs-backend';
import { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';
import * as winston from 'winston';
/**
@@ -108,6 +108,7 @@ export const techdocsPlugin = createBackendPlugin({
cache: coreServices.cache,
httpAuth: coreServices.httpAuth,
auth: coreServices.auth,
catalog: catalogServiceRef,
},
async init({
config,
@@ -118,6 +119,7 @@ export const techdocsPlugin = createBackendPlugin({
cache,
httpAuth,
auth,
catalog,
}) {
const winstonLogger = loggerToWinstonLogger(logger);
// Preparers are responsible for fetching source files for documentation.
@@ -161,6 +163,7 @@ export const techdocsPlugin = createBackendPlugin({
discovery,
httpAuth,
auth,
catalogClient: catalog,
}),
);
@@ -15,11 +15,11 @@
*/
import { CacheService } from '@backstage/backend-plugin-api';
import { CachedEntityLoader } from './CachedEntityLoader';
import { CatalogClient } from '@backstage/catalog-client';
import { CatalogApi } from '@backstage/catalog-client';
import { CompoundEntityRef } from '@backstage/catalog-model';
describe('CachedEntityLoader', () => {
const catalog: jest.Mocked<CatalogClient> = {
const catalog: jest.Mocked<CatalogApi> = {
getEntityByRef: jest.fn(),
} as any;
@@ -13,8 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CacheService } from '@backstage/backend-plugin-api';
import { CatalogClient } from '@backstage/catalog-client';
import { CatalogApi } from '@backstage/catalog-client';
import {
Entity,
CompoundEntityRef,
@@ -22,12 +23,12 @@ import {
} from '@backstage/catalog-model';
export type CachedEntityLoaderOptions = {
catalog: CatalogClient;
catalog: CatalogApi;
cache: CacheService;
};
export class CachedEntityLoader {
private readonly catalog: CatalogClient;
private readonly catalog: CatalogApi;
private readonly cache: CacheService;
private readonly readTimeout = 1000;
@@ -13,11 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
createLegacyAuthAdapters,
PluginCacheManager,
} from '@backstage/backend-common';
import { CatalogClient } from '@backstage/catalog-client';
import { CatalogApi, CatalogClient } from '@backstage/catalog-client';
import { stringifyEntityRef } from '@backstage/catalog-model';
import { Config } from '@backstage/config';
import { NotFoundError } from '@backstage/errors';
@@ -48,7 +49,6 @@ import {
* deployment configuration (prepare/generate/publish all in the Backend).
*
* @public
*
*/
export type OutOfTheBoxDeploymentOptions = {
preparers: PreparerBuilder;
@@ -61,7 +61,7 @@ export type OutOfTheBoxDeploymentOptions = {
cache: PluginCacheManager;
docsBuildStrategy?: DocsBuildStrategy;
buildLogTransport?: winston.transport;
catalogClient?: CatalogClient;
catalogClient?: CatalogApi;
httpAuth?: HttpAuthService;
auth?: AuthService;
};
@@ -81,7 +81,7 @@ export type RecommendedDeploymentOptions = {
cache: PluginCacheManager;
docsBuildStrategy?: DocsBuildStrategy;
buildLogTransport?: winston.transport;
catalogClient?: CatalogClient;
catalogClient?: CatalogApi;
httpAuth?: HttpAuthService;
auth?: AuthService;
};
@@ -112,7 +112,7 @@ function isOutOfTheBoxOption(
* Creates a techdocs router.
*
* @public
*@deprecated This function is only exported for legacy reasons and will be removed in the future.
* @deprecated This function is only exported for legacy reasons and will be removed in the future.
* Please {@link https://backstage.io/docs/backend-system/building-backends/migrating | migrate } to use the new backend system and follow these {@link https://backstage.io/docs/features/techdocs/getting-started#new-backend-system | instructions } to install the user settings backend plugin.
*/
export async function createRouter(
+3
View File
@@ -6438,6 +6438,7 @@ __metadata:
"@backstage/cli": "workspace:^"
"@backstage/config": "workspace:^"
"@backstage/integration-aws-node": "workspace:^"
"@backstage/plugin-catalog-node": "workspace:^"
"@backstage/plugin-notifications-common": "workspace:^"
"@backstage/plugin-notifications-node": "workspace:^"
"@backstage/types": "workspace:^"
@@ -6464,6 +6465,7 @@ __metadata:
"@backstage/plugin-auth-backend": "workspace:^"
"@backstage/plugin-auth-backend-module-guest-provider": "workspace:^"
"@backstage/plugin-auth-node": "workspace:^"
"@backstage/plugin-catalog-node": "workspace:^"
"@backstage/plugin-events-backend": "workspace:^"
"@backstage/plugin-events-node": "workspace:^"
"@backstage/plugin-notifications-common": "workspace:^"
@@ -7683,6 +7685,7 @@ __metadata:
"@backstage/errors": "workspace:^"
"@backstage/integration": "workspace:^"
"@backstage/plugin-catalog-common": "workspace:^"
"@backstage/plugin-catalog-node": "workspace:^"
"@backstage/plugin-permission-common": "workspace:^"
"@backstage/plugin-search-backend-module-techdocs": "workspace:^"
"@backstage/plugin-techdocs-common": "workspace:^"