using System; using System.IO; using System.Threading; using System.Threading.Tasks; using StellaOps.Scanner.Cache.Abstractions; using StellaOps.Scanner.Surface.Env; using StellaOps.Scanner.Reachability.Gates; namespace StellaOps.Scanner.Reachability; public interface IRichGraphPublisherService { Task PublishAsync(ReachabilityUnionGraph graph, string analysisId, CancellationToken cancellationToken = default); } /// /// Service wrapper that builds richgraph-v1 from a union graph and stores it in CAS. /// public sealed class ReachabilityRichGraphPublisherService : IRichGraphPublisherService { private readonly ISurfaceEnvironment _environment; private readonly IFileContentAddressableStore _cas; private readonly IRichGraphPublisher _publisher; private readonly IRichGraphGateAnnotator? _gateAnnotator; public ReachabilityRichGraphPublisherService( ISurfaceEnvironment environment, IFileContentAddressableStore cas, IRichGraphPublisher publisher, IRichGraphGateAnnotator? gateAnnotator = null) { _environment = environment ?? throw new ArgumentNullException(nameof(environment)); _cas = cas ?? throw new ArgumentNullException(nameof(cas)); _publisher = publisher ?? throw new ArgumentNullException(nameof(publisher)); _gateAnnotator = gateAnnotator; } public async Task PublishAsync(ReachabilityUnionGraph graph, string analysisId, CancellationToken cancellationToken = default) { var richGraph = RichGraphBuilder.FromUnion(graph, "scanner.reachability", "0.1.0"); if (_gateAnnotator is not null) { richGraph = await _gateAnnotator.AnnotateAsync(richGraph, cancellationToken).ConfigureAwait(false); } var workRoot = Path.Combine(_environment.Settings.CacheRoot.FullName, "reachability"); Directory.CreateDirectory(workRoot); return await _publisher.PublishAsync(richGraph, analysisId, _cas, workRoot, cancellationToken).ConfigureAwait(false); } }