diff --git a/.changeset/sad-showers-begin.md b/.changeset/sad-showers-begin.md new file mode 100644 index 0000000000..eccbd9981c --- /dev/null +++ b/.changeset/sad-showers-begin.md @@ -0,0 +1,57 @@ +--- +'@backstage/plugin-catalog-backend': major +--- + +**BREAKING**: Removed all deprecated exports. + +The following removed exports are available from `@backstage/plugin-catalog-node`: + +- `locationSpecToMetadataName` +- `locationSpecToLocationEntity` +- `processingResult` +- `EntitiesSearchFilter` +- `EntityFilter` +- `DeferredEntity` +- `EntityRelationSpec` +- `CatalogProcessor` +- `CatalogProcessorParser` +- `CatalogProcessorCache` +- `CatalogProcessorEmit` +- `CatalogProcessorLocationResult` +- `CatalogProcessorEntityResult` +- `CatalogProcessorRelationResult` +- `CatalogProcessorErrorResult` +- `CatalogProcessorRefreshKeysResult` +- `CatalogProcessorResult` +- `EntityProvider` +- `EntityProviderConnection` +- `EntityProviderMutation` +- `AnalyzeOptions` +- `LocationAnalyzer` +- `ScmLocationAnalyzer` +- `PlaceholderResolver` +- `PlaceholderResolverParams` +- `PlaceholderResolverRead` +- `PlaceholderResolverResolveUrl` + +The following removed exports are available from `@backstage/plugin-catalog-common`: + +- `LocationSpec` +- `AnalyzeLocationRequest` +- `AnalyzeLocationResponse` +- `AnalyzeLocationExistingEntity` +- `AnalyzeLocationGenerateEntity` +- `AnalyzeLocationEntityField` + +The following removed exports are instead implemented in the new backend system by `@backstage/plugin-search-backend-module-catalog`: + +- `defaultCatalogCollatorEntityTransformer` +- `CatalogCollatorEntityTransformer` +- `DefaultCatalogCollator` + +The following exports are removed without a direct replacement: + +- `DefaultCatalogCollatorFactory` +- `DefaultCatalogCollatorFactoryOptions` +- `LocationEntityProcessor` +- `LocationEntityProcessorOptions` diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 930851b350..fb6032342b 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -74,8 +74,6 @@ "@backstage/plugin-events-node": "workspace:^", "@backstage/plugin-permission-common": "workspace:^", "@backstage/plugin-permission-node": "workspace:^", - "@backstage/plugin-search-backend-module-catalog": "workspace:^", - "@backstage/plugin-search-common": "workspace:^", "@backstage/types": "workspace:^", "@opentelemetry/api": "^1.9.0", "@types/express": "^4.17.6", diff --git a/plugins/catalog-backend/report.api.md b/plugins/catalog-backend/report.api.md index 3a47cc4354..e92e688aa4 100644 --- a/plugins/catalog-backend/report.api.md +++ b/plugins/catalog-backend/report.api.md @@ -3,49 +3,26 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { AnalyzeLocationEntityField as AnalyzeLocationEntityField_2 } from '@backstage/plugin-catalog-common'; -import { AnalyzeLocationExistingEntity as AnalyzeLocationExistingEntity_2 } from '@backstage/plugin-catalog-common'; -import { AnalyzeLocationGenerateEntity as AnalyzeLocationGenerateEntity_2 } from '@backstage/plugin-catalog-common'; -import { AnalyzeLocationRequest as AnalyzeLocationRequest_2 } from '@backstage/plugin-catalog-common'; -import { AnalyzeLocationResponse as AnalyzeLocationResponse_2 } from '@backstage/plugin-catalog-common'; -import { AnalyzeOptions as AnalyzeOptions_2 } from '@backstage/plugin-catalog-node'; import { AuditorService } from '@backstage/backend-plugin-api'; 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 { CatalogProcessor as CatalogProcessor_2 } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorCache as CatalogProcessorCache_2 } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorEmit as CatalogProcessorEmit_2 } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorEntityResult as CatalogProcessorEntityResult_2 } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorErrorResult as CatalogProcessorErrorResult_2 } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorLocationResult as CatalogProcessorLocationResult_2 } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorParser as CatalogProcessorParser_2 } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorRefreshKeysResult as CatalogProcessorRefreshKeysResult_2 } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorRelationResult as CatalogProcessorRelationResult_2 } from '@backstage/plugin-catalog-node'; -import { CatalogProcessorResult as CatalogProcessorResult_2 } from '@backstage/plugin-catalog-node'; +import { CatalogProcessor } from '@backstage/plugin-catalog-node'; +import { CatalogProcessorCache } from '@backstage/plugin-catalog-node'; +import { CatalogProcessorEmit } from '@backstage/plugin-catalog-node'; +import { CatalogProcessorParser } from '@backstage/plugin-catalog-node'; +import { CatalogProcessorResult } from '@backstage/plugin-catalog-node'; import { Config } from '@backstage/config'; import { DatabaseService } from '@backstage/backend-plugin-api'; -import { DeferredEntity as DeferredEntity_2 } from '@backstage/plugin-catalog-node'; import { DiscoveryService } from '@backstage/backend-plugin-api'; -import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; -import { EntitiesSearchFilter as EntitiesSearchFilter_2 } from '@backstage/plugin-catalog-node'; +import { EntitiesSearchFilter } from '@backstage/plugin-catalog-node'; import { Entity } from '@backstage/catalog-model'; -import { EntityFilter as EntityFilter_2 } from '@backstage/plugin-catalog-node'; import { EntityPolicy } from '@backstage/catalog-model'; -import { EntityProvider as EntityProvider_2 } from '@backstage/plugin-catalog-node'; -import { EntityProviderConnection as EntityProviderConnection_2 } from '@backstage/plugin-catalog-node'; -import { EntityProviderMutation as EntityProviderMutation_2 } from '@backstage/plugin-catalog-node'; -import { EntityRelationSpec as EntityRelationSpec_2 } from '@backstage/plugin-catalog-node'; +import { EntityProvider } from '@backstage/plugin-catalog-node'; import { EventBroker } from '@backstage/plugin-events-node'; import { EventsService } from '@backstage/plugin-events-node'; -import { GetEntitiesRequest } from '@backstage/catalog-client'; import { HttpAuthService } from '@backstage/backend-plugin-api'; -import { LocationAnalyzer as LocationAnalyzer_2 } from '@backstage/plugin-catalog-node'; -import { LocationSpec as LocationSpec_2 } from '@backstage/plugin-catalog-common'; -import { locationSpecToLocationEntity as locationSpecToLocationEntity_2 } from '@backstage/plugin-catalog-node'; -import { locationSpecToMetadataName as locationSpecToMetadataName_2 } from '@backstage/plugin-catalog-node'; +import { LocationAnalyzer } from '@backstage/plugin-catalog-node'; +import { LocationSpec } from '@backstage/plugin-catalog-common'; import { LoggerService } from '@backstage/backend-plugin-api'; import { Permission } from '@backstage/plugin-permission-common'; import { PermissionAuthorizer } from '@backstage/plugin-permission-common'; @@ -53,54 +30,31 @@ import { PermissionRule } from '@backstage/plugin-permission-node'; import { PermissionRuleParams } from '@backstage/plugin-permission-common'; import { PermissionsRegistryService } from '@backstage/backend-plugin-api'; import { PermissionsService } from '@backstage/backend-plugin-api'; -import { PlaceholderResolver as PlaceholderResolver_2 } from '@backstage/plugin-catalog-node'; -import { PlaceholderResolverParams as PlaceholderResolverParams_2 } from '@backstage/plugin-catalog-node'; -import { PlaceholderResolverRead as PlaceholderResolverRead_2 } from '@backstage/plugin-catalog-node'; -import { PlaceholderResolverResolveUrl as PlaceholderResolverResolveUrl_2 } from '@backstage/plugin-catalog-node'; -import { Readable } from 'stream'; +import { PlaceholderResolver } from '@backstage/plugin-catalog-node'; import { RootConfigService } from '@backstage/backend-plugin-api'; import { Router } from 'express'; import { SchedulerService } from '@backstage/backend-plugin-api'; import { ScmIntegrationRegistry } from '@backstage/integration'; -import { ScmLocationAnalyzer as ScmLocationAnalyzer_2 } from '@backstage/plugin-catalog-node'; -import { TokenManager } from '@backstage/backend-common'; +import { ScmLocationAnalyzer } from '@backstage/plugin-catalog-node'; import { UrlReaderService } from '@backstage/backend-plugin-api'; import { Validators } from '@backstage/catalog-model'; -// @public @deprecated -export type AnalyzeLocationEntityField = AnalyzeLocationEntityField_2; - -// @public @deprecated -export type AnalyzeLocationExistingEntity = AnalyzeLocationExistingEntity_2; - -// @public @deprecated -export type AnalyzeLocationGenerateEntity = AnalyzeLocationGenerateEntity_2; - -// @public @deprecated (undocumented) -export type AnalyzeLocationRequest = AnalyzeLocationRequest_2; - -// @public @deprecated (undocumented) -export type AnalyzeLocationResponse = AnalyzeLocationResponse_2; - -// @public @deprecated (undocumented) -export type AnalyzeOptions = AnalyzeOptions_2; - // @public (undocumented) -export class AnnotateLocationEntityProcessor implements CatalogProcessor_2 { +export class AnnotateLocationEntityProcessor implements CatalogProcessor { constructor(options: { integrations: ScmIntegrationRegistry }); // (undocumented) getProcessorName(): string; // (undocumented) preProcessEntity( entity: Entity, - location: LocationSpec_2, - _: CatalogProcessorEmit_2, - originLocation: LocationSpec_2, + location: LocationSpec, + _: CatalogProcessorEmit, + originLocation: LocationSpec, ): Promise; } // @public (undocumented) -export class AnnotateScmSlugEntityProcessor implements CatalogProcessor_2 { +export class AnnotateScmSlugEntityProcessor implements CatalogProcessor { constructor(opts: { scmIntegrationRegistry: ScmIntegrationRegistry; kinds?: string[]; @@ -115,18 +69,18 @@ export class AnnotateScmSlugEntityProcessor implements CatalogProcessor_2 { // (undocumented) getProcessorName(): string; // (undocumented) - preProcessEntity(entity: Entity, location: LocationSpec_2): Promise; + preProcessEntity(entity: Entity, location: LocationSpec): Promise; } // @public (undocumented) -export class BuiltinKindsEntityProcessor implements CatalogProcessor_2 { +export class BuiltinKindsEntityProcessor implements CatalogProcessor { // (undocumented) getProcessorName(): string; // (undocumented) postProcessEntity( entity: Entity, - _location: LocationSpec_2, - emit: CatalogProcessorEmit_2, + _location: LocationSpec, + emit: CatalogProcessorEmit, ): Promise; // (undocumented) validateEntityKind(entity: Entity): Promise; @@ -144,10 +98,10 @@ export class CatalogBuilder { ...policies: Array> ): CatalogBuilder; addEntityProvider( - ...providers: Array> + ...providers: Array> ): CatalogBuilder; addLocationAnalyzers( - ...analyzers: Array> + ...analyzers: Array> ): CatalogBuilder; addPermissionRules( ...permissionRules: Array< @@ -156,24 +110,24 @@ export class CatalogBuilder { ): this; addPermissions(...permissions: Array>): this; addProcessor( - ...processors: Array> + ...processors: Array> ): CatalogBuilder; build(): Promise<{ processingEngine: CatalogProcessingEngine; router: Router; }>; static create(env: CatalogEnvironment): CatalogBuilder; - getDefaultProcessors(): CatalogProcessor_2[]; + getDefaultProcessors(): CatalogProcessor[]; replaceEntityPolicies(policies: EntityPolicy[]): CatalogBuilder; - replaceProcessors(processors: CatalogProcessor_2[]): CatalogBuilder; + replaceProcessors(processors: CatalogProcessor[]): CatalogBuilder; setAllowedLocationTypes(allowedLocationTypes: string[]): CatalogBuilder; - setEntityDataParser(parser: CatalogProcessorParser_2): CatalogBuilder; + setEntityDataParser(parser: CatalogProcessorParser): CatalogBuilder; setEventBroker(broker: EventBroker | EventsService): CatalogBuilder; setFieldFormatValidators(validators: Partial): CatalogBuilder; - setLocationAnalyzer(locationAnalyzer: LocationAnalyzer_2): CatalogBuilder; + setLocationAnalyzer(locationAnalyzer: LocationAnalyzer): CatalogBuilder; setPlaceholderResolver( key: string, - resolver: PlaceholderResolver_2, + resolver: PlaceholderResolver, ): CatalogBuilder; setProcessingInterval( processingInterval: ProcessingIntervalFunction, @@ -189,10 +143,6 @@ export class CatalogBuilder { useLegacySingleProcessorValidation(): this; } -// @public @deprecated (undocumented) -export type CatalogCollatorEntityTransformer = - CatalogCollatorEntityTransformer_2; - // @public @deprecated (undocumented) export type CatalogEnvironment = { logger: LoggerService; @@ -211,7 +161,7 @@ export type CatalogEnvironment = { // @public export type CatalogPermissionRuleInput< TParams extends PermissionRuleParams = PermissionRuleParams, -> = PermissionRule; +> = PermissionRule; // @public const catalogPlugin: BackendFeature; @@ -225,39 +175,8 @@ export interface CatalogProcessingEngine { stop(): Promise; } -// @public @deprecated (undocumented) -export type CatalogProcessor = CatalogProcessor_2; - -// @public @deprecated (undocumented) -export type CatalogProcessorCache = CatalogProcessorCache_2; - -// @public @deprecated (undocumented) -export type CatalogProcessorEmit = CatalogProcessorEmit_2; - -// @public @deprecated (undocumented) -export type CatalogProcessorEntityResult = CatalogProcessorEntityResult_2; - -// @public @deprecated (undocumented) -export type CatalogProcessorErrorResult = CatalogProcessorErrorResult_2; - -// @public @deprecated (undocumented) -export type CatalogProcessorLocationResult = CatalogProcessorLocationResult_2; - -// @public @deprecated (undocumented) -export type CatalogProcessorParser = CatalogProcessorParser_2; - -// @public @deprecated (undocumented) -export type CatalogProcessorRefreshKeysResult = - CatalogProcessorRefreshKeysResult_2; - -// @public @deprecated (undocumented) -export type CatalogProcessorRelationResult = CatalogProcessorRelationResult_2; - -// @public @deprecated (undocumented) -export type CatalogProcessorResult = CatalogProcessorResult_2; - // @public (undocumented) -export class CodeOwnersProcessor implements CatalogProcessor_2 { +export class CodeOwnersProcessor implements CatalogProcessor { constructor(options: { integrations: ScmIntegrationRegistry; logger: LoggerService; @@ -274,7 +193,7 @@ export class CodeOwnersProcessor implements CatalogProcessor_2 { // (undocumented) getProcessorName(): string; // (undocumented) - preProcessEntity(entity: Entity, location: LocationSpec_2): Promise; + preProcessEntity(entity: Entity, location: LocationSpec): Promise; } // @public @@ -283,218 +202,55 @@ export function createRandomProcessingInterval(options: { maxSeconds: number; }): ProcessingIntervalFunction; -// @public @deprecated (undocumented) -export class DefaultCatalogCollator { - constructor(options: { - discovery: DiscoveryService; - tokenManager: TokenManager; - locationTemplate?: string; - filter?: GetEntitiesRequest['filter']; - catalogClient?: CatalogApi; - }); - // (undocumented) - protected applyArgsToFormat( - format: string, - args: Record, - ): string; - // (undocumented) - protected readonly catalogClient: CatalogApi; - // (undocumented) - protected discovery: DiscoveryService; - // (undocumented) - execute(): Promise; - // (undocumented) - protected filter?: GetEntitiesRequest['filter']; - // (undocumented) - static fromConfig( - _config: Config, - options: { - discovery: DiscoveryService; - tokenManager: TokenManager; - filter?: GetEntitiesRequest['filter']; - }, - ): DefaultCatalogCollator; - // (undocumented) - protected locationTemplate: string; - // (undocumented) - protected tokenManager: TokenManager; - // (undocumented) - readonly type: string; - // (undocumented) - readonly visibilityPermission: Permission; -} - -// @public @deprecated (undocumented) -export const defaultCatalogCollatorEntityTransformer: CatalogCollatorEntityTransformer_2; - -// @public @deprecated (undocumented) -export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory { - // (undocumented) - static fromConfig( - configRoot: Config, - options: DefaultCatalogCollatorFactoryOptions, - ): DefaultCatalogCollatorFactory; - // (undocumented) - getCollator(): Promise; - // (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 @deprecated (undocumented) -export type DeferredEntity = DeferredEntity_2; - -// @public @deprecated (undocumented) -export type EntitiesSearchFilter = EntitiesSearchFilter_2; - -// @public @deprecated (undocumented) -export type EntityFilter = EntityFilter_2; - -// @public @deprecated (undocumented) -export type EntityProvider = EntityProvider_2; - -// @public @deprecated (undocumented) -export type EntityProviderConnection = EntityProviderConnection_2; - -// @public @deprecated (undocumented) -export type EntityProviderMutation = EntityProviderMutation_2; - -// @public @deprecated (undocumented) -export type EntityRelationSpec = EntityRelationSpec_2; - // @public (undocumented) -export class FileReaderProcessor implements CatalogProcessor_2 { +export class FileReaderProcessor implements CatalogProcessor { // (undocumented) getProcessorName(): string; // (undocumented) readLocation( - location: LocationSpec_2, + location: LocationSpec, optional: boolean, - emit: CatalogProcessorEmit_2, - parser: CatalogProcessorParser_2, + emit: CatalogProcessorEmit, + parser: CatalogProcessorParser, ): Promise; } -// @public @deprecated (undocumented) -export type LocationAnalyzer = LocationAnalyzer_2; - -// @public @deprecated -export class LocationEntityProcessor implements CatalogProcessor_2 { - constructor(options: LocationEntityProcessorOptions); - // (undocumented) - getProcessorName(): string; - // (undocumented) - postProcessEntity( - entity: Entity, - location: LocationSpec_2, - emit: CatalogProcessorEmit_2, - ): Promise; -} - -// @public @deprecated (undocumented) -export type LocationEntityProcessorOptions = { - integrations: ScmIntegrationRegistry; -}; - -// @public @deprecated -export type LocationSpec = LocationSpec_2; - -// @public @deprecated (undocumented) -export const locationSpecToLocationEntity: typeof locationSpecToLocationEntity_2; - -// @public @deprecated (undocumented) -export const locationSpecToMetadataName: typeof locationSpecToMetadataName_2; - // @public (undocumented) export function parseEntityYaml( data: Buffer, - location: LocationSpec_2, -): Iterable; + location: LocationSpec, +): Iterable; // @public -export class PlaceholderProcessor implements CatalogProcessor_2 { +export class PlaceholderProcessor implements CatalogProcessor { constructor(options: PlaceholderProcessorOptions); // (undocumented) getProcessorName(): string; // (undocumented) preProcessEntity( entity: Entity, - location: LocationSpec_2, - emit: CatalogProcessorEmit_2, + location: LocationSpec, + emit: CatalogProcessorEmit, ): Promise; } // @public (undocumented) export type PlaceholderProcessorOptions = { - resolvers: Record; + resolvers: Record; reader: UrlReaderService; integrations: ScmIntegrationRegistry; }; -// @public @deprecated (undocumented) -export type PlaceholderResolver = PlaceholderResolver_2; - -// @public @deprecated (undocumented) -export type PlaceholderResolverParams = PlaceholderResolverParams_2; - -// @public @deprecated (undocumented) -export type PlaceholderResolverRead = PlaceholderResolverRead_2; - -// @public @deprecated (undocumented) -export type PlaceholderResolverResolveUrl = PlaceholderResolverResolveUrl_2; - // @public export type ProcessingIntervalFunction = () => number; -// @public @deprecated (undocumented) -export const processingResult: Readonly<{ - readonly notFoundError: ( - atLocation: LocationSpec_2, - message: string, - ) => CatalogProcessorResult_2; - readonly inputError: ( - atLocation: LocationSpec_2, - message: string, - ) => CatalogProcessorResult_2; - readonly generalError: ( - atLocation: LocationSpec_2, - message: string, - ) => CatalogProcessorResult_2; - readonly location: (newLocation: LocationSpec_2) => CatalogProcessorResult_2; - readonly entity: ( - atLocation: LocationSpec_2, - newEntity: Entity, - options?: { - locationKey?: string | null; - }, - ) => CatalogProcessorResult_2; - readonly relation: (spec: EntityRelationSpec_2) => CatalogProcessorResult_2; - readonly refresh: (key: string) => CatalogProcessorResult_2; -}>; - -// @public @deprecated (undocumented) -export type ScmLocationAnalyzer = ScmLocationAnalyzer_2; - // @public export function transformLegacyPolicyToProcessor( policy: EntityPolicy, -): CatalogProcessor_2; +): CatalogProcessor; // @public (undocumented) -export class UrlReaderProcessor implements CatalogProcessor_2 { +export class UrlReaderProcessor implements CatalogProcessor { constructor(options: { reader: UrlReaderService; logger: LoggerService; @@ -504,11 +260,11 @@ export class UrlReaderProcessor implements CatalogProcessor_2 { getProcessorName(): string; // (undocumented) readLocation( - location: LocationSpec_2, + location: LocationSpec, optional: boolean, - emit: CatalogProcessorEmit_2, - parser: CatalogProcessorParser_2, - cache: CatalogProcessorCache_2, + emit: CatalogProcessorEmit, + parser: CatalogProcessorParser, + cache: CatalogProcessorCache, ): Promise; } ``` diff --git a/plugins/catalog-backend/src/deprecated.ts b/plugins/catalog-backend/src/deprecated.ts deleted file mode 100644 index 023e93e664..0000000000 --- a/plugins/catalog-backend/src/deprecated.ts +++ /dev/null @@ -1,502 +0,0 @@ -/* - * Copyright 2023 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 { - TokenManager, - createLegacyAuthAdapters, -} from '@backstage/backend-common'; -import { AuthService, DiscoveryService } from '@backstage/backend-plugin-api'; -import { - CatalogApi, - CatalogClient, - EntityFilterQuery, - GetEntitiesRequest, -} from '@backstage/catalog-client'; -import { - Entity, - isGroupEntity, - isUserEntity, - stringifyEntityRef, -} from '@backstage/catalog-model'; -import { Config } from '@backstage/config'; -import { - CatalogEntityDocument, - type AnalyzeLocationEntityField as _AnalyzeLocationEntityField, - type AnalyzeLocationExistingEntity as _AnalyzeLocationExistingEntity, - type AnalyzeLocationGenerateEntity as _AnalyzeLocationGenerateEntity, - type AnalyzeLocationRequest as _AnalyzeLocationRequest, - type AnalyzeLocationResponse as _AnalyzeLocationResponse, - type LocationSpec as _LocationSpec, -} from '@backstage/plugin-catalog-common'; -import { catalogEntityReadPermission } from '@backstage/plugin-catalog-common/alpha'; -import { - locationSpecToMetadataName as _locationSpecToMetadataName, - locationSpecToLocationEntity as _locationSpecToLocationEntity, - processingResult as _processingResult, - type EntitiesSearchFilter as _EntitiesSearchFilter, - type EntityFilter as _EntityFilter, - type DeferredEntity as _DeferredEntity, - type EntityRelationSpec as _EntityRelationSpec, - type CatalogProcessor as _CatalogProcessor, - type CatalogProcessorParser as _CatalogProcessorParser, - type CatalogProcessorCache as _CatalogProcessorCache, - type CatalogProcessorEmit as _CatalogProcessorEmit, - type CatalogProcessorLocationResult as _CatalogProcessorLocationResult, - type CatalogProcessorEntityResult as _CatalogProcessorEntityResult, - type CatalogProcessorRelationResult as _CatalogProcessorRelationResult, - type CatalogProcessorErrorResult as _CatalogProcessorErrorResult, - type CatalogProcessorRefreshKeysResult as _CatalogProcessorRefreshKeysResult, - type CatalogProcessorResult as _CatalogProcessorResult, - type EntityProvider as _EntityProvider, - type EntityProviderConnection as _EntityProviderConnection, - type EntityProviderMutation as _EntityProviderMutation, - type AnalyzeOptions as _AnalyzeOptions, - type PlaceholderResolver as _PlaceholderResolver, - type PlaceholderResolverParams as _PlaceholderResolverParams, - type PlaceholderResolverRead as _PlaceholderResolverRead, - type PlaceholderResolverResolveUrl as _PlaceholderResolverResolveUrl, - type LocationAnalyzer as _LocationAnalyzer, - type ScmLocationAnalyzer as _ScmLocationAnalyzer, -} from '@backstage/plugin-catalog-node'; -import { Permission } from '@backstage/plugin-permission-common'; -import { - defaultCatalogCollatorEntityTransformer as _defaultCatalogCollatorEntityTransformer, - type CatalogCollatorEntityTransformer as _CatalogCollatorEntityTransformer, -} from '@backstage/plugin-search-backend-module-catalog'; -import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; -import { Readable } from 'stream'; - -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export const locationSpecToMetadataName = _locationSpecToMetadataName; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export const locationSpecToLocationEntity = _locationSpecToLocationEntity; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export const processingResult = _processingResult; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type EntitiesSearchFilter = _EntitiesSearchFilter; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type EntityFilter = _EntityFilter; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type DeferredEntity = _DeferredEntity; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type EntityRelationSpec = _EntityRelationSpec; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessor = _CatalogProcessor; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessorParser = _CatalogProcessorParser; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessorCache = _CatalogProcessorCache; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessorEmit = _CatalogProcessorEmit; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessorLocationResult = _CatalogProcessorLocationResult; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessorEntityResult = _CatalogProcessorEntityResult; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessorRelationResult = _CatalogProcessorRelationResult; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessorErrorResult = _CatalogProcessorErrorResult; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessorRefreshKeysResult = - _CatalogProcessorRefreshKeysResult; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type CatalogProcessorResult = _CatalogProcessorResult; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type EntityProvider = _EntityProvider; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type EntityProviderConnection = _EntityProviderConnection; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type EntityProviderMutation = _EntityProviderMutation; - -/** - * Holds the entity location information. - * - * @remarks - * - * `presence` flag: when using repo importer plugin, location is being created before the component yaml file is merged to the main branch. - * This flag is then set to indicate that the file can be not present. - * default value: 'required'. - * - * @public - * @deprecated use the same type from `@backstage/plugin-catalog-common` instead - */ -export type LocationSpec = _LocationSpec; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type AnalyzeOptions = _AnalyzeOptions; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type LocationAnalyzer = _LocationAnalyzer; -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type ScmLocationAnalyzer = _ScmLocationAnalyzer; - -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type PlaceholderResolver = _PlaceholderResolver; - -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type PlaceholderResolverParams = _PlaceholderResolverParams; - -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type PlaceholderResolverRead = _PlaceholderResolverRead; - -/** - * @public - * @deprecated import from `@backstage/plugin-catalog-node` instead - */ -export type PlaceholderResolverResolveUrl = _PlaceholderResolverResolveUrl; - -/** - * @public - * @deprecated use the same type from `@backstage/plugin-catalog-common` instead - */ -export type AnalyzeLocationRequest = _AnalyzeLocationRequest; -/** - * @public - * @deprecated use the same type from `@backstage/plugin-catalog-common` instead - */ -export type AnalyzeLocationResponse = _AnalyzeLocationResponse; - -/** - * If the folder pointed to already contained catalog info yaml files, they are - * read and emitted like this so that the frontend can inform the user that it - * located them and can make sure to register them as well if they weren't - * already - * @public - * @deprecated use the same type from `@backstage/plugin-catalog-common` instead - */ -export type AnalyzeLocationExistingEntity = _AnalyzeLocationExistingEntity; -/** - * This is some form of representation of what the analyzer could deduce. - * We should probably have a chat about how this can best be conveyed to - * the frontend. It'll probably contain a (possibly incomplete) entity, plus - * enough info for the frontend to know what form data to show to the user - * for overriding/completing the info. - * @public - * @deprecated use the same type from `@backstage/plugin-catalog-common` instead - */ -export type AnalyzeLocationGenerateEntity = _AnalyzeLocationGenerateEntity; - -/** - * - * This is where I get really vague. Something like this perhaps? Or it could be - * something like a json-schema that contains enough info for the frontend to - * be able to present a form and explanations - * @public - * @deprecated use the same type from `@backstage/plugin-catalog-common` instead - */ -export type AnalyzeLocationEntityField = _AnalyzeLocationEntityField; - -namespace search { - const configKey = 'search.collators.catalog'; - - const defaults = { - schedule: { - frequency: { minutes: 10 }, - timeout: { minutes: 15 }, - initialDelay: { seconds: 3 }, - }, - collatorOptions: { - locationTemplate: '/catalog/:namespace/:kind/:name', - filter: undefined, - batchSize: 500, - }, - }; - - export const readCollatorConfigOptions = ( - configRoot: Config, - ): { - locationTemplate: string; - filter: EntityFilterQuery | undefined; - batchSize: number; - } => { - const config = configRoot.getOptionalConfig(configKey); - if (!config) { - return defaults.collatorOptions; - } - - return { - locationTemplate: - config.getOptionalString('locationTemplate') ?? - defaults.collatorOptions.locationTemplate, - filter: - config.getOptional('filter') ?? - defaults.collatorOptions.filter, - batchSize: - config.getOptionalNumber('batchSize') ?? - defaults.collatorOptions.batchSize, - }; - }; - - export const getDocumentText = (entity: Entity): string => { - const documentTexts: string[] = []; - if (entity.metadata.description) { - documentTexts.push(entity.metadata.description); - } - - if (isUserEntity(entity) || isGroupEntity(entity)) { - if (entity.spec?.profile?.displayName) { - documentTexts.push(entity.spec.profile.displayName); - } - } - - if (isUserEntity(entity)) { - if (entity.spec?.profile?.email) { - documentTexts.push(entity.spec.profile.email); - } - } - - return documentTexts.join(' : '); - }; -} - -/** - * @public - * @deprecated import from `@backstage/plugin-search-backend-module-catalog` instead - */ -export const defaultCatalogCollatorEntityTransformer = - _defaultCatalogCollatorEntityTransformer; - -/** - * @public - * @deprecated This is no longer supported since the new backend system migration - */ -export class DefaultCatalogCollatorFactory implements DocumentCollatorFactory { - public readonly type = 'software-catalog'; - public readonly visibilityPermission: Permission = - catalogEntityReadPermission; - - private locationTemplate: string; - private filter?: GetEntitiesRequest['filter']; - private batchSize: number; - private readonly catalogClient: CatalogApi; - private entityTransformer: CatalogCollatorEntityTransformer; - private auth: AuthService; - - static fromConfig( - configRoot: Config, - options: DefaultCatalogCollatorFactoryOptions, - ) { - const configOptions = search.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, - entityTransformer: options.entityTransformer, - auth: adaptedAuth, - discovery: options.discovery, - catalogClient: options.catalogClient, - }); - } - - private constructor(options: { - locationTemplate: string; - filter: GetEntitiesRequest['filter']; - batchSize: number; - entityTransformer?: CatalogCollatorEntityTransformer; - auth: AuthService; - discovery: DiscoveryService; - catalogClient?: CatalogApi; - }) { - const { - auth, - batchSize, - discovery, - locationTemplate, - filter, - catalogClient, - entityTransformer, - } = options; - - this.locationTemplate = locationTemplate; - this.filter = filter; - this.batchSize = batchSize; - this.catalogClient = - catalogClient || new CatalogClient({ discoveryApi: discovery }); - this.entityTransformer = - entityTransformer ?? defaultCatalogCollatorEntityTransformer; - this.auth = auth; - } - - async getCollator(): Promise { - return Readable.from(this.execute()); - } - - private async *execute(): AsyncGenerator { - let entitiesRetrieved = 0; - 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( - { - filter: this.filter, - limit: this.batchSize, - ...(cursor ? { cursor } : {}), - }, - { token }, - ); - cursor = response.pageInfo.nextCursor; - entitiesRetrieved += response.items.length; - - for (const entity of response.items) { - yield { - ...this.entityTransformer(entity), - authorization: { - resourceRef: stringifyEntityRef(entity), - }, - location: this.applyArgsToFormat(this.locationTemplate, { - namespace: entity.metadata.namespace || 'default', - kind: entity.kind, - name: entity.metadata.name, - }), - }; - } - } while (cursor); - } - - private applyArgsToFormat( - format: string, - args: Record, - ): string { - let formatted = format; - - for (const [key, value] of Object.entries(args)) { - formatted = formatted.replace(`:${key}`, value); - } - - return formatted.toLowerCase(); - } -} - -/** - * @public - * @deprecated This is no longer supported since the new backend system migration - */ -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; - /** - * Allows you to customize how entities are shaped into documents. - */ - entityTransformer?: CatalogCollatorEntityTransformer; -}; - -/** - * @public - * @deprecated import from `@backstage/plugin-search-backend-module-catalog` instead - */ -export type CatalogCollatorEntityTransformer = - _CatalogCollatorEntityTransformer; diff --git a/plugins/catalog-backend/src/index.ts b/plugins/catalog-backend/src/index.ts index 3de6cea22e..40235a1724 100644 --- a/plugins/catalog-backend/src/index.ts +++ b/plugins/catalog-backend/src/index.ts @@ -23,8 +23,6 @@ export { catalogPlugin as default } from './service/CatalogPlugin'; export * from './processors'; export * from './processing'; -export * from './search'; export * from './service'; -export * from './deprecated'; export * from './constants'; export * from './util'; diff --git a/plugins/catalog-backend/src/processors/LocationEntityProcessor.test.ts b/plugins/catalog-backend/src/processors/LocationEntityProcessor.test.ts deleted file mode 100644 index 5e000f87d6..0000000000 --- a/plugins/catalog-backend/src/processors/LocationEntityProcessor.test.ts +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2020 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 { ConfigReader } from '@backstage/config'; -import { - ScmIntegrations, - ScmIntegrationRegistry, -} from '@backstage/integration'; -import path from 'path'; -import { toAbsoluteUrl } from './LocationEntityProcessor'; -import { LocationSpec } from '@backstage/plugin-catalog-common'; - -describe('LocationEntityProcessor', () => { - describe('toAbsoluteUrl', () => { - it('handles files', () => { - const integrations = {} as unknown as ScmIntegrationRegistry; - const base: LocationSpec = { - type: 'file', - target: `some${path.sep}path${path.sep}catalog-info.yaml`, - }; - expect(toAbsoluteUrl(integrations, base, `.${path.sep}c`)).toBe( - `some${path.sep}path${path.sep}c`, - ); - expect(toAbsoluteUrl(integrations, base, `${path.sep}c`)).toBe( - `${path.sep}c`, - ); - }); - - it('handles urls', () => { - const integrations = ScmIntegrations.fromConfig(new ConfigReader({})); - const base: LocationSpec = { - type: 'url', - target: 'http://a.com/b/catalog-info.yaml', - }; - jest.spyOn(integrations, 'resolveUrl'); - - expect(toAbsoluteUrl(integrations, base, './c/d')).toBe( - 'http://a.com/b/c/d', - ); - expect(toAbsoluteUrl(integrations, base, 'c/d')).toBe( - 'http://a.com/b/c/d', - ); - expect(toAbsoluteUrl(integrations, base, 'http://b.com/z')).toBe( - 'http://b.com/z', - ); - - expect(integrations.resolveUrl).toHaveBeenCalledTimes(3); - }); - - it('handles azure urls specifically', () => { - const integrations = ScmIntegrations.fromConfig( - new ConfigReader({ - integrations: { - azure: [{ host: 'dev.azure.com' }], - }, - }), - ); - - expect( - toAbsoluteUrl( - integrations, - { - type: 'url', - target: - 'https://dev.azure.com/organization/project/_git/repository?path=%2Fcatalog-info.yaml', - }, - './a.yaml', - ), - ).toBe( - 'https://dev.azure.com/organization/project/_git/repository?path=%2Fa.yaml', - ); - }); - }); -}); diff --git a/plugins/catalog-backend/src/processors/LocationEntityProcessor.ts b/plugins/catalog-backend/src/processors/LocationEntityProcessor.ts deleted file mode 100644 index 7bfd7f33cd..0000000000 --- a/plugins/catalog-backend/src/processors/LocationEntityProcessor.ts +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2020 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 { Entity, LocationEntity } from '@backstage/catalog-model'; -import { ScmIntegrationRegistry } from '@backstage/integration'; -import path from 'path'; -import { LocationSpec } from '@backstage/plugin-catalog-common'; -import { - processingResult, - CatalogProcessor, - CatalogProcessorEmit, -} from '@backstage/plugin-catalog-node'; - -export function toAbsoluteUrl( - integrations: ScmIntegrationRegistry, - base: LocationSpec, - target: string, -): string { - try { - if (base.type === 'file') { - if (target.startsWith('.')) { - return path.join(path.dirname(base.target), target); - } - return target; - } - return integrations.resolveUrl({ url: target, base: base.target }); - } catch (e) { - return target; - } -} - -/** - * @public - * @deprecated This processor should no longer be used - */ -export type LocationEntityProcessorOptions = { - integrations: ScmIntegrationRegistry; -}; - -/** - * Legacy processor, should not be used. - * - * @remarks - * - * In the old catalog architecture, this processor translated Location entities - * into URLs that should be fetched. This is no longer needed since the engine - * handles this internally. - * - * @public - * @deprecated This processor should no longer be used - */ -export class LocationEntityProcessor implements CatalogProcessor { - constructor(private readonly options: LocationEntityProcessorOptions) {} - - getProcessorName(): string { - return 'LocationEntityProcessor'; - } - - async postProcessEntity( - entity: Entity, - location: LocationSpec, - emit: CatalogProcessorEmit, - ): Promise { - if (entity.kind === 'Location') { - const locationEntity = entity as LocationEntity; - - const type = locationEntity.spec.type || location.type; - if (type === 'file' && location.target.endsWith(path.sep)) { - emit( - processingResult.inputError( - location, - `LocationEntityProcessor cannot handle ${type} type location with target ${location.target} that ends with a path separator`, - ), - ); - } - - const targets = new Array(); - if (locationEntity.spec.target) { - targets.push(locationEntity.spec.target); - } - if (locationEntity.spec.targets) { - targets.push(...locationEntity.spec.targets); - } - - for (const maybeRelativeTarget of targets) { - const target = toAbsoluteUrl( - this.options.integrations, - location, - maybeRelativeTarget, - ); - emit(processingResult.location({ type, target })); - } - } - - return entity; - } -} diff --git a/plugins/catalog-backend/src/processors/index.ts b/plugins/catalog-backend/src/processors/index.ts index ee2204f20f..1a43444b1a 100644 --- a/plugins/catalog-backend/src/processors/index.ts +++ b/plugins/catalog-backend/src/processors/index.ts @@ -19,8 +19,6 @@ export { AnnotateScmSlugEntityProcessor } from './AnnotateScmSlugEntityProcessor export { BuiltinKindsEntityProcessor } from './BuiltinKindsEntityProcessor'; export { CodeOwnersProcessor } from './CodeOwnersProcessor'; export { FileReaderProcessor } from './FileReaderProcessor'; -export { LocationEntityProcessor } from './LocationEntityProcessor'; -export type { LocationEntityProcessorOptions } from './LocationEntityProcessor'; export { PlaceholderProcessor } from './PlaceholderProcessor'; export type { PlaceholderProcessorOptions } from './PlaceholderProcessor'; export { UrlReaderProcessor } from './UrlReaderProcessor'; diff --git a/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts b/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts deleted file mode 100644 index 9473d45bb6..0000000000 --- a/plugins/catalog-backend/src/search/DefaultCatalogCollator.test.ts +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2021 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 { TokenManager } from '@backstage/backend-common'; -import { - mockServices, - registerMswTestHooks, -} from '@backstage/backend-test-utils'; -import { Entity } from '@backstage/catalog-model'; -import { DefaultCatalogCollator } from './DefaultCatalogCollator'; -import { setupServer } from 'msw/node'; -import { rest } from 'msw'; -import { ConfigReader } from '@backstage/config'; - -const server = setupServer(); - -const expectedEntities: Entity[] = [ - { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - name: 'test-entity', - description: 'The expected description', - }, - spec: { - type: 'some-type', - lifecycle: 'experimental', - owner: 'someone', - }, - }, - { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Component', - metadata: { - title: 'Test Entity', - name: 'test-entity-2', - description: 'The expected description 2', - }, - spec: { - type: 'some-type', - lifecycle: 'experimental', - owner: 'someone', - }, - }, -]; - -describe('DefaultCatalogCollator', () => { - const mockDiscovery = mockServices.discovery.mock({ - getBaseUrl: async () => 'http://localhost:7007', - }); - let mockTokenManager: jest.Mocked; - let collator: DefaultCatalogCollator; - - registerMswTestHooks(server); - beforeAll(() => { - mockTokenManager = { - getToken: jest.fn().mockResolvedValue({ token: '' }), - authenticate: jest.fn(), - }; - collator = new DefaultCatalogCollator({ - discovery: mockDiscovery, - tokenManager: mockTokenManager, - }); - }); - beforeEach(() => { - server.use( - rest.get('http://localhost:7007/entities', (req, res, ctx) => { - if (req.url.searchParams.has('filter')) { - const filter = req.url.searchParams.get('filter'); - if (filter === 'kind=Foo,kind=Bar') { - // When filtering on the 'Foo,Bar' kinds we simply return no items, to simulate a filter - return res(ctx.json([])); - } - throw new Error('Unexpected filter parameter'); - } - return res(ctx.json(expectedEntities)); - }), - ); - }); - afterAll(() => { - jest.useRealTimers(); - }); - - it('fetches from the configured catalog service', async () => { - const documents = await collator.execute(); - expect(mockDiscovery.getBaseUrl).toHaveBeenCalledWith('catalog'); - expect(documents).toHaveLength(expectedEntities.length); - }); - - it('maps a returned entity to an expected CatalogEntityDocument', async () => { - const documents = await collator.execute(); - expect(documents[0]).toMatchObject({ - title: expectedEntities[0].metadata.name, - location: '/catalog/default/component/test-entity', - text: expectedEntities[0].metadata.description, - namespace: 'default', - componentType: expectedEntities[0]!.spec!.type, - lifecycle: expectedEntities[0]!.spec!.lifecycle, - owner: expectedEntities[0]!.spec!.owner, - authorization: { - resourceRef: 'component:default/test-entity', - }, - }); - expect(documents[1]).toMatchObject({ - title: `${expectedEntities[1].metadata.title} (${expectedEntities[1].metadata.name})`, - location: '/catalog/default/component/test-entity-2', - text: expectedEntities[1].metadata.description, - namespace: 'default', - componentType: expectedEntities[1]!.spec!.type, - lifecycle: expectedEntities[1]!.spec!.lifecycle, - owner: expectedEntities[1]!.spec!.owner, - authorization: { - resourceRef: 'component:default/test-entity-2', - }, - }); - }); - - it('maps a returned entity with a custom locationTemplate', async () => { - // Provide an alternate location template. - collator = new DefaultCatalogCollator({ - discovery: mockDiscovery, - tokenManager: mockTokenManager, - locationTemplate: '/software/:name', - }); - - const documents = await collator.execute(); - expect(documents[0]).toMatchObject({ - location: '/software/test-entity', - }); - }); - - it('allows filtering of the retrieved catalog entities', async () => { - // Provide an alternate location template. - collator = DefaultCatalogCollator.fromConfig(new ConfigReader({}), { - discovery: mockDiscovery, - tokenManager: mockTokenManager, - filter: { - kind: ['Foo', 'Bar'], - }, - }); - - const documents = await collator.execute(); - // The simulated 'Foo,Bar' filter should return in an empty list - expect(documents).toHaveLength(0); - }); -}); diff --git a/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts b/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts deleted file mode 100644 index 11f6030ce6..0000000000 --- a/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2021 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 { TokenManager } from '@backstage/backend-common'; -import { - Entity, - isUserEntity, - stringifyEntityRef, -} from '@backstage/catalog-model'; -import { Config } from '@backstage/config'; -import { - CatalogApi, - CatalogClient, - GetEntitiesRequest, -} from '@backstage/catalog-client'; -import { catalogEntityReadPermission } from '@backstage/plugin-catalog-common/alpha'; -import { CatalogEntityDocument } from '@backstage/plugin-catalog-common'; -import { Permission } from '@backstage/plugin-permission-common'; -import { DiscoveryService } from '@backstage/backend-plugin-api'; - -/** - * @public - * @deprecated Upgrade to a more recent `@backstage/plugin-search-backend-node` and - * use `DefaultCatalogCollatorFactory` instead. - */ -export class DefaultCatalogCollator { - protected discovery: DiscoveryService; - protected locationTemplate: string; - protected filter?: GetEntitiesRequest['filter']; - protected readonly catalogClient: CatalogApi; - public readonly type: string = 'software-catalog'; - public readonly visibilityPermission: Permission = - catalogEntityReadPermission; - protected tokenManager: TokenManager; - - static fromConfig( - _config: Config, - options: { - discovery: DiscoveryService; - tokenManager: TokenManager; - filter?: GetEntitiesRequest['filter']; - }, - ) { - return new DefaultCatalogCollator({ - ...options, - }); - } - - constructor(options: { - discovery: DiscoveryService; - tokenManager: TokenManager; - locationTemplate?: string; - filter?: GetEntitiesRequest['filter']; - catalogClient?: CatalogApi; - }) { - const { discovery, locationTemplate, filter, catalogClient, tokenManager } = - options; - - this.discovery = discovery; - this.locationTemplate = - locationTemplate || '/catalog/:namespace/:kind/:name'; - this.filter = filter; - this.catalogClient = - catalogClient || new CatalogClient({ discoveryApi: discovery }); - this.tokenManager = tokenManager; - } - - protected applyArgsToFormat( - format: string, - args: Record, - ): string { - let formatted = format; - for (const [key, value] of Object.entries(args)) { - formatted = formatted.replace(`:${key}`, value); - } - return formatted.toLowerCase(); - } - - private getDocumentText(entity: Entity): string { - let documentText = entity.metadata.description || ''; - if (isUserEntity(entity)) { - if (entity.spec?.profile?.displayName && documentText) { - // combine displayName and description - const displayName = entity.spec?.profile?.displayName; - documentText = displayName.concat(' : ', documentText); - } else { - documentText = entity.spec?.profile?.displayName || documentText; - } - } - return documentText; - } - - async execute() { - const { token } = await this.tokenManager.getToken(); - const response = await this.catalogClient.getEntities( - { - filter: this.filter, - }, - { token }, - ); - return response.items.map((entity: Entity): CatalogEntityDocument => { - return { - title: entity.metadata.title - ? `${entity.metadata.title} (${entity.metadata.name})` - : entity.metadata.name, - location: this.applyArgsToFormat(this.locationTemplate, { - namespace: entity.metadata.namespace || 'default', - kind: entity.kind, - name: entity.metadata.name, - }), - text: this.getDocumentText(entity), - componentType: entity.spec?.type?.toString() || 'other', - type: entity.spec?.type?.toString() || 'other', - namespace: entity.metadata.namespace || 'default', - kind: entity.kind, - lifecycle: (entity.spec?.lifecycle as string) || '', - owner: (entity.spec?.owner as string) || '', - authorization: { - resourceRef: stringifyEntityRef(entity), - }, - }; - }); - } -} diff --git a/plugins/catalog-backend/src/search/index.ts b/plugins/catalog-backend/src/search/index.ts deleted file mode 100644 index 50966e4c5b..0000000000 --- a/plugins/catalog-backend/src/search/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2021 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. - */ - -/** - * todo(backstage/techdocs-core): stop exporting this in a future release. - */ -export { DefaultCatalogCollator } from './DefaultCatalogCollator'; diff --git a/yarn.lock b/yarn.lock index a6aa5e382c..9216e2687f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6032,8 +6032,6 @@ __metadata: "@backstage/plugin-events-node": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" "@backstage/plugin-permission-node": "workspace:^" - "@backstage/plugin-search-backend-module-catalog": "workspace:^" - "@backstage/plugin-search-common": "workspace:^" "@backstage/repo-tools": "workspace:^" "@backstage/test-utils": "workspace:^" "@backstage/types": "workspace:^"