diff --git a/src/Microsoft.ComponentDetection.Orchestrator/Commands/ListDetectorsCommand.cs b/src/Microsoft.ComponentDetection.Orchestrator/Commands/ListDetectorsCommand.cs
index 2704e4e28..6eb145330 100644
--- a/src/Microsoft.ComponentDetection.Orchestrator/Commands/ListDetectorsCommand.cs
+++ b/src/Microsoft.ComponentDetection.Orchestrator/Commands/ListDetectorsCommand.cs
@@ -9,24 +9,12 @@ namespace Microsoft.ComponentDetection.Orchestrator.Commands;
///
/// Lists available detectors.
///
-public sealed class ListDetectorsCommand : Command
+/// The detectors.
+/// The console.
+public sealed class ListDetectorsCommand(
+ IEnumerable detectors,
+ IAnsiConsole console) : Command
{
- private readonly IEnumerable detectors;
- private readonly IAnsiConsole console;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The detectors.
- /// The console.
- public ListDetectorsCommand(
- IEnumerable detectors,
- IAnsiConsole console)
- {
- this.detectors = detectors;
- this.console = console;
- }
-
///
public override int Execute(
CommandContext context,
@@ -36,12 +24,12 @@ public override int Execute(
var table = new Table();
table.AddColumn("Name");
- foreach (var detector in this.detectors)
+ foreach (var detector in detectors)
{
table.AddRow(detector.Id);
}
- this.console.Write(table);
+ console.Write(table);
return (int)ProcessingResultCode.Success;
}
diff --git a/src/Microsoft.ComponentDetection.Orchestrator/Commands/ListDetectorsSettings.cs b/src/Microsoft.ComponentDetection.Orchestrator/Commands/ListDetectorsSettings.cs
index 4877364f3..b224dff6f 100644
--- a/src/Microsoft.ComponentDetection.Orchestrator/Commands/ListDetectorsSettings.cs
+++ b/src/Microsoft.ComponentDetection.Orchestrator/Commands/ListDetectorsSettings.cs
@@ -3,6 +3,4 @@ namespace Microsoft.ComponentDetection.Orchestrator.Commands;
///
/// Settings for the ListDetectors command.
///
-public class ListDetectorsSettings : BaseSettings
-{
-}
+public class ListDetectorsSettings : BaseSettings;
diff --git a/src/Microsoft.ComponentDetection.Orchestrator/Commands/ScanCommand.cs b/src/Microsoft.ComponentDetection.Orchestrator/Commands/ScanCommand.cs
index de4a28048..385ba605e 100644
--- a/src/Microsoft.ComponentDetection.Orchestrator/Commands/ScanCommand.cs
+++ b/src/Microsoft.ComponentDetection.Orchestrator/Commands/ScanCommand.cs
@@ -44,7 +44,7 @@ public override async Task ExecuteAsync(
CancellationToken cancellationToken)
{
this.fileWritingService.Init(settings.Output);
- var result = await this.scanExecutionService.ExecuteScanAsync(settings);
+ var result = await this.scanExecutionService.ExecuteScanAsync(settings, cancellationToken);
this.WriteComponentManifest(settings, result);
return 0;
}
@@ -53,11 +53,12 @@ public override async Task ExecuteAsync(
/// Method to provide a way to execute the scan command and obtain the ScanResult object.
///
/// ScanSettings object specifying the parameters for the scan execution.
+ /// CancellationToken to monitor for cancellation requests.
/// A ScanResult object.
- public async Task ExecuteScanCommandAsync(ScanSettings settings)
+ public async Task ExecuteScanCommandAsync(ScanSettings settings, CancellationToken cancellationToken = default)
{
this.fileWritingService.Init(settings.Output);
- var result = await this.scanExecutionService.ExecuteScanAsync(settings);
+ var result = await this.scanExecutionService.ExecuteScanAsync(settings, cancellationToken);
this.WriteComponentManifest(settings, result);
return result;
}
diff --git a/src/Microsoft.ComponentDetection.Orchestrator/Services/DetectorProcessingService.cs b/src/Microsoft.ComponentDetection.Orchestrator/Services/DetectorProcessingService.cs
index 248c401d1..24364fc9b 100644
--- a/src/Microsoft.ComponentDetection.Orchestrator/Services/DetectorProcessingService.cs
+++ b/src/Microsoft.ComponentDetection.Orchestrator/Services/DetectorProcessingService.cs
@@ -41,10 +41,12 @@ public DetectorProcessingService(
this.logger = logger;
}
+ ///
public async Task ProcessDetectorsAsync(
ScanSettings settings,
IEnumerable detectors,
- DetectorRestrictions detectorRestrictions)
+ DetectorRestrictions detectorRestrictions,
+ CancellationToken cancellationToken = default)
{
using var scope = this.logger.BeginScope("Processing detectors");
this.logger.LogInformation($"Finding components...");
diff --git a/src/Microsoft.ComponentDetection.Orchestrator/Services/IDetectorProcessingService.cs b/src/Microsoft.ComponentDetection.Orchestrator/Services/IDetectorProcessingService.cs
index 748b676ad..465ea1cfc 100644
--- a/src/Microsoft.ComponentDetection.Orchestrator/Services/IDetectorProcessingService.cs
+++ b/src/Microsoft.ComponentDetection.Orchestrator/Services/IDetectorProcessingService.cs
@@ -1,14 +1,27 @@
namespace Microsoft.ComponentDetection.Orchestrator.Services;
using System.Collections.Generic;
+using System.Threading;
using System.Threading.Tasks;
using Microsoft.ComponentDetection.Contracts;
using Microsoft.ComponentDetection.Orchestrator.Commands;
+///
+/// Defines a service for processing component detectors during a scan operation.
+///
public interface IDetectorProcessingService
{
- Task ProcessDetectorsAsync(
+ ///
+ /// Processes the specified detectors asynchronously based on the provided scan settings and detector restrictions.
+ ///
+ /// The scan settings that configure how the detection process should be executed.
+ /// The collection of component detectors to be processed.
+ /// The restrictions that determine which detectors should be included or excluded from processing.
+ /// A token to monitor for cancellation requests.
+ /// A task that represents the asynchronous operation. The task result contains the with information about the detection process outcome.
+ public Task ProcessDetectorsAsync(
ScanSettings settings,
IEnumerable detectors,
- DetectorRestrictions detectorRestrictions);
+ DetectorRestrictions detectorRestrictions,
+ CancellationToken cancellationToken = default);
}
diff --git a/src/Microsoft.ComponentDetection.Orchestrator/Services/IScanExecutionService.cs b/src/Microsoft.ComponentDetection.Orchestrator/Services/IScanExecutionService.cs
index 6132b0628..e3712e6ed 100644
--- a/src/Microsoft.ComponentDetection.Orchestrator/Services/IScanExecutionService.cs
+++ b/src/Microsoft.ComponentDetection.Orchestrator/Services/IScanExecutionService.cs
@@ -1,10 +1,20 @@
namespace Microsoft.ComponentDetection.Orchestrator.Services;
+using System.Threading;
using System.Threading.Tasks;
using Microsoft.ComponentDetection.Contracts.BcdeModels;
using Microsoft.ComponentDetection.Orchestrator.Commands;
+///
+/// Defines a service responsible for executing component detection scans.
+///
public interface IScanExecutionService
{
- Task ExecuteScanAsync(ScanSettings settings);
+ ///
+ /// Executes a scan asynchronously based on the provided scan settings.
+ ///
+ /// The scan settings that configure how the scan should be executed.
+ /// A token to monitor for cancellation requests.
+ /// A task that represents the asynchronous scan operation. The task result contains the with information about the scan execution.
+ public Task ExecuteScanAsync(ScanSettings settings, CancellationToken cancellationToken = default);
}
diff --git a/src/Microsoft.ComponentDetection.Orchestrator/Services/ScanExecutionService.cs b/src/Microsoft.ComponentDetection.Orchestrator/Services/ScanExecutionService.cs
index 94ef6f64b..d065adff3 100644
--- a/src/Microsoft.ComponentDetection.Orchestrator/Services/ScanExecutionService.cs
+++ b/src/Microsoft.ComponentDetection.Orchestrator/Services/ScanExecutionService.cs
@@ -4,6 +4,7 @@ namespace Microsoft.ComponentDetection.Orchestrator.Services;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
+using System.Threading;
using System.Threading.Tasks;
using Microsoft.ComponentDetection.Contracts;
using Microsoft.ComponentDetection.Contracts.BcdeModels;
@@ -33,7 +34,8 @@ public ScanExecutionService(
this.logger = logger;
}
- public async Task ExecuteScanAsync(ScanSettings settings)
+ ///
+ public async Task ExecuteScanAsync(ScanSettings settings, CancellationToken cancellationToken = default)
{
using var scope = this.logger.BeginScope("Executing BCDE scan");
@@ -44,7 +46,7 @@ public async Task ExecuteScanAsync(ScanSettings settings)
this.logger.LogDebug("Finished applying restrictions to detectors.");
- var processingResult = await this.detectorProcessingService.ProcessDetectorsAsync(settings, detectorsWithAppliedRestrictions, detectorRestrictions);
+ var processingResult = await this.detectorProcessingService.ProcessDetectorsAsync(settings, detectorsWithAppliedRestrictions, detectorRestrictions, cancellationToken);
var scanResult = this.graphTranslationService.GenerateScanResultFromProcessingResult(processingResult, settings);
scanResult.DetectorsInScan = detectorsWithAppliedRestrictions.Select(ConvertToContract).ToList();
diff --git a/test/Microsoft.ComponentDetection.Orchestrator.Tests/Commands/ScanCommandTests.cs b/test/Microsoft.ComponentDetection.Orchestrator.Tests/Commands/ScanCommandTests.cs
index 77687ec32..38fa2ff1f 100644
--- a/test/Microsoft.ComponentDetection.Orchestrator.Tests/Commands/ScanCommandTests.cs
+++ b/test/Microsoft.ComponentDetection.Orchestrator.Tests/Commands/ScanCommandTests.cs
@@ -44,7 +44,7 @@ public async Task ScanCommand_ExecutesScanAndWritesManifestAsync()
var result = await this.command.ExecuteAsync(null, settings, CancellationToken.None);
this.fileWritingServiceMock.Verify(x => x.Init(settings.Output), Times.Once);
- this.scanExecutionServiceMock.Verify(x => x.ExecuteScanAsync(settings), Times.Once);
+ this.scanExecutionServiceMock.Verify(x => x.ExecuteScanAsync(settings, CancellationToken.None), Times.Once);
this.fileWritingServiceMock.Verify(x => x.ResolveFilePath(It.IsAny()), Times.Once);
this.fileWritingServiceMock.Verify(x => x.AppendToFile(It.IsAny(), It.IsAny()));
result.Should().Be(0);
@@ -58,7 +58,7 @@ public async Task ScanCommand_ExecutesScanAndWritesUserManifestAsync()
var result = await this.command.ExecuteAsync(null, settings, CancellationToken.None);
this.fileWritingServiceMock.Verify(x => x.Init(settings.Output), Times.Once);
- this.scanExecutionServiceMock.Verify(x => x.ExecuteScanAsync(settings), Times.Once);
+ this.scanExecutionServiceMock.Verify(x => x.ExecuteScanAsync(settings, CancellationToken.None), Times.Once);
this.fileWritingServiceMock.Verify(x => x.WriteFile(It.Is(x => x == settings.ManifestFile), It.IsAny()));
result.Should().Be(0);
@@ -75,7 +75,7 @@ public async Task ScanCommand_ExecutesScanAndPrintsManifestAsync()
var result = await this.command.ExecuteAsync(null, settings, CancellationToken.None);
this.fileWritingServiceMock.Verify(x => x.Init(settings.Output), Times.Once);
- this.scanExecutionServiceMock.Verify(x => x.ExecuteScanAsync(settings), Times.Once);
+ this.scanExecutionServiceMock.Verify(x => x.ExecuteScanAsync(settings, CancellationToken.None), Times.Once);
this.fileWritingServiceMock.Verify(x => x.ResolveFilePath(It.IsAny()), Times.Once);
this.fileWritingServiceMock.Verify(x => x.AppendToFile(It.IsAny(), It.IsAny()));
@@ -95,7 +95,7 @@ public async Task ExecuteScanCommandAsync_PrintsManifestAsync()
var result = await this.command.ExecuteScanCommandAsync(settings);
this.fileWritingServiceMock.Verify(x => x.Init(settings.Output), Times.Once);
- this.scanExecutionServiceMock.Verify(x => x.ExecuteScanAsync(settings), Times.Once);
+ this.scanExecutionServiceMock.Verify(x => x.ExecuteScanAsync(settings, CancellationToken.None), Times.Once);
this.fileWritingServiceMock.Verify(x => x.ResolveFilePath(It.IsAny()), Times.Once);
this.fileWritingServiceMock.Verify(x => x.AppendToFile(It.IsAny(), It.IsAny()));
@@ -111,7 +111,7 @@ public async Task ExecuteScanCommandAsync_WritesUserManifestAsync()
var result = await this.command.ExecuteScanCommandAsync(settings);
this.fileWritingServiceMock.Verify(x => x.Init(settings.Output), Times.Once);
- this.scanExecutionServiceMock.Verify(x => x.ExecuteScanAsync(settings), Times.Once);
+ this.scanExecutionServiceMock.Verify(x => x.ExecuteScanAsync(settings, CancellationToken.None), Times.Once);
this.fileWritingServiceMock.Verify(x => x.WriteFile(It.Is(x => x == settings.ManifestFile), It.IsAny()));
}
}
diff --git a/test/Microsoft.ComponentDetection.Orchestrator.Tests/Services/BcdeScanExecutionServiceTests.cs b/test/Microsoft.ComponentDetection.Orchestrator.Tests/Services/BcdeScanExecutionServiceTests.cs
index e55ec78b0..91567178a 100644
--- a/test/Microsoft.ComponentDetection.Orchestrator.Tests/Services/BcdeScanExecutionServiceTests.cs
+++ b/test/Microsoft.ComponentDetection.Orchestrator.Tests/Services/BcdeScanExecutionServiceTests.cs
@@ -4,6 +4,7 @@ namespace Microsoft.ComponentDetection.Orchestrator.Tests.Services;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Threading;
using System.Threading.Tasks;
using AwesomeAssertions;
using Microsoft.ComponentDetection.Common.DependencyGraph;
@@ -765,10 +766,11 @@ private async Task DetectComponentsHappyPathAsync(
x.ProcessDetectorsAsync(
settings,
It.Is>(inputDetectors => restrictedDetectors.Intersect(inputDetectors).Count() == restrictedDetectors.Length),
- Match.Create(restriction => true)))
+ Match.Create(restriction => true),
+ CancellationToken.None))
.ReturnsAsync(processingResult);
- var result = await this.serviceUnderTest.ExecuteScanAsync(settings);
+ var result = await this.serviceUnderTest.ExecuteScanAsync(settings, CancellationToken.None);
result.ResultCode.Should().Be(ProcessingResultCode.Success);
result.SourceDirectory.Should().NotBeNull();
result.SourceDirectory.Should().Be(settings.SourceDirectory.ToString());
@@ -824,10 +826,11 @@ private async Task DetectComponentsHappyPathAsync(
x.ProcessDetectorsAsync(
settings,
It.Is>(inputDetectors => restrictedDetectors.Intersect(inputDetectors).Count() == restrictedDetectors.Length),
- Match.Create(restriction => true)))
+ Match.Create(restriction => true),
+ CancellationToken.None))
.ReturnsAsync(processingResult);
- var result = await this.serviceUnderTest.ExecuteScanAsync(settings);
+ var result = await this.serviceUnderTest.ExecuteScanAsync(settings, CancellationToken.None);
result.ResultCode.Should().Be(ProcessingResultCode.Success);
result.SourceDirectory.Should().NotBeNull();
result.SourceDirectory.Should().Be(settings.SourceDirectory.ToString());
@@ -880,10 +883,11 @@ private async Task SetupRecorderBasedScanningAsync(
x.ProcessDetectorsAsync(
settings,
It.Is>(inputDetectors => restrictedDetectors.Intersect(inputDetectors).Count() == restrictedDetectors.Length),
- Match.Create(restriction => true)))
+ Match.Create(restriction => true),
+ CancellationToken.None))
.ReturnsAsync(processingResult);
- var result = await this.serviceUnderTest.ExecuteScanAsync(settings);
+ var result = await this.serviceUnderTest.ExecuteScanAsync(settings, CancellationToken.None);
result.ResultCode.Should().Be(ProcessingResultCode.Success);
result.SourceDirectory.Should().NotBeNull();
result.SourceDirectory.Should().Be(settings.SourceDirectory.ToString());