switch to using string refs
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
@@ -819,7 +819,7 @@ export type EntitiesCatalog = {
|
||||
outputEntities?: boolean;
|
||||
},
|
||||
): Promise<EntityUpsertResponse[]>;
|
||||
entityAncestry(entityRef: EntityName): Promise<EntityAncestryResponse>;
|
||||
entityAncestry(entityRef: string): Promise<EntityAncestryResponse>;
|
||||
};
|
||||
|
||||
// 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[];
|
||||
}>;
|
||||
};
|
||||
|
||||
|
||||
@@ -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<EntityAncestryResponse>;
|
||||
entityAncestry(entityRef: string): Promise<EntityAncestryResponse>;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
@@ -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: [],
|
||||
},
|
||||
]),
|
||||
);
|
||||
|
||||
@@ -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<EntityAncestryResponse> {
|
||||
const rootRef = stringifyEntityRef(entityRef);
|
||||
async entityAncestry(rootRef: string): Promise<EntityAncestryResponse> {
|
||||
const [rootRow] = await this.database<DbRefreshStateRow>('refresh_state')
|
||||
.leftJoin<DbFinalEntitiesRow>('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<string>();
|
||||
const todo = new Array<Entity>();
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user