switch to using string refs

Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
Fredrik Adelöw
2021-09-29 18:45:58 +02:00
parent c1836728e0
commit 56d244e606
5 changed files with 32 additions and 74 deletions
+3 -3
View File
@@ -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[];
}>;
};
+5 -10
View File
@@ -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);
},
);