Skip to content

Commit 4ab0fea

Browse files
committed
Improve get catalog by slug
1 parent 0254aae commit 4ab0fea

2 files changed

Lines changed: 167 additions & 82 deletions

File tree

src/main/java/org/opendevstack/component_catalog/server/services/CatalogItemBySlugService.java

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.opendevstack.component_catalog.server.services;
22

3+
import org.opendevstack.component_catalog.server.services.catalog.CatalogServiceAdapter;
34
import org.opendevstack.component_catalog.server.services.catalog.InvalidCatalogEntityException;
45
import org.opendevstack.component_catalog.server.services.catalog.entity.CatalogItemEntityContext;
56
import org.opendevstack.component_catalog.server.services.exceptions.InvalidIdException;
@@ -30,13 +31,15 @@ public class CatalogItemBySlugService {
3031

3132
private final CatalogsCollectionService catalogsCollectionService;
3233
private final CatalogEntitiesService catalogEntitiesService;
34+
private final CatalogServiceAdapter catalogServiceAdapter;
35+
private final BitbucketService bitbucketService;
3336

3437
/**
3538
* Resolves a {@link CatalogItemSlug} to the matching {@link CatalogItemEntityContext}.
3639
*
3740
* @param slug the parsed composite slug
3841
* @return an {@link Optional} with the matching context, or empty if not found
39-
* @throws InvalidIdException if any catalog id is structurally invalid
42+
* @throws InvalidIdException if any catalog or item id is structurally invalid
4043
* @throws InvalidCatalogEntityException if a catalog entity cannot be parsed
4144
*/
4245
public Optional<CatalogItemEntityContext> findByCatalogItemSlug(CatalogItemSlug slug)
@@ -59,27 +62,40 @@ public Optional<CatalogItemEntityContext> findByCatalogItemSlug(CatalogItemSlug
5962

6063
for (var target : targets) {
6164
var catalogId = idEncode(target.getUrl());
62-
var itemContexts = catalogEntitiesService.getCatalogItemsEntities(catalogId);
63-
var match = itemContexts.stream()
64-
.filter(ctx -> itemMatchesSlug(ctx, slug))
65-
.findFirst();
66-
if (match.isPresent()) {
67-
log.debug("Resolved slug '{}' to item in catalog target '{}'", slug, target.getUrl());
68-
return match;
65+
66+
var catalogIdPathAt = catalogServiceAdapter.bitbucketPathAtFromId(catalogId);
67+
68+
// Optimisation: skip catalogs whose Bitbucket project key does not match the slug's project key,
69+
// avoiding unnecessary item loading. This relies on the assumption that catalog items live in the
70+
// same Bitbucket project as their catalog definition.
71+
if (CatalogItemSlug.normalise(catalogIdPathAt.getProjectKey()).equals(slug.getProjectKey())) {
72+
log.debug("Catalog target '{}' matches slug project key '{}', checking items...",
73+
target.getUrl(), slug.getProjectKey());
74+
75+
var slugCatalogEntity = catalogEntitiesService.getCatalogEntity(catalogId);
76+
77+
if (slugCatalogEntity.isPresent()) {
78+
// A slug uniquely identifies one item. Multiple matches (e.g. the same repo referenced
79+
// in more than one catalog entry) are not expected; we return the first one found.
80+
for (var itemTarget : slugCatalogEntity.get().getMetadata().getSpec().getTargets()) {
81+
var itemPathAt = bitbucketService.pathAtBuilder()
82+
.rawUrl(itemTarget.getUrl())
83+
.build();
84+
if (CatalogItemSlug.normalise(itemPathAt.getProjectKey()).equals(slug.getProjectKey())
85+
&& itemPathAt.getRepoSlug().equalsIgnoreCase(slug.getRepoName())) {
86+
var itemId = idEncode(itemPathAt.getPathAt());
87+
log.debug("Resolved slug '{}' to item id '{}' in catalog target '{}'", slug, itemId, target.getUrl());
88+
return catalogEntitiesService.getCatalogItemEntity(itemId);
89+
}
90+
}
91+
}
92+
6993
}
7094
}
7195

7296
log.debug("No catalog item matched slug '{}'", slug);
7397
return Optional.empty();
7498
}
7599

76-
// --- private helpers ---
77-
78-
private boolean itemMatchesSlug(CatalogItemEntityContext ctx, CatalogItemSlug slug) {
79-
var normalisedProjectKey = CatalogItemSlug.normalise(ctx.getRepoCatalogItemPathAt().getProjectKey());
80-
return normalisedProjectKey.equals(slug.getProjectKey())
81-
&& slug.getRepoName().equalsIgnoreCase(ctx.getRepoCatalogItemPathAt().getRepoSlug());
82-
}
83-
84100
}
85101

0 commit comments

Comments
 (0)