diff --git a/plugins/catalog-backend/api-report.md b/plugins/catalog-backend/api-report.md index 5b5700e921..fb27a2cc2a 100644 --- a/plugins/catalog-backend/api-report.md +++ b/plugins/catalog-backend/api-report.md @@ -819,7 +819,7 @@ export type EntitiesCatalog = { outputEntities?: boolean; }, ): Promise; - entityAncestry(entityRef: EntityName): Promise; + entityAncestry(entityRef: string): Promise; }; // Warning: (ae-missing-release-tag) "EntitiesRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -858,10 +858,10 @@ function entity( // @public (undocumented) export type EntityAncestryResponse = { - root: EntityName; + rootEntityRef: string; items: Array<{ entity: Entity; - parents: EntityName[]; + parentEntityRefs: string[]; }>; }; diff --git a/plugins/catalog-backend/src/catalog/types.ts b/plugins/catalog-backend/src/catalog/types.ts index 66364e3f23..217e077434 100644 --- a/plugins/catalog-backend/src/catalog/types.ts +++ b/plugins/catalog-backend/src/catalog/types.ts @@ -14,12 +14,7 @@ * limitations under the License. */ -import { - Entity, - EntityName, - EntityRelationSpec, - Location, -} from '@backstage/catalog-model'; +import { Entity, EntityRelationSpec, Location } from '@backstage/catalog-model'; import { EntityFilter, EntityPagination } from '../database/types'; // @@ -58,10 +53,10 @@ export type EntityUpsertResponse = { /** @public */ export type EntityAncestryResponse = { - root: EntityName; + rootEntityRef: string; items: Array<{ entity: Entity; - parents: EntityName[]; + parentEntityRefs: string[]; }>; }; @@ -101,9 +96,9 @@ export type EntitiesCatalog = { /** * Returns the full ancestry tree upward along reference edges. * - * @param entityRef - The root of the tree + * @param entityRef - An entity reference to the root of the tree */ - entityAncestry(entityRef: EntityName): Promise; + entityAncestry(entityRef: string): Promise; }; // diff --git a/plugins/catalog-backend/src/next/NextEntitiesCatalog.test.ts b/plugins/catalog-backend/src/next/NextEntitiesCatalog.test.ts index cc3801aece..c173c926e8 100644 --- a/plugins/catalog-backend/src/next/NextEntitiesCatalog.test.ts +++ b/plugins/catalog-backend/src/next/NextEntitiesCatalog.test.ts @@ -16,6 +16,8 @@ import { TestDatabaseId, TestDatabases } from '@backstage/backend-test-utils'; import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; +import { Knex } from 'knex'; +import { v4 as uuid } from 'uuid'; import { DatabaseManager } from './database/DatabaseManager'; import { DbFinalEntitiesRow, @@ -23,8 +25,6 @@ import { DbRefreshStateRow, } from './database/tables'; import { NextEntitiesCatalog } from './NextEntitiesCatalog'; -import { v4 as uuid } from 'uuid'; -import { Knex } from 'knex'; describe('NextEntitiesCatalog', () => { const databases = TestDatabases.create({ @@ -103,34 +103,24 @@ describe('NextEntitiesCatalog', () => { await addEntity(knex, root, [{ entity: parent }]); const catalog = new NextEntitiesCatalog(knex); - const result = await catalog.entityAncestry({ - kind: 'k', - namespace: 'default', - name: 'root', - }); - expect(result.root).toEqual({ - kind: 'k', - namespace: 'default', - name: 'root', - }); + const result = await catalog.entityAncestry('k:default/root'); + expect(result.rootEntityRef).toEqual('k:default/root'); expect(result.items).toEqual( expect.arrayContaining([ { entity: expect.objectContaining({ metadata: { name: 'root' } }), - parents: [{ kind: 'k', namespace: 'default', name: 'parent' }], + parentEntityRefs: ['k:default/parent'], }, { entity: expect.objectContaining({ metadata: { name: 'parent' } }), - parents: [ - { kind: 'k', namespace: 'default', name: 'grandparent' }, - ], + parentEntityRefs: ['k:default/grandparent'], }, { entity: expect.objectContaining({ metadata: { name: 'grandparent' }, }), - parents: [], + parentEntityRefs: [], }, ]), ); @@ -144,11 +134,7 @@ describe('NextEntitiesCatalog', () => { const { knex } = await createDatabase(databaseId); const catalog = new NextEntitiesCatalog(knex); await expect(() => - catalog.entityAncestry({ - kind: 'k', - namespace: 'default', - name: 'root', - }), + catalog.entityAncestry('k:default/root'), ).rejects.toThrow('No such entity k:default/root'); }, 60_000, @@ -190,47 +176,32 @@ describe('NextEntitiesCatalog', () => { await addEntity(knex, root, [{ entity: parent1 }, { entity: parent2 }]); const catalog = new NextEntitiesCatalog(knex); - const result = await catalog.entityAncestry({ - kind: 'k', - namespace: 'default', - name: 'root', - }); - expect(result.root).toEqual({ - kind: 'k', - namespace: 'default', - name: 'root', - }); + const result = await catalog.entityAncestry('k:default/root'); + expect(result.rootEntityRef).toEqual('k:default/root'); expect(result.items).toEqual( expect.arrayContaining([ { entity: expect.objectContaining({ metadata: { name: 'root' } }), - parents: [ - { kind: 'k', namespace: 'default', name: 'parent1' }, - { kind: 'k', namespace: 'default', name: 'parent2' }, - ], + parentEntityRefs: ['k:default/parent1', 'k:default/parent2'], }, { entity: expect.objectContaining({ metadata: { name: 'parent1' }, }), - parents: [ - { kind: 'k', namespace: 'default', name: 'grandparent' }, - ], + parentEntityRefs: ['k:default/grandparent'], }, { entity: expect.objectContaining({ metadata: { name: 'parent2' }, }), - parents: [ - { kind: 'k', namespace: 'default', name: 'grandparent' }, - ], + parentEntityRefs: ['k:default/grandparent'], }, { entity: expect.objectContaining({ metadata: { name: 'grandparent' }, }), - parents: [], + parentEntityRefs: [], }, ]), ); diff --git a/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts b/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts index 319972a5a9..14fda4ea24 100644 --- a/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts +++ b/plugins/catalog-backend/src/next/NextEntitiesCatalog.ts @@ -14,12 +14,7 @@ * limitations under the License. */ -import { - Entity, - EntityName, - parseEntityRef, - stringifyEntityRef, -} from '@backstage/catalog-model'; +import { Entity, stringifyEntityRef } from '@backstage/catalog-model'; import { InputError, NotFoundError } from '@backstage/errors'; import { Knex } from 'knex'; import { @@ -169,8 +164,7 @@ export class NextEntitiesCatalog implements EntitiesCatalog { .delete(); } - async entityAncestry(entityRef: EntityName): Promise { - const rootRef = stringifyEntityRef(entityRef); + async entityAncestry(rootRef: string): Promise { const [rootRow] = await this.database('refresh_state') .leftJoin('final_entities', { 'refresh_state.entity_id': 'final_entities.entity_id', @@ -187,7 +181,7 @@ export class NextEntitiesCatalog implements EntitiesCatalog { const rootEntity = JSON.parse(rootRow.entityJson) as Entity; const seenEntityRefs = new Set(); const todo = new Array(); - const items = new Array<{ entity: Entity; parents: EntityName[] }>(); + const items = new Array<{ entity: Entity; parentEntityRefs: string[] }>(); for ( let current: Entity | undefined = rootEntity; @@ -213,9 +207,9 @@ export class NextEntitiesCatalog implements EntitiesCatalog { parentEntityJson: 'final_entities.final_entity', }); - const parentRefs: EntityName[] = []; + const parentRefs: string[] = []; for (const { parentEntityRef, parentEntityJson } of parentRows) { - parentRefs.push(parseEntityRef(parentEntityRef)); + parentRefs.push(parentEntityRef); if (!seenEntityRefs.has(parentEntityRef)) { seenEntityRefs.add(parentEntityRef); todo.push(JSON.parse(parentEntityJson)); @@ -224,12 +218,12 @@ export class NextEntitiesCatalog implements EntitiesCatalog { items.push({ entity: current, - parents: parentRefs, + parentEntityRefs: parentRefs, }); } return { - root: entityRef, + rootEntityRef: stringifyEntityRef(rootEntity), items, }; } diff --git a/plugins/catalog-backend/src/next/NextRouter.ts b/plugins/catalog-backend/src/next/NextRouter.ts index 2f3bddf215..6352f96c59 100644 --- a/plugins/catalog-backend/src/next/NextRouter.ts +++ b/plugins/catalog-backend/src/next/NextRouter.ts @@ -18,6 +18,7 @@ import { errorHandler } from '@backstage/backend-common'; import { analyzeLocationSchema, locationSpecSchema, + stringifyEntityRef, } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; import { NotFoundError } from '@backstage/errors'; @@ -129,11 +130,8 @@ export async function createNextRouter( '/entities/by-name/:kind/:namespace/:name/ancestry', async (req, res) => { const { kind, namespace, name } = req.params; - const response = await entitiesCatalog.entityAncestry({ - kind, - namespace, - name, - }); + const entityRef = stringifyEntityRef({ kind, namespace, name }); + const response = await entitiesCatalog.entityAncestry(entityRef); res.status(200).json(response); }, );