nuget reorganization
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Globalization;
|
||||
using StellaOps.SbomService.Models;
|
||||
using StellaOps.SbomService.Repositories;
|
||||
|
||||
namespace StellaOps.SbomService.Services;
|
||||
|
||||
@@ -8,16 +10,16 @@ internal sealed class InMemorySbomQueryService : ISbomQueryService
|
||||
private readonly IReadOnlyList<PathRecord> _paths;
|
||||
private readonly IReadOnlyList<TimelineRecord> _timelines;
|
||||
private readonly IReadOnlyList<CatalogRecord> _catalog;
|
||||
private readonly IReadOnlyList<ComponentLookupRecord> _components;
|
||||
private readonly IComponentLookupRepository _componentLookupRepository;
|
||||
private readonly ConcurrentDictionary<string, object> _cache = new();
|
||||
|
||||
public InMemorySbomQueryService()
|
||||
public InMemorySbomQueryService(IComponentLookupRepository componentLookupRepository)
|
||||
{
|
||||
_componentLookupRepository = componentLookupRepository;
|
||||
// Deterministic seed data for early contract testing; replace with Mongo-backed implementation later.
|
||||
_paths = SeedPaths();
|
||||
_timelines = SeedTimelines();
|
||||
_catalog = SeedCatalog();
|
||||
_components = SeedComponents();
|
||||
}
|
||||
|
||||
public Task<QueryResult<SbomPathResult>> GetPathsAsync(SbomPathQuery query, CancellationToken cancellationToken)
|
||||
@@ -131,34 +133,27 @@ internal sealed class InMemorySbomQueryService : ISbomQueryService
|
||||
return Task.FromResult(new QueryResult<SbomCatalogResult>(result, false));
|
||||
}
|
||||
|
||||
public Task<QueryResult<ComponentLookupResult>> GetComponentLookupAsync(ComponentLookupQuery query, CancellationToken cancellationToken)
|
||||
public async Task<QueryResult<ComponentLookupResult>> GetComponentLookupAsync(ComponentLookupQuery query, CancellationToken cancellationToken)
|
||||
{
|
||||
var cacheKey = $"component|{query.Purl}|{query.Artifact}|{query.Offset}|{query.Limit}";
|
||||
if (_cache.TryGetValue(cacheKey, out var cached) && cached is ComponentLookupResult cachedResult)
|
||||
{
|
||||
return Task.FromResult(new QueryResult<ComponentLookupResult>(cachedResult, true));
|
||||
return new QueryResult<ComponentLookupResult>(cachedResult, true);
|
||||
}
|
||||
|
||||
var filtered = _components
|
||||
.Where(c => c.Purl.Equals(query.Purl, StringComparison.OrdinalIgnoreCase))
|
||||
.Where(c => query.Artifact is null || c.Artifact.Equals(query.Artifact, StringComparison.OrdinalIgnoreCase))
|
||||
.OrderBy(c => c.Artifact)
|
||||
.ThenBy(c => c.Purl)
|
||||
.ToList();
|
||||
var page = await _componentLookupRepository.QueryAsync(query, cancellationToken);
|
||||
|
||||
var page = filtered
|
||||
.Skip(query.Offset)
|
||||
.Take(query.Limit)
|
||||
.Select(c => new ComponentNeighbor(c.NeighborPurl, c.Relationship, c.License, c.Scope, c.RuntimeFlag))
|
||||
.ToList();
|
||||
|
||||
string? nextCursor = query.Offset + query.Limit < filtered.Count
|
||||
string? nextCursor = query.Offset + query.Limit < page.Count
|
||||
? (query.Offset + query.Limit).ToString(CultureInfo.InvariantCulture)
|
||||
: null;
|
||||
|
||||
var result = new ComponentLookupResult(query.Purl, query.Artifact, page, nextCursor, CacheHint: "seeded");
|
||||
var neighbors = page
|
||||
.Select(c => new ComponentNeighbor(c.NeighborPurl, c.Relationship, c.License, c.Scope, c.RuntimeFlag))
|
||||
.ToList();
|
||||
|
||||
var result = new ComponentLookupResult(query.Purl, query.Artifact, neighbors, nextCursor, CacheHint: "seeded");
|
||||
_cache[cacheKey] = result;
|
||||
return Task.FromResult(new QueryResult<ComponentLookupResult>(result, false));
|
||||
return new QueryResult<ComponentLookupResult>(result, false);
|
||||
}
|
||||
|
||||
private static IReadOnlyList<PathRecord> SeedPaths()
|
||||
|
||||
Reference in New Issue
Block a user