fix batch fetch by ref with filtering
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
---
|
||||
|
||||
Fix a bug where the batch fetch by ref endpoint did not work in conjunction with filtering (e.g. if authorization was enabled).
|
||||
@@ -98,7 +98,9 @@ export interface EntitiesBatchRequest {
|
||||
*/
|
||||
entityRefs: string[];
|
||||
/**
|
||||
* Any additional filters to apply in the selection of the entities.
|
||||
* Any additional filters to apply in the selection of the entities. Entities
|
||||
* that do not match the filter result in a null entry in the response, as if
|
||||
* they did not exist.
|
||||
*/
|
||||
filter?: EntityFilter;
|
||||
/**
|
||||
|
||||
@@ -87,6 +87,9 @@ describe('DefaultEntitiesCatalog', () => {
|
||||
});
|
||||
}
|
||||
|
||||
const search = await buildEntitySearch(id, entity);
|
||||
await knex<DbSearchRow>('search').insert(search);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -721,6 +724,51 @@ describe('DefaultEntitiesCatalog', () => {
|
||||
},
|
||||
60_000,
|
||||
);
|
||||
|
||||
it.each(databases.eachSupportedId())(
|
||||
'queries for entities by ref, including filtering, %p',
|
||||
async databaseId => {
|
||||
await createDatabase(databaseId);
|
||||
|
||||
await addEntity(
|
||||
{
|
||||
apiVersion: 'a',
|
||||
kind: 'k',
|
||||
metadata: { name: 'one' },
|
||||
spec: {},
|
||||
relations: [],
|
||||
},
|
||||
[],
|
||||
);
|
||||
await addEntity(
|
||||
{
|
||||
apiVersion: 'a',
|
||||
kind: 'k',
|
||||
metadata: { name: 'two' },
|
||||
spec: { owner: 'me' },
|
||||
relations: [],
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const catalog = new DefaultEntitiesCatalog({
|
||||
database: knex,
|
||||
logger: getVoidLogger(),
|
||||
stitcher,
|
||||
});
|
||||
|
||||
const { items } = await catalog.entitiesBatch({
|
||||
entityRefs: ['k:default/two', 'k:default/one'],
|
||||
filter: { key: 'spec.owner', values: ['me'] },
|
||||
});
|
||||
|
||||
expect(items.map(e => e && stringifyEntityRef(e))).toEqual([
|
||||
'k:default/two',
|
||||
null,
|
||||
]);
|
||||
},
|
||||
60_000,
|
||||
);
|
||||
});
|
||||
|
||||
describe('queryEntities', () => {
|
||||
|
||||
@@ -309,17 +309,27 @@ export class DefaultEntitiesCatalog implements EntitiesCatalog {
|
||||
|
||||
for (const chunk of lodashChunk(request.entityRefs, 200)) {
|
||||
let query = this.database<DbFinalEntitiesRow>('final_entities')
|
||||
.innerJoin<DbRefreshStateRow>('refresh_state', {
|
||||
'refresh_state.entity_id': 'final_entities.entity_id',
|
||||
})
|
||||
.innerJoin<DbRefreshStateRow>(
|
||||
'refresh_state',
|
||||
'refresh_state.entity_id',
|
||||
'final_entities.entity_id',
|
||||
)
|
||||
.select({
|
||||
entityRef: 'refresh_state.entity_ref',
|
||||
entity: 'final_entities.final_entity',
|
||||
})
|
||||
.whereIn('refresh_state.entity_ref', chunk);
|
||||
|
||||
if (request?.filter) {
|
||||
query = parseFilter(request.filter, query, this.database);
|
||||
query = parseFilter(
|
||||
request.filter,
|
||||
query,
|
||||
this.database,
|
||||
false,
|
||||
'refresh_state.entity_id',
|
||||
);
|
||||
}
|
||||
|
||||
for (const row of await query) {
|
||||
lookup.set(row.entityRef, row.entity ? JSON.parse(row.entity) : null);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user