remove old backend support in the catalog collator

Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
Fredrik Adelöw
2024-12-18 13:27:27 +01:00
parent 3eb73508a8
commit dd515e3b23
15 changed files with 98 additions and 241 deletions
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/plugin-search-backend-module-catalog': minor
---
**BREAKING**: Removed support for the old backend system. Please [migrate to the new backend system](https://backstage.io/docs/backend-system/) and enable [the catalog collator](https://backstage.io/docs/features/search/collators#catalog) there.
As part of this, the `/alpha` export path is gone too. Just import the module from the root of the package as usual instead.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend': minor
---
Removed the long-deprecated `DefaultCatalogCollatorFactory` and `DefaultCatalogCollatorFactoryOptions` exports, which now no longer exist in the search plugin's offerings. If you were using these, you want to migrate to [the new backend system](https://backstage.io/docs/backend-system/) and use the [catalog collator](https://backstage.io/docs/features/search/collators#catalog) directly.
@@ -15,7 +15,6 @@
*/
import { useHotCleanup } from '@backstage/backend-common';
import { DefaultCatalogCollatorFactory } from '@backstage/plugin-search-backend-module-catalog';
import { ToolDocumentCollatorFactory } from '@backstage/plugin-search-backend-module-explore';
import { createRouter } from '@backstage/plugin-search-backend';
import { ElasticSearchSearchEngine } from '@backstage/plugin-search-backend-module-elasticsearch';
@@ -67,16 +66,6 @@ export default async function createPlugin(
initialDelay: { seconds: 3 },
});
// Collators are responsible for gathering documents known to plugins. This
// particular collator gathers entities from the software catalog.
indexBuilder.addCollator({
schedule,
factory: DefaultCatalogCollatorFactory.fromConfig(env.config, {
discovery: env.discovery,
tokenManager: env.tokenManager,
}),
});
indexBuilder.addCollator({
schedule,
factory: DefaultTechDocsCollatorFactory.fromConfig(env.config, {
-9
View File
@@ -28,8 +28,6 @@ import { CatalogProcessorRelationResult as CatalogProcessorRelationResult_2 } fr
import { CatalogProcessorResult as CatalogProcessorResult_2 } from '@backstage/plugin-catalog-node';
import { Config } from '@backstage/config';
import { DatabaseService } from '@backstage/backend-plugin-api';
import { DefaultCatalogCollatorFactory as DefaultCatalogCollatorFactory_2 } from '@backstage/plugin-search-backend-module-catalog';
import { DefaultCatalogCollatorFactoryOptions as DefaultCatalogCollatorFactoryOptions_2 } from '@backstage/plugin-search-backend-module-catalog';
import { DeferredEntity as DeferredEntity_2 } from '@backstage/plugin-catalog-node';
import { DiscoveryService } from '@backstage/backend-plugin-api';
import { EntitiesSearchFilter as EntitiesSearchFilter_2 } from '@backstage/plugin-catalog-node';
@@ -326,13 +324,6 @@ export class DefaultCatalogCollator {
// @public @deprecated (undocumented)
export const defaultCatalogCollatorEntityTransformer: CatalogCollatorEntityTransformer_2;
// @public @deprecated (undocumented)
export const DefaultCatalogCollatorFactory: typeof DefaultCatalogCollatorFactory_2;
// @public @deprecated (undocumented)
export type DefaultCatalogCollatorFactoryOptions =
DefaultCatalogCollatorFactoryOptions_2;
// @public @deprecated (undocumented)
export type DeferredEntity = DeferredEntity_2;
-15
View File
@@ -53,9 +53,7 @@ import {
} from '@backstage/plugin-catalog-node';
import {
defaultCatalogCollatorEntityTransformer as _defaultCatalogCollatorEntityTransformer,
DefaultCatalogCollatorFactory as _DefaultCatalogCollatorFactory,
type CatalogCollatorEntityTransformer as _CatalogCollatorEntityTransformer,
type DefaultCatalogCollatorFactoryOptions as _DefaultCatalogCollatorFactoryOptions,
} from '@backstage/plugin-search-backend-module-catalog';
/**
@@ -254,12 +252,6 @@ export type AnalyzeLocationGenerateEntity = _AnalyzeLocationGenerateEntity;
*/
export type AnalyzeLocationEntityField = _AnalyzeLocationEntityField;
/**
* @public
* @deprecated import from `@backstage/plugin-search-backend-module-catalog` instead
*/
export const DefaultCatalogCollatorFactory = _DefaultCatalogCollatorFactory;
/**
* @public
* @deprecated import from `@backstage/plugin-search-backend-module-catalog` instead
@@ -267,13 +259,6 @@ export const DefaultCatalogCollatorFactory = _DefaultCatalogCollatorFactory;
export const defaultCatalogCollatorEntityTransformer =
_defaultCatalogCollatorEntityTransformer;
/**
* @public
* @deprecated import from `@backstage/plugin-search-backend-module-catalog` instead
*/
export type DefaultCatalogCollatorFactoryOptions =
_DefaultCatalogCollatorFactoryOptions;
/**
* @public
* @deprecated import from `@backstage/plugin-search-backend-module-catalog` instead
@@ -8,7 +8,9 @@
"pluginPackage": "@backstage/plugin-search-backend"
},
"publishConfig": {
"access": "public"
"access": "public",
"main": "dist/index.cjs.js",
"types": "dist/index.d.ts"
},
"homepage": "https://backstage.io",
"repository": {
@@ -17,23 +19,8 @@
"directory": "plugins/search-backend-module-catalog"
},
"license": "Apache-2.0",
"exports": {
".": "./src/index.ts",
"./alpha": "./src/alpha.ts",
"./package.json": "./package.json"
},
"main": "src/index.ts",
"types": "src/index.ts",
"typesVersions": {
"*": {
"alpha": [
"src/alpha.ts"
],
"package.json": [
"package.json"
]
}
},
"files": [
"dist",
"config.d.ts"
@@ -48,7 +35,6 @@
"test": "backstage-cli package test"
},
"dependencies": {
"@backstage/backend-common": "^0.25.0",
"@backstage/backend-plugin-api": "workspace:^",
"@backstage/catalog-client": "workspace:^",
"@backstage/catalog-model": "workspace:^",
@@ -1,13 +0,0 @@
## API Report File for "@backstage/plugin-search-backend-module-catalog"
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { BackendFeature } from '@backstage/backend-plugin-api';
// @alpha (undocumented)
const _feature: BackendFeature;
export default _feature;
// (No @packageDocumentation comment for this package)
```
@@ -3,22 +3,10 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
/// <reference types="node" />
import { AuthService } from '@backstage/backend-plugin-api';
import { BackendFeature } from '@backstage/backend-plugin-api';
import { CatalogApi } from '@backstage/catalog-client';
import { CatalogCollatorEntityTransformer as CatalogCollatorEntityTransformer_2 } from '@backstage/plugin-search-backend-module-catalog';
import { CatalogEntityDocument } from '@backstage/plugin-catalog-common';
import { Config } from '@backstage/config';
import { DiscoveryService } from '@backstage/backend-plugin-api';
import { DocumentCollatorFactory } from '@backstage/plugin-search-common';
import { Entity } from '@backstage/catalog-model';
import { ExtensionPoint } from '@backstage/backend-plugin-api';
import { GetEntitiesRequest } from '@backstage/catalog-client';
import { Permission } from '@backstage/plugin-permission-common';
import { Readable } from 'stream';
import { TokenManager } from '@backstage/backend-common';
// @public (undocumented)
export type CatalogCollatorEntityTransformer = (
@@ -27,43 +15,16 @@ export type CatalogCollatorEntityTransformer = (
// @public
export type CatalogCollatorExtensionPoint = {
setEntityTransformer(transformer: CatalogCollatorEntityTransformer_2): void;
setEntityTransformer(transformer: CatalogCollatorEntityTransformer): void;
};
// @public
export const catalogCollatorExtensionPoint: ExtensionPoint<CatalogCollatorExtensionPoint>;
// @public
const _default: BackendFeature;
export default _default;
// @public (undocumented)
export const defaultCatalogCollatorEntityTransformer: CatalogCollatorEntityTransformer;
// @public @deprecated
export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory {
// (undocumented)
static fromConfig(
configRoot: Config,
options: DefaultCatalogCollatorFactoryOptions,
): DefaultCatalogCollatorFactory;
// (undocumented)
getCollator(): Promise<Readable>;
// (undocumented)
readonly type = 'software-catalog';
// (undocumented)
readonly visibilityPermission: Permission;
}
// @public @deprecated (undocumented)
export type DefaultCatalogCollatorFactoryOptions = {
auth?: AuthService;
discovery: DiscoveryService;
tokenManager?: TokenManager;
locationTemplate?: string;
filter?: GetEntitiesRequest['filter'];
batchSize?: number;
catalogClient?: CatalogApi;
entityTransformer?: CatalogCollatorEntityTransformer;
};
// @public
const searchBackendModule: BackendFeature;
export default searchBackendModule;
```
@@ -1,21 +0,0 @@
/*
* Copyright 2024 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 { default as feature } from './module';
/** @alpha */
const _feature = feature;
export default _feature;
@@ -16,7 +16,6 @@
import { mockServices } from '@backstage/backend-test-utils';
import { Entity } from '@backstage/catalog-model';
import { ConfigReader } from '@backstage/config';
import { catalogServiceMock } from '@backstage/plugin-catalog-node/testUtils';
import { TestPipeline } from '@backstage/plugin-search-backend-node';
import { Readable } from 'stream';
@@ -54,9 +53,7 @@ const expectedEntities: Entity[] = [
describe('DefaultCatalogCollatorFactory', () => {
const config = mockServices.rootConfig();
const discovery = mockServices.discovery.mock({
getBaseUrl: async () => 'http://localhost:7007',
});
const auth = mockServices.auth();
const catalog = catalogServiceMock({ entities: expectedEntities });
describe('getCollator', () => {
@@ -65,8 +62,8 @@ describe('DefaultCatalogCollatorFactory', () => {
beforeEach(async () => {
factory = DefaultCatalogCollatorFactory.fromConfig(config, {
discovery,
catalogClient: catalog,
auth,
catalog,
});
collator = await factory.getCollator();
});
@@ -117,8 +114,8 @@ describe('DefaultCatalogCollatorFactory', () => {
it('maps a returned entity to an expected CatalogEntityDocument with custom transformer', async () => {
const customFactory = DefaultCatalogCollatorFactory.fromConfig(config, {
discovery,
catalogClient: catalog,
auth,
catalog,
entityTransformer: entity => ({
title: `custom-title-${
entity.metadata.title ?? entity.metadata.name
@@ -173,11 +170,19 @@ describe('DefaultCatalogCollatorFactory', () => {
it('maps a returned entity with a custom locationTemplate', async () => {
// Provide an alternate location template.
factory = DefaultCatalogCollatorFactory.fromConfig(new ConfigReader({}), {
discovery: discovery,
catalogClient: catalog,
locationTemplate: '/software/:name',
});
factory = DefaultCatalogCollatorFactory.fromConfig(
mockServices.rootConfig({
data: {
search: {
collators: { catalog: { locationTemplate: '/software/:name' } },
},
},
}),
{
auth,
catalog,
},
);
collator = await factory.getCollator();
const pipeline = TestPipeline.fromCollator(collator);
@@ -189,13 +194,19 @@ describe('DefaultCatalogCollatorFactory', () => {
it('allows filtering of the retrieved catalog entities', async () => {
// Provide a custom filter.
factory = DefaultCatalogCollatorFactory.fromConfig(new ConfigReader({}), {
discovery: discovery,
catalogClient: catalog,
filter: {
kind: ['Foo', 'Bar'],
factory = DefaultCatalogCollatorFactory.fromConfig(
mockServices.rootConfig({
data: {
search: {
collators: { catalog: { filter: { kind: ['Foo', 'Bar'] } } },
},
},
}),
{
auth,
catalog,
},
});
);
collator = await factory.getCollator();
const pipeline = TestPipeline.fromCollator(collator);
@@ -206,11 +217,19 @@ describe('DefaultCatalogCollatorFactory', () => {
});
it('paginates through catalog entities using batchSize', async () => {
factory = DefaultCatalogCollatorFactory.fromConfig(config, {
discovery,
catalogClient: catalog,
batchSize: 1,
});
factory = DefaultCatalogCollatorFactory.fromConfig(
mockServices.rootConfig({
data: {
search: {
collators: { catalog: { batchSize: 1 } },
},
},
}),
{
auth,
catalog,
},
);
collator = await factory.getCollator();
const pipeline = TestPipeline.fromCollator(collator);
@@ -14,20 +14,13 @@
* limitations under the License.
*/
import {
TokenManager,
createLegacyAuthAdapters,
} from '@backstage/backend-common';
import { AuthService, DiscoveryService } from '@backstage/backend-plugin-api';
import {
CatalogApi,
CatalogClient,
GetEntitiesRequest,
} from '@backstage/catalog-client';
import { AuthService } from '@backstage/backend-plugin-api';
import { QueryEntitiesInitialRequest } from '@backstage/catalog-client';
import { stringifyEntityRef } from '@backstage/catalog-model';
import { Config } from '@backstage/config';
import { CatalogEntityDocument } from '@backstage/plugin-catalog-common';
import { catalogEntityReadPermission } from '@backstage/plugin-catalog-common/alpha';
import { CatalogService } from '@backstage/plugin-catalog-node';
import { Permission } from '@backstage/plugin-permission-common';
import { DocumentCollatorFactory } from '@backstage/plugin-search-common';
import { Readable } from 'stream';
@@ -35,29 +28,10 @@ import { CatalogCollatorEntityTransformer } from './CatalogCollatorEntityTransfo
import { readCollatorConfigOptions } from './config';
import { defaultCatalogCollatorEntityTransformer } from './defaultCatalogCollatorEntityTransformer';
/**
* @public
* @deprecated This type is deprecated along with the {@link DefaultCatalogCollatorFactory}.
*/
export type DefaultCatalogCollatorFactoryOptions = {
auth?: AuthService;
discovery: DiscoveryService;
tokenManager?: TokenManager;
/**
* @deprecated Use the config key `search.collators.catalog.locationTemplate` instead.
*/
locationTemplate?: string;
/**
* @deprecated Use the config key `search.collators.catalog.filter` instead.
*/
filter?: GetEntitiesRequest['filter'];
/**
* @deprecated Use the config key `search.collators.catalog.batchSize` instead.
*/
batchSize?: number;
// TODO(freben): Change to required CatalogService instead when fully migrated to the new backend system.
catalogClient?: CatalogApi;
/**
auth: AuthService;
catalog: CatalogService;
/*
* Allows you to customize how entities are shaped into documents.
*/
entityTransformer?: CatalogCollatorEntityTransformer;
@@ -65,9 +39,6 @@ export type DefaultCatalogCollatorFactoryOptions = {
/**
* Collates entities from the Catalog into documents for the search backend.
*
* @public
* @deprecated Migrate to the {@link https://backstage.io/docs/backend-system/building-backends/migrating | new backend system} and install this collator via module instead (see {@link https://github.com/backstage/backstage/blob/nbs10/search-deprecate-create-router/plugins/search-backend-module-catalog/README.md#installation | here} for more installation details).
*/
export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory {
public readonly type = 'software-catalog';
@@ -75,9 +46,9 @@ export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory {
catalogEntityReadPermission;
private locationTemplate: string;
private filter?: GetEntitiesRequest['filter'];
private filter?: QueryEntitiesInitialRequest['filter'];
private batchSize: number;
private readonly catalogClient: CatalogApi;
private readonly catalog: CatalogService;
private entityTransformer: CatalogCollatorEntityTransformer;
private auth: AuthService;
@@ -86,47 +57,37 @@ export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory {
options: DefaultCatalogCollatorFactoryOptions,
) {
const configOptions = readCollatorConfigOptions(configRoot);
const { auth: adaptedAuth } = createLegacyAuthAdapters({
auth: options.auth,
discovery: options.discovery,
tokenManager: options.tokenManager,
});
return new DefaultCatalogCollatorFactory({
locationTemplate:
options.locationTemplate ?? configOptions.locationTemplate,
filter: options.filter ?? configOptions.filter,
batchSize: options.batchSize ?? configOptions.batchSize,
locationTemplate: configOptions.locationTemplate,
filter: configOptions.filter,
batchSize: configOptions.batchSize,
entityTransformer: options.entityTransformer,
auth: adaptedAuth,
discovery: options.discovery,
catalogClient: options.catalogClient,
auth: options.auth,
catalog: options.catalog,
});
}
private constructor(options: {
locationTemplate: string;
filter: GetEntitiesRequest['filter'];
filter: QueryEntitiesInitialRequest['filter'];
batchSize: number;
entityTransformer?: CatalogCollatorEntityTransformer;
auth: AuthService;
discovery: DiscoveryService;
catalogClient?: CatalogApi;
catalog: CatalogService;
}) {
const {
auth,
batchSize,
discovery,
locationTemplate,
filter,
catalogClient,
catalog,
entityTransformer,
} = options;
this.locationTemplate = locationTemplate;
this.filter = filter;
this.batchSize = batchSize;
this.catalogClient =
catalogClient || new CatalogClient({ discoveryApi: discovery });
this.catalog = catalog;
this.entityTransformer =
entityTransformer ?? defaultCatalogCollatorEntityTransformer;
this.auth = auth;
@@ -141,17 +102,13 @@ export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory {
let cursor: string | undefined = undefined;
do {
const { token } = await this.auth.getPluginRequestToken({
onBehalfOf: await this.auth.getOwnServiceCredentials(),
targetPluginId: 'catalog',
});
const response = await this.catalogClient.queryEntities(
const response = await this.catalog.queryEntities(
{
filter: this.filter,
limit: this.batchSize,
...(cursor ? { cursor } : {}),
},
{ token },
{ credentials: await this.auth.getOwnServiceCredentials() },
);
cursor = response.pageInfo.nextCursor;
entitiesRetrieved += response.items.length;
@@ -14,8 +14,5 @@
* limitations under the License.
*/
export { DefaultCatalogCollatorFactory } from './DefaultCatalogCollatorFactory';
export type { DefaultCatalogCollatorFactoryOptions } from './DefaultCatalogCollatorFactory';
export { defaultCatalogCollatorEntityTransformer } from './defaultCatalogCollatorEntityTransformer';
export type { CatalogCollatorEntityTransformer } from './CatalogCollatorEntityTransformer';
@@ -16,9 +16,13 @@
/**
* @packageDocumentation
*
* A module for the search backend that exports Catalog modules.
*/
export * from './module';
export { default } from './module';
export {
type CatalogCollatorExtensionPoint,
catalogCollatorExtensionPoint,
searchBackendModule as default,
} from './module';
export * from './collators';
@@ -16,7 +16,7 @@
import { mockServices, startTestBackend } from '@backstage/backend-test-utils';
import { searchIndexRegistryExtensionPoint } from '@backstage/plugin-search-backend-node/alpha';
import searchModuleCatalogCollator from './module';
import { searchBackendModule } from './module';
describe('searchModuleCatalogCollator', () => {
it('should register the catalog collator to the search index registry extension point with factory and schedule', async () => {
@@ -28,7 +28,7 @@ describe('searchModuleCatalogCollator', () => {
extensionPoints: [
[searchIndexRegistryExtensionPoint, extensionPointMock],
],
features: [searchModuleCatalogCollator],
features: [searchBackendModule],
});
expect(extensionPointMock.addCollator).toHaveBeenCalledTimes(1);
@@ -50,7 +50,7 @@ describe('searchModuleCatalogCollator', () => {
],
],
features: [
searchModuleCatalogCollator,
searchBackendModule,
mockServices.rootConfig.factory({
data: {
search: {
@@ -16,7 +16,8 @@
/**
* @packageDocumentation
* A module for the search backend that exports Catalog modules.
*
* A collator module for the search backend that indexes your software catalog.
*/
import {
@@ -24,13 +25,11 @@ import {
createBackendModule,
createExtensionPoint,
} from '@backstage/backend-plugin-api';
import { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';
import {
CatalogCollatorEntityTransformer,
DefaultCatalogCollatorFactory,
} from '@backstage/plugin-search-backend-module-catalog';
import { catalogServiceRef } from '@backstage/plugin-catalog-node';
import { searchIndexRegistryExtensionPoint } from '@backstage/plugin-search-backend-node/alpha';
import { readScheduleConfigOptions } from './collators/config';
import { CatalogCollatorEntityTransformer } from './collators';
import { DefaultCatalogCollatorFactory } from './collators/DefaultCatalogCollatorFactory';
/**
* Options for {@link catalogCollatorExtensionPoint}.
@@ -60,7 +59,7 @@ export const catalogCollatorExtensionPoint =
*
* @public
*/
export default createBackendModule({
export const searchBackendModule = createBackendModule({
pluginId: 'search',
moduleId: 'catalog-collator',
register(env) {
@@ -79,28 +78,19 @@ export default createBackendModule({
deps: {
auth: coreServices.auth,
config: coreServices.rootConfig,
discovery: coreServices.discovery,
scheduler: coreServices.scheduler,
indexRegistry: searchIndexRegistryExtensionPoint,
catalog: catalogServiceRef,
},
async init({
auth,
config,
discovery,
scheduler,
indexRegistry,
catalog,
}) {
async init({ auth, config, scheduler, indexRegistry, catalog }) {
indexRegistry.addCollator({
schedule: scheduler.createScheduledTaskRunner(
readScheduleConfigOptions(config),
),
factory: DefaultCatalogCollatorFactory.fromConfig(config, {
auth,
catalog,
entityTransformer,
discovery,
catalogClient: catalog,
}),
});
},