forked from microsoft/OSSGadget
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Migrate most of the logic that doesn't depend on CLI to a separate sh…
…ared library (microsoft#295) * Moved shared logic that isn't relevant to the CLI to Shared-lib. This way the libraries can access that logic and not be dependent on CLI Specific logic. * Update Find Squats to use the new Shared and Shared-lib structure. * Fix the FindSourceTool to use the new lib stuff. * Update the rest of the OSS Gadget tools to use the HTTP Client from HttpClientFactory instead of the CommonInitialization WebClient. Still need to fix the tests. * Removed import of shared in oss-download that was causing problems for it. * Add support for old behavior of single static httpclient when none is provided. Fixes shared lib nuget. * Namespaces cleanup Fix no default parametereless constructor for gadgets. * Remove Unneeded Usings The usings were causing the default static HttpHandler to become disposed prematurely. Restore ENvironment variable setting to baseprojectmanager. * Expand PyPi source finding code. * Fix CodeQL Workflow for .NET 6 * Allow empty construction of DefaultHttpClient * Use DefaultHttpClientFactory for CLIs Update DefaultHttpClientFactory to use the environment variable for the user agent. * Remove CommonInitialization After removal of the static reference to httpclient this no longer did anything. * Restore parameterless constructors for CLI objects These constructors call into the IHTTPClientFactory constructor with DefaultHttpClientFactory. * Second set of constructors * Use the restored parameterless constructors. Co-authored-by: Gabe Stocco <[email protected]>
- Loading branch information
Showing
96 changed files
with
1,869 additions
and
1,118 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright (c) Microsoft Corporation. Licensed under the MIT License. | ||
|
||
namespace Microsoft.CST.OpenSource | ||
{ | ||
using Microsoft.CST.OpenSource.Helpers; | ||
using System; | ||
using System.Net.Http; | ||
|
||
/// <summary> | ||
/// This is the HttpClientFactory that will be used if one is not specified. This factory lazily constructs a single HttpClient and presents it for reuse to reduce resource usage. | ||
/// </summary> | ||
public sealed class DefaultHttpClientFactory : IHttpClientFactory | ||
{ | ||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0044:Add readonly modifier", Justification = "Modified through reflection.")] | ||
private string ENV_HTTPCLIENT_USER_AGENT = "OSSDL"; | ||
|
||
public DefaultHttpClientFactory(string? userAgent = null) | ||
{ | ||
EnvironmentHelper.OverrideEnvironmentVariables(this); | ||
|
||
_httpClientLazy = new(() => | ||
{ | ||
HttpClient cli = new(handler); | ||
cli.DefaultRequestHeaders.UserAgent.ParseAdd(userAgent ?? ENV_HTTPCLIENT_USER_AGENT); | ||
return cli; | ||
}); | ||
} | ||
|
||
private static readonly SocketsHttpHandler handler = new() | ||
{ | ||
AllowAutoRedirect = true, | ||
UseCookies = false, | ||
MaxAutomaticRedirections = 5, | ||
PooledConnectionIdleTimeout = TimeSpan.FromSeconds(30), | ||
PooledConnectionLifetime = TimeSpan.FromSeconds(30), | ||
AutomaticDecompression = System.Net.DecompressionMethods.All, | ||
}; | ||
|
||
private readonly Lazy<HttpClient> _httpClientLazy; | ||
|
||
/// <summary> | ||
/// Returns the singleton HttpClient for this factory. | ||
/// </summary> | ||
/// <param name="name"></param> | ||
/// <returns></returns> | ||
public HttpClient CreateClient(string name) => _httpClientLazy.Value; | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
src/Shared-lib/Exceptions/InvalidProjectManagerException.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// Copyright (c) Microsoft Corporation. Licensed under the MIT License. | ||
|
||
namespace Microsoft.CST.OpenSource.Exceptions | ||
{ | ||
using System; | ||
|
||
/// <summary> | ||
/// Exception thrown when the PackageURL has an invalid manager.. | ||
/// </summary> | ||
public class InvalidProjectManagerException : Exception | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="InvalidProjectManagerException"/> class. | ||
/// </summary> | ||
public InvalidProjectManagerException(PackageURL packageUrl) | ||
: base($"The package URL: {packageUrl} has an invalid Project Manager.") | ||
{ | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
// Copyright (c) Microsoft Corporation. Licensed under the MIT License. | ||
|
||
namespace Microsoft.CST.OpenSource.Helpers | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
/// <summary> | ||
/// Static helper methods for validating parameters. | ||
/// </summary> | ||
public static class Check | ||
{ | ||
/// <summary> | ||
/// Checks that the given parameter is not null, empty, or whitespace. | ||
/// </summary> | ||
/// <param name="paramName">The name of the parameter. Can be retrieved by using nameof(parameter).</param> | ||
/// <param name="value">The value of the parameter.</param> | ||
/// <returns>The value of the parameter if it passes the validation.</returns> | ||
/// <exception cref="ArgumentNullException">The parameter value is null, empty, or whitespace.</exception> | ||
public static string NotEmptyOrWhitespace(string paramName, string? value) | ||
{ | ||
// The parameterName can't be null so explicitly check (can't call EnsureIsNotNullOrWhitespace in this case!) | ||
if (string.IsNullOrWhiteSpace(paramName)) | ||
{ | ||
throw new ArgumentNullException(nameof(paramName)); | ||
} | ||
|
||
if (string.IsNullOrWhiteSpace(value)) | ||
{ | ||
throw new ArgumentNullException(value); | ||
} | ||
|
||
return value; | ||
} | ||
|
||
/// <summary> | ||
/// Checks that the given parameter is not null. | ||
/// </summary> | ||
/// <typeparam name="T">The type of the parameter.</typeparam> | ||
/// <param name="paramName">The name of the parameter. Can be retrieved by using nameof(parameter).</param> | ||
/// <param name="value">The value of the parameter.</param> | ||
/// <param name="message">An optional message that will be included as apart of the exception if the value is null.</param> | ||
/// <returns>The value of the parameter if it passes the validation.</returns> | ||
/// <exception cref="ArgumentNullException">The parameter value is null.</exception> | ||
public static T NotNull<T>(string paramName, T? value, string? message = null) | ||
{ | ||
NotEmptyOrWhitespace(nameof(paramName), paramName); | ||
message = message ?? $"Value cannot be null. (Parameter '{paramName}')"; | ||
|
||
if (value == null) | ||
{ | ||
throw new ArgumentNullException(paramName, message); | ||
} | ||
|
||
return value; | ||
} | ||
|
||
/// <summary> | ||
/// Check that the given parameter is in the enum. | ||
/// </summary> | ||
/// <typeparam name="T">The enum type of the parameter.</typeparam> | ||
/// <param name="paramName">The name of the parameter. Can be retrieved by using nameof(parameter).</param> | ||
/// <param name="value">The value of the parameter.</param> | ||
/// <returns>The value of the parameter if it passes the validation.</returns> | ||
/// <exception cref="ArgumentOutOfRangeException">The parameter value is not apart of the enum.</exception> | ||
public static T IsInEnum<T>(string paramName, T value) | ||
where T : Enum | ||
{ | ||
NotEmptyOrWhitespace(nameof(paramName), paramName); | ||
NotNull(paramName, value); | ||
|
||
if (!Enum.IsDefined(value.GetType(), value)) | ||
{ | ||
throw new ArgumentOutOfRangeException( | ||
paramName, | ||
$"The value is {value} is not a valid value of {value.GetType()}."); | ||
} | ||
|
||
return value; | ||
} | ||
|
||
/// <summary> | ||
/// Ensures that the provided enumerable is not null and contains at least one item. | ||
/// </summary> | ||
/// <typeparam name="T">The type of object contained in the enumerable.</typeparam> | ||
/// <param name="parameterName">Parameter name (embedded in exception if thrown).</param> | ||
/// <param name="parameterValue">The value to validate.</param> | ||
/// <exception cref="ArgumentNullException"> Enumerable object is null.</exception> | ||
/// <exception cref="ArgumentOutOfRangeException">Enumerable does not contain at least 1 object.</exception> | ||
public static void NotNullOrEmpty<T>( | ||
string parameterName, | ||
IEnumerable<T>? parameterValue) | ||
{ | ||
NotNullAndHasMinimumCount(parameterName, parameterValue, 1); | ||
} | ||
|
||
/// <summary> | ||
/// Ensures that the provided enumerable is not null and contains at least minimumCount elements. | ||
/// </summary> | ||
/// <typeparam name="T">The type of object contained in the enumerable.</typeparam> | ||
/// <param name="parameterName">Parameter name (embedded in exception if thrown).</param> | ||
/// <param name="parameterValue">The value to validate.</param> | ||
/// <param name="minimumCount">The minimum number of items required in the enumerable.</param> | ||
/// <exception cref="ArgumentNullException">Enumerable object is null.</exception> | ||
/// <exception cref="ArgumentOutOfRangeException">Enumerable does not contain at least <paramref name="minimumCount"/> number of objects.</exception> | ||
public static void NotNullAndHasMinimumCount<T>( | ||
string parameterName, | ||
IEnumerable<T>? parameterValue, | ||
int minimumCount) | ||
{ | ||
NotEmptyOrWhitespace(nameof(parameterName), parameterName); | ||
|
||
if (parameterValue == null) | ||
{ | ||
throw new ArgumentNullException(parameterName); | ||
} | ||
|
||
if (parameterValue.Count() < minimumCount) | ||
{ | ||
throw new ArgumentOutOfRangeException( | ||
parameterName, | ||
$"{parameterName} does not contain at least {minimumCount} elements."); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// Copyright (c) Microsoft Corporation. Licensed under the MIT License. | ||
|
||
namespace Microsoft.CST.OpenSource.Helpers | ||
{ | ||
using System; | ||
using System.Reflection; | ||
|
||
public class EnvironmentHelper | ||
{ | ||
public static NLog.ILogger Logger { get; set; } = NLog.LogManager.GetCurrentClassLogger(); | ||
|
||
/// <summary> | ||
/// Overrides static members starting with ENV_ with the respective environment variables.Allows | ||
/// users to easily override fields like API endpoint roots. Only strings are supported. | ||
/// </summary> | ||
/// <param name="targetObject"> Examine this object (using reflection) </param> | ||
public static void OverrideEnvironmentVariables(object targetObject) | ||
{ | ||
foreach (FieldInfo fieldInfo in targetObject.GetType().GetFields(BindingFlags.Static | | ||
BindingFlags.Public | | ||
BindingFlags.NonPublic)) | ||
{ | ||
if (fieldInfo.FieldType.FullName == "System.String" && | ||
fieldInfo.Name.StartsWith("ENV_") && | ||
fieldInfo.Name.Length > 4) | ||
{ | ||
string? bareName = fieldInfo.Name[4..]; | ||
|
||
string? value = Environment.GetEnvironmentVariable(bareName); | ||
if (value != null) | ||
{ | ||
Logger.Debug("Assiging value of {0} to {1}", bareName, fieldInfo.Name); | ||
fieldInfo.SetValue(null, value); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
src/Shared/Helpers/StringExtensions.cs → src/Shared-lib/Helpers/StringExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.