catalog-backend: review fixes

This commit is contained in:
Patrik Oldsberg
2020-10-22 17:36:56 +02:00
parent a7478736bd
commit 15278fae30
6 changed files with 34 additions and 41 deletions
@@ -32,8 +32,8 @@ export const RELATION_OWNER_OF = 'ownerOf';
/**
* A relation with an API entity, typically from a component or system
*/
export const RELATION_IMPLEMENTED_BY = 'implementedBy';
export const RELATION_IMPLEMENTS = 'implements';
export const RELATION_CONSUMES_API = 'consumesApi';
export const RELATION_PROVIDES_API = 'providesApi';
/**
* A relation denoting a dependency on another entity.
@@ -18,7 +18,7 @@ import { getVoidLogger } from '@backstage/backend-common';
import type { Entity } from '@backstage/catalog-model';
import { Database, DatabaseManager } from '../database';
import { DatabaseEntitiesCatalog } from './DatabaseEntitiesCatalog';
import { EntityMutationRequest } from './types';
import { EntityUpsertRequest } from './types';
describe('DatabaseEntitiesCatalog', () => {
let db: jest.Mocked<Database>;
@@ -272,8 +272,8 @@ describe('DatabaseEntitiesCatalog', () => {
await DatabaseManager.createTestDatabase(),
getVoidLogger(),
);
const entities: EntityMutationRequest[] = [];
for (let i = 0; i < 200; ++i) {
const entities: EntityUpsertRequest[] = [];
for (let i = 0; i < 300; ++i) {
entities.push({
entity: {
apiVersion: 'a',
@@ -286,21 +286,21 @@ describe('DatabaseEntitiesCatalog', () => {
await catalog.batchAddOrUpdateEntities(entities);
const afterFirst = await catalog.entities();
expect(afterFirst.length).toBe(200);
expect(afterFirst.length).toBe(300);
entities[40].entity.metadata.op = 'changed';
entities.push({
entity: {
apiVersion: 'a',
kind: 'k',
metadata: { name: `n200`, op: 'added' },
metadata: { name: `n300`, op: 'added' },
},
relations: [],
});
await catalog.batchAddOrUpdateEntities(entities);
const afterSecond = await catalog.entities();
expect(afterSecond.length).toBe(201);
expect(afterSecond.length).toBe(301);
expect(afterSecond.find(e => e.metadata.op === 'changed')).toBeDefined();
expect(afterSecond.find(e => e.metadata.op === 'added')).toBeDefined();
}, 10000);
@@ -31,8 +31,8 @@ import type { Database, DbEntityResponse, EntityFilters } from '../database';
import { durationText } from '../util/timing';
import type {
EntitiesCatalog,
EntityMutationRequest,
EntityMutationResponse,
EntityUpsertRequest,
EntityUpsertResponse,
} from './types';
type BatchContext = {
@@ -134,9 +134,9 @@ export class DatabaseEntitiesCatalog implements EntitiesCatalog {
* @param locationId The location that they all belong to
*/
async batchAddOrUpdateEntities(
requests: EntityMutationRequest[],
requests: EntityUpsertRequest[],
locationId?: string,
): Promise<EntityMutationResponse[]> {
): Promise<EntityUpsertResponse[]> {
// Group the entities by unique kind+namespace combinations
const entitiesByKindAndNamespace = groupBy(requests, ({ entity }) => {
const name = getEntityName(entity);
@@ -144,7 +144,7 @@ export class DatabaseEntitiesCatalog implements EntitiesCatalog {
});
const limiter = limiterFactory(BATCH_CONCURRENCY);
const tasks: Promise<EntityMutationResponse[]>[] = [];
const tasks: Promise<EntityUpsertResponse[]>[] = [];
for (const groupRequests of Object.values(entitiesByKindAndNamespace)) {
const { kind, namespace } = getEntityName(groupRequests[0].entity);
@@ -157,7 +157,7 @@ export class DatabaseEntitiesCatalog implements EntitiesCatalog {
limiter(async () => {
const first = serializeEntityRef(batch[0].entity);
const last = serializeEntityRef(batch[batch.length - 1].entity);
const modifiedEntityIds: EntityMutationResponse[] = [];
const modifiedEntityIds: EntityUpsertResponse[] = [];
this.logger.debug(
`Considering batch ${first}-${last} (${batch.length} entries)`,
);
@@ -224,12 +224,12 @@ export class DatabaseEntitiesCatalog implements EntitiesCatalog {
// produce the list of entities to be added, and the list of entities to be
// updated
private async analyzeBatch(
requests: EntityMutationRequest[],
requests: EntityUpsertRequest[],
{ kind, namespace }: BatchContext,
): Promise<{
toAdd: EntityMutationRequest[];
toUpdate: EntityMutationRequest[];
toIgnore: EntityMutationRequest[];
toAdd: EntityUpsertRequest[];
toUpdate: EntityUpsertRequest[];
toIgnore: EntityUpsertRequest[];
}> {
const markTimestamp = process.hrtime();
@@ -244,9 +244,9 @@ export class DatabaseEntitiesCatalog implements EntitiesCatalog {
oldEntities.map(e => [e.metadata.name, e]),
);
const toAdd: EntityMutationRequest[] = [];
const toUpdate: EntityMutationRequest[] = [];
const toIgnore: EntityMutationRequest[] = [];
const toAdd: EntityUpsertRequest[] = [];
const toUpdate: EntityUpsertRequest[] = [];
const toIgnore: EntityUpsertRequest[] = [];
for (const request of requests) {
const newEntity = request.entity;
@@ -275,9 +275,9 @@ export class DatabaseEntitiesCatalog implements EntitiesCatalog {
// Efficiently adds the given entities to storage, under the assumption that
// they do not conflict with any existing entities
private async batchAdd(
requests: EntityMutationRequest[],
requests: EntityUpsertRequest[],
{ locationId }: BatchContext,
): Promise<EntityMutationResponse[]> {
): Promise<EntityUpsertResponse[]> {
const markTimestamp = process.hrtime();
const res = await this.database.transaction(
@@ -306,11 +306,11 @@ export class DatabaseEntitiesCatalog implements EntitiesCatalog {
// Efficiently updates the given entities into storage, under the assumption
// that there already exist entities with the same names
private async batchUpdate(
requests: EntityMutationRequest[],
requests: EntityUpsertRequest[],
{ locationId }: BatchContext,
): Promise<EntityMutationResponse[]> {
): Promise<EntityUpsertResponse[]> {
const markTimestamp = process.hrtime();
const responseIds: EntityMutationResponse[] = [];
const responseIds: EntityUpsertResponse[] = [];
// TODO(freben): Still not batched
for (const entity of requests) {
const res = await this.addOrUpdateEntity(entity.entity, locationId);
+4 -4
View File
@@ -21,12 +21,12 @@ import type { EntityFilters } from '../database';
// Entities
//
export type EntityMutationRequest = {
export type EntityUpsertRequest = {
entity: Entity;
relations: EntityRelationSpec[];
};
export type EntityMutationResponse = {
export type EntityUpsertResponse = {
entityId: string;
};
@@ -41,9 +41,9 @@ export type EntitiesCatalog = {
* @param locationId The location that they all belong to
*/
batchAddOrUpdateEntities(
entities: EntityMutationRequest[],
entities: EntityUpsertRequest[],
locationId?: string,
): Promise<EntityMutationResponse[]>;
): Promise<EntityUpsertResponse[]>;
};
//
@@ -103,10 +103,6 @@ export class HigherOrderOperations implements HigherOrderOperation {
location.id,
);
if (writtenEntities.length === 0) {
return { location, entities: [] };
}
const entities = await this.entitiesCatalog.entities({
'metadata.uid': writtenEntities.map(e => e.entityId),
});
@@ -23,6 +23,7 @@ import {
ComponentEntityV1alpha1,
RELATION_OWNED_BY,
RELATION_OWNER_OF,
getEntityName,
} from '@backstage/catalog-model';
import { CatalogProcessor, CatalogProcessorEmit } from './types';
import * as result from './results';
@@ -46,11 +47,7 @@ export class OwnerRelationProcessor implements CatalogProcessor {
if (owner) {
const namespace = entity.metadata.namespace ?? ENTITY_DEFAULT_NAMESPACE;
const selfRef = {
kind: entity.kind,
name: entity.metadata.name,
namespace,
};
const selfRef = getEntityName(entity);
const ownerRef = parseEntityRef(owner, {
defaultKind: 'group',
defaultNamespace: namespace,
@@ -58,15 +55,15 @@ export class OwnerRelationProcessor implements CatalogProcessor {
emit(
result.relation({
type: RELATION_OWNED_BY,
source: selfRef,
type: RELATION_OWNED_BY,
target: ownerRef,
}),
);
emit(
result.relation({
type: RELATION_OWNER_OF,
source: ownerRef,
type: RELATION_OWNER_OF,
target: selfRef,
}),
);