Skip to content

Commit

Permalink
Made the Timeout in LicenseInformationService configurable via CLI ar…
Browse files Browse the repository at this point in the history
…gument (microsoft#584)
  • Loading branch information
kidcline1 committed Nov 1, 2024
1 parent eeb06b9 commit f4620fe
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 5 deletions.
9 changes: 9 additions & 0 deletions src/Microsoft.Sbom.Api/Config/Args/GenerationArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,15 @@ public class GenerationArgs : GenerationAndValidationCommonArgs
[ArgDescription("If set to true, we will attempt to fetch license information of packages detected in the SBOM from the ClearlyDefinedApi.")]
public bool? FetchLicenseInformation { get; set; }

/// <summary>
/// Specifies the timeout in seconds for fetching the license information. Defaults to 30 seconds. Has no effect if
/// FetchLicenseInformation (li) argument is false or not provided.
/// </summary>
[ArgShortcut("lto")]
[ArgDescription("Specifies the timeout in seconds for fetching the license information. Defaults to 30 seconds. " +
"Has no effect if the FetchLicenseInformation (li) argument is false or not provided. ")]
public int? LicenseInformationTimeout { get; set; }

/// <summary>
/// If set to true, we will attempt to parse license and supplier info from the packages metadata file.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,15 @@ async Task Scan(string path)
{
licenseInformationRetrieved = true;

var apiResponses = await licenseInformationFetcher.FetchLicenseInformationAsync(listOfComponentsForApi);
List<string> apiResponses;
if (configuration.LicenseInformationTimeout is null)
{
apiResponses = await licenseInformationFetcher.FetchLicenseInformationAsync(listOfComponentsForApi);
}
else
{
apiResponses = await licenseInformationFetcher.FetchLicenseInformationAsync(listOfComponentsForApi, configuration.LicenseInformationTimeout.Value);
}

foreach (var response in apiResponses)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ public interface ILicenseInformationFetcher
/// <returns></returns>
List<string> ConvertComponentsToListForApi(IEnumerable<ScannedComponent> scannedComponents);

/// <inheritdoc cref="FetchLicenseInformationAsync(List{string}, int)"/>>
Task<List<string>> FetchLicenseInformationAsync(List<string> listOfComponentsForApi);

/// <summary>
/// Calls the ClearlyDefined API to get the license information for the list of components.
/// </summary>
/// <param name="listOfComponentsForApi"> A list of strings formatted into a list of strings that can be used to call the batch ClearlyDefined API.</param>
/// <param name="timeout">Timeout in seconds to use when making web requests</param>
/// <returns></returns>
Task<List<string>> FetchLicenseInformationAsync(List<string> listOfComponentsForApi);
Task<List<string>> FetchLicenseInformationAsync(List<string> listOfComponentsForApi, int timeout);

/// <summary>
/// Gets the dictionary of licenses that were fetched from the ClearlyDefined API.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ namespace Microsoft.Sbom.Api.Executors;
public interface ILicenseInformationService
{
public Task<List<string>> FetchLicenseInformationFromAPI(List<string> listOfComponentsForApi);

public Task<List<string>> FetchLicenseInformationFromAPI(List<string> listOfComponentsForApi, int timeout);
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,12 @@ public List<string> ConvertComponentsToListForApi(IEnumerable<ScannedComponent>

public async Task<List<string>> FetchLicenseInformationAsync(List<string> listOfComponentsForApi)
{
return await licenseInformationService.FetchLicenseInformationFromAPI(listOfComponentsForApi);
return await FetchLicenseInformationAsync(listOfComponentsForApi, 30);
}

public async Task<List<string>> FetchLicenseInformationAsync(List<string> listOfComponentsForApi, int timeout)
{
return await licenseInformationService.FetchLicenseInformationFromAPI(listOfComponentsForApi, timeout);
}

// Will attempt to extract license information from a clearlyDefined batch API response. Will always return a dictionary which may be empty depending on the response.
Expand Down
8 changes: 6 additions & 2 deletions src/Microsoft.Sbom.Api/Executors/LicenseInformationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ public class LicenseInformationService : ILicenseInformationService
private readonly ILogger log;
private readonly IRecorder recorder;
private readonly HttpClient httpClient;
private const int ClientTimeoutSeconds = 30;

public LicenseInformationService(ILogger log, IRecorder recorder, HttpClient httpClient)
{
Expand All @@ -30,6 +29,11 @@ public LicenseInformationService(ILogger log, IRecorder recorder, HttpClient htt
}

public async Task<List<string>> FetchLicenseInformationFromAPI(List<string> listOfComponentsForApi)
{
return await FetchLicenseInformationFromAPI(listOfComponentsForApi, 30);
}

public async Task<List<string>> FetchLicenseInformationFromAPI(List<string> listOfComponentsForApi, int timeout)
{
var batchSize = 500;
var responses = new List<HttpResponseMessage>();
Expand All @@ -38,7 +42,7 @@ public async Task<List<string>> FetchLicenseInformationFromAPI(List<string> list
var uri = new Uri("https://api.clearlydefined.io/definitions?expand=-files");

httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.Timeout = TimeSpan.FromSeconds(ClientTimeoutSeconds);
httpClient.Timeout = TimeSpan.FromSeconds(timeout);

for (var i = 0; i < listOfComponentsForApi.Count; i += batchSize)
{
Expand Down
9 changes: 9 additions & 0 deletions src/Microsoft.Sbom.Common/Config/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public class Configuration : IConfiguration
private static readonly AsyncLocal<ConfigurationSetting<string>> generationTimestamp = new();
private static readonly AsyncLocal<ConfigurationSetting<bool>> followSymlinks = new();
private static readonly AsyncLocal<ConfigurationSetting<bool>> fetchLicenseInformation = new();
private static readonly AsyncLocal<ConfigurationSetting<int>> licenseInformationTimeout = new();
private static readonly AsyncLocal<ConfigurationSetting<bool>> enablePackageMetadataParsing = new();
private static readonly AsyncLocal<ConfigurationSetting<bool>> deleteManifestDirIfPresent = new();
private static readonly AsyncLocal<ConfigurationSetting<bool>> failIfNoPackages = new();
Expand Down Expand Up @@ -309,6 +310,14 @@ public ConfigurationSetting<bool> FetchLicenseInformation
set => fetchLicenseInformation.Value = value;
}

/// <inheritdoc cref="IConfiguration.LicenseInformationTimeout" />
[DefaultValue(30)]
public ConfigurationSetting<int> LicenseInformationTimeout
{
get => licenseInformationTimeout.Value;
set => licenseInformationTimeout.Value = value;
}

/// <inheritdoc cref="IConfiguration.EnablePackageMetadataParsing" />
[DefaultValue(false)]
public ConfigurationSetting<bool> EnablePackageMetadataParsing
Expand Down
6 changes: 6 additions & 0 deletions src/Microsoft.Sbom.Common/Config/IConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@ public interface IConfiguration
/// </summary>
ConfigurationSetting<bool> FetchLicenseInformation { get; set; }

/// <summary>
/// Specifies the timeout in seconds for fetching the license information. Defaults to 30 seconds. Has no effect if
/// FetchLicenseInformation (li) argument is false or not provided.
/// </summary>
ConfigurationSetting<int> LicenseInformationTimeout { get; set; }

/// <summary>
/// If set to true, we will attempt to locate and parse package metadata files for additional information to include in the SBOM such as .nuspec/.pom files in the local package cache.
/// </summary>
Expand Down
4 changes: 4 additions & 0 deletions src/Microsoft.Sbom.Common/Config/InputConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ public class InputConfiguration : IConfiguration
[DefaultValue(false)]
public ConfigurationSetting<bool> FetchLicenseInformation { get; set; }

/// <inheritdoc cref="IConfiguration.LicenseInformationTimeout" />
[DefaultValue(30)]
public ConfigurationSetting<int> LicenseInformationTimeout { get; set; }

[DefaultValue(false)]
public ConfigurationSetting<bool> EnablePackageMetadataParsing { get; set; }

Expand Down

0 comments on commit f4620fe

Please sign in to comment.