Restructure solution layout by module

This commit is contained in:
master
2025-10-28 15:10:40 +02:00
parent 95daa159c4
commit d870da18ce
4103 changed files with 192899 additions and 187024 deletions

View File

@@ -0,0 +1,124 @@
using System.Globalization;
namespace StellaOps.Concelier.Connector.Vndr.Cisco.Configuration;
public sealed class CiscoOptions
{
public const string HttpClientName = "concelier.source.vndr.cisco";
public const string AuthHttpClientName = "concelier.source.vndr.cisco.auth";
public Uri BaseUri { get; set; } = new("https://api.cisco.com/security/advisories/v2/", UriKind.Absolute);
public Uri TokenEndpoint { get; set; } = new("https://id.cisco.com/oauth2/default/v1/token", UriKind.Absolute);
public string ClientId { get; set; } = string.Empty;
public string ClientSecret { get; set; } = string.Empty;
public int PageSize { get; set; } = 100;
public int MaxPagesPerFetch { get; set; } = 5;
public int MaxAdvisoriesPerFetch { get; set; } = 200;
public TimeSpan InitialBackfillWindow { get; set; } = TimeSpan.FromDays(30);
public TimeSpan RequestDelay { get; set; } = TimeSpan.FromMilliseconds(250);
public TimeSpan RequestTimeout { get; set; } = TimeSpan.FromSeconds(30);
public TimeSpan FailureBackoff { get; set; } = TimeSpan.FromMinutes(5);
public TimeSpan TokenRefreshSkew { get; set; } = TimeSpan.FromMinutes(1);
public string LastModifiedPathTemplate { get; set; } = "advisories/lastmodified/{0}";
public void Validate()
{
if (BaseUri is null || !BaseUri.IsAbsoluteUri)
{
throw new InvalidOperationException("Cisco BaseUri must be an absolute URI.");
}
if (TokenEndpoint is null || !TokenEndpoint.IsAbsoluteUri)
{
throw new InvalidOperationException("Cisco TokenEndpoint must be an absolute URI.");
}
if (string.IsNullOrWhiteSpace(ClientId))
{
throw new InvalidOperationException("Cisco clientId must be configured.");
}
if (string.IsNullOrWhiteSpace(ClientSecret))
{
throw new InvalidOperationException("Cisco clientSecret must be configured.");
}
if (PageSize is < 1 or > 100)
{
throw new InvalidOperationException("Cisco PageSize must be between 1 and 100.");
}
if (MaxPagesPerFetch <= 0)
{
throw new InvalidOperationException("Cisco MaxPagesPerFetch must be greater than zero.");
}
if (MaxAdvisoriesPerFetch <= 0)
{
throw new InvalidOperationException("Cisco MaxAdvisoriesPerFetch must be greater than zero.");
}
if (InitialBackfillWindow <= TimeSpan.Zero)
{
throw new InvalidOperationException("Cisco InitialBackfillWindow must be positive.");
}
if (RequestDelay < TimeSpan.Zero)
{
throw new InvalidOperationException("Cisco RequestDelay cannot be negative.");
}
if (RequestTimeout <= TimeSpan.Zero)
{
throw new InvalidOperationException("Cisco RequestTimeout must be positive.");
}
if (FailureBackoff <= TimeSpan.Zero)
{
throw new InvalidOperationException("Cisco FailureBackoff must be positive.");
}
if (TokenRefreshSkew < TimeSpan.FromSeconds(5))
{
throw new InvalidOperationException("Cisco TokenRefreshSkew must be at least 5 seconds.");
}
if (string.IsNullOrWhiteSpace(LastModifiedPathTemplate))
{
throw new InvalidOperationException("Cisco LastModifiedPathTemplate must be configured.");
}
}
public Uri BuildLastModifiedUri(DateOnly date, int pageIndex, int pageSize)
{
if (pageIndex < 1)
{
throw new ArgumentOutOfRangeException(nameof(pageIndex), pageIndex, "Page index must be >= 1.");
}
if (pageSize is < 1 or > 100)
{
throw new ArgumentOutOfRangeException(nameof(pageSize), pageSize, "Page size must be between 1 and 100.");
}
var path = string.Format(CultureInfo.InvariantCulture, LastModifiedPathTemplate, date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture));
var builder = new UriBuilder(BaseUri);
var basePath = builder.Path.TrimEnd('/');
builder.Path = $"{basePath}/{path}".Replace("//", "/", StringComparison.Ordinal);
var query = $"pageIndex={pageIndex.ToString(CultureInfo.InvariantCulture)}&pageSize={pageSize.ToString(CultureInfo.InvariantCulture)}";
builder.Query = string.IsNullOrEmpty(builder.Query) ? query : builder.Query.TrimStart('?') + "&" + query;
return builder.Uri;
}
}