partly or unimplemented features - now implemented
This commit is contained in:
@@ -419,6 +419,87 @@ Exports evidence pack for artifact(s).
|
||||
}
|
||||
```
|
||||
|
||||
### GET /api/v1/lineage/stream
|
||||
|
||||
Subscribe to real-time lineage updates via Server-Sent Events (SSE).
|
||||
|
||||
**Query Parameters:**
|
||||
- `watchDigests` (optional): Comma-separated list of digests to filter updates.
|
||||
|
||||
**Response:** SSE stream with events:
|
||||
```
|
||||
event: lineage-update
|
||||
data: {"id":"uuid","type":"SbomAdded","digest":"sha256:...","timestamp":"...","data":{...}}
|
||||
```
|
||||
|
||||
**Event Types:**
|
||||
- `SbomAdded` - New SBOM version created
|
||||
- `VexChanged` - VEX status changed for a component
|
||||
- `ReachabilityUpdated` - Reachability analysis completed
|
||||
- `EdgeChanged` - Lineage edge added/removed
|
||||
- `Heartbeat` - Keep-alive ping
|
||||
|
||||
### GET /api/v1/lineage/{artifactDigest}/optimized
|
||||
|
||||
Get paginated and depth-pruned lineage graph for performance.
|
||||
|
||||
**Query Parameters:**
|
||||
- `maxDepth` (optional, default: 3): Maximum traversal depth
|
||||
- `pageSize` (optional, default: 50): Nodes per page
|
||||
- `pageNumber` (optional, default: 0): Zero-indexed page number
|
||||
- `searchTerm` (optional): Filter nodes by name
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"centerDigest": "sha256:abc123...",
|
||||
"nodes": [...],
|
||||
"edges": [...],
|
||||
"boundaryNodes": [
|
||||
{"digest": "sha256:...", "hiddenChildrenCount": 5, "hiddenParentsCount": 0}
|
||||
],
|
||||
"totalNodes": 150,
|
||||
"hasMorePages": true,
|
||||
"pageNumber": 0,
|
||||
"pageSize": 50
|
||||
}
|
||||
```
|
||||
|
||||
### GET /api/v1/lineage/{artifactDigest}/levels
|
||||
|
||||
Progressive level-by-level graph traversal via SSE.
|
||||
|
||||
**Query Parameters:**
|
||||
- `direction` (optional, default: "Children"): Traversal direction (Children/Parents/Center)
|
||||
- `maxDepth` (optional, default: 5): Maximum depth to traverse
|
||||
|
||||
**Response:** SSE stream with level events:
|
||||
```
|
||||
event: level
|
||||
data: {"depth":0,"nodes":[...],"isComplete":true}
|
||||
|
||||
event: level
|
||||
data: {"depth":1,"nodes":[...],"isComplete":true}
|
||||
|
||||
event: complete
|
||||
data: {"status":"done"}
|
||||
```
|
||||
|
||||
### GET /api/v1/lineage/{artifactDigest}/metadata
|
||||
|
||||
Get cached metadata about a lineage graph.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"centerDigest": "sha256:abc123...",
|
||||
"totalNodes": 150,
|
||||
"totalEdges": 175,
|
||||
"maxDepth": 8,
|
||||
"computedAt": "2025-12-28T10:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
## Caching Strategy
|
||||
|
||||
### Hover Card Cache (Valkey)
|
||||
@@ -434,6 +515,86 @@ Exports evidence pack for artifact(s).
|
||||
- **TTL:** 10 minutes
|
||||
- **Invalidation:** On new VEX data for either artifact
|
||||
|
||||
### Graph Metadata Cache (Valkey)
|
||||
|
||||
- **Key:** `lineage:metadata:{tenantId}:{centerDigest}`
|
||||
- **TTL:** 10 minutes
|
||||
- **Contents:** Node count, edge count, max depth
|
||||
- **Invalidation:** On lineage edge changes via `DELETE /api/v1/lineage/{digest}/cache`
|
||||
|
||||
### Optimization Cache
|
||||
|
||||
The `LineageGraphOptimizer` uses IDistributedCache to store:
|
||||
- Pre-computed metadata for large graphs
|
||||
- BFS distance calculations
|
||||
- Pagination state for consistent paging
|
||||
|
||||
## Real-Time Streaming Architecture
|
||||
|
||||
### LineageStreamService
|
||||
|
||||
Provides Server-Sent Events (SSE) for real-time lineage updates:
|
||||
|
||||
```csharp
|
||||
public interface ILineageStreamService
|
||||
{
|
||||
IAsyncEnumerable<LineageUpdateEvent> SubscribeAsync(
|
||||
Guid tenantId,
|
||||
IReadOnlyList<string>? watchDigests = null,
|
||||
CancellationToken ct = default);
|
||||
|
||||
Task NotifySbomAddedAsync(Guid tenantId, string artifactDigest,
|
||||
string? parentDigest, SbomVersionSummary summary, CancellationToken ct);
|
||||
|
||||
Task NotifyVexChangedAsync(Guid tenantId, string artifactDigest,
|
||||
VexChangeData change, CancellationToken ct);
|
||||
|
||||
Task NotifyReachabilityUpdatedAsync(Guid tenantId, string artifactDigest,
|
||||
ReachabilityUpdateData update, CancellationToken ct);
|
||||
|
||||
Task NotifyEdgeChangedAsync(Guid tenantId, string fromDigest,
|
||||
string toDigest, LineageEdgeChangeType changeType, CancellationToken ct);
|
||||
}
|
||||
```
|
||||
|
||||
**Implementation:**
|
||||
- Uses `Channel<T>` for tenant-scoped subscription management
|
||||
- Bounded channels with `DropOldest` policy to handle slow consumers
|
||||
- Optional digest filtering for targeted subscriptions
|
||||
- Automatic subscription cleanup on disconnect
|
||||
|
||||
### LineageGraphOptimizer
|
||||
|
||||
Optimizes large graphs for UI performance:
|
||||
|
||||
```csharp
|
||||
public interface ILineageGraphOptimizer
|
||||
{
|
||||
OptimizedLineageGraph Optimize(LineageOptimizationRequest request);
|
||||
|
||||
IAsyncEnumerable<LineageLevel> TraverseLevelsAsync(
|
||||
string centerDigest,
|
||||
ImmutableArray<LineageNode> nodes,
|
||||
ImmutableArray<LineageEdge> edges,
|
||||
TraversalDirection direction,
|
||||
int maxDepth = 10,
|
||||
CancellationToken ct = default);
|
||||
|
||||
Task<LineageGraphMetadata> GetOrComputeMetadataAsync(
|
||||
Guid tenantId, string centerDigest,
|
||||
ImmutableArray<LineageNode> nodes,
|
||||
ImmutableArray<LineageEdge> edges,
|
||||
CancellationToken ct);
|
||||
}
|
||||
```
|
||||
|
||||
**Optimization Features:**
|
||||
1. **Depth Pruning:** BFS-based distance computation from center node
|
||||
2. **Search Filtering:** Case-insensitive node name matching
|
||||
3. **Pagination:** Stable ordering with configurable page size
|
||||
4. **Boundary Detection:** Identifies nodes with hidden children for expand-on-demand UI
|
||||
5. **Level Traversal:** Progressive rendering via async enumerable
|
||||
|
||||
## Determinism Guarantees
|
||||
|
||||
1. **Node Ordering:** Sorted by `sequenceNumber DESC`, then `createdAt DESC`
|
||||
|
||||
Reference in New Issue
Block a user