From 6a91c0e81b74e1592d22912f496e8e48c211be91 Mon Sep 17 00:00:00 2001 From: Apollo3zehn Date: Fri, 15 Mar 2024 21:35:13 +0100 Subject: [PATCH] Follow Nexus changes --- .editorconfig | 29 ++- .gitignore | 2 + Directory.Build.props | 2 +- src/Nexus.Sources.Federation/Federation.cs | 201 +++++++++--------- .../Nexus.Sources.Federation.csproj | 4 +- .../FederationTests.cs | 2 +- .../Nexus.Sources.Federation.Tests.csproj | 2 +- 7 files changed, 130 insertions(+), 112 deletions(-) diff --git a/.editorconfig b/.editorconfig index 0ccff01..32c963d 100755 --- a/.editorconfig +++ b/.editorconfig @@ -1,10 +1,31 @@ -# How to format: -# (1) Add dotnet_diagnostic.XXXX.severity = error -# (2) Run dotnet-format: dotnet format --diagnostics XXXX +# How to apply single rule: +# Run dotnet format --diagnostics XXXX --severity info + +# How to apply all rules: +# Run dotnet format --severity error/info/warn/ + +[*] +trim_trailing_whitespace = true [*.cs] # "run cleanup": https://betterprogramming.pub/enforce-net-code-style-with-editorconfig-d2f0d79091ac -# TODO: build real editorconfig file: https://github.com/dotnet/roslyn/blob/main/.editorconfig +# TODO: build real editorconfig file: https://github.com/dotnet/roslyn/blob/main/.editorconfig + +# Prefer var +csharp_style_var_for_built_in_types = false +csharp_style_var_when_type_is_apparent = true +csharp_style_var_elsewhere = true +dotnet_diagnostic.IDE0007.severity = warning + +# Make field +dotnet_diagnostic.IDE0044.severity = warning + +# Use file scoped namespace declarations +dotnet_diagnostic.IDE0161.severity = error +csharp_style_namespace_declarations = file_scoped + +# Collection initialization can be simplified +dotnet_diagnostic.IDE0300.severity = warning # Enable naming rule violation errors on build (alternative: dotnet_analyzer_diagnostic.category-Style.severity = error) dotnet_diagnostic.IDE1006.severity = error diff --git a/.gitignore b/.gitignore index e95dc5b..4bbc1fa 100755 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ .vs/ +.venv/ + artifacts/ BenchmarkDotNet.Artifacts diff --git a/Directory.Build.props b/Directory.Build.props index a73d076..db678da 100755 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,7 +2,7 @@ true - net7.0 + net8.0 enable enable true diff --git a/src/Nexus.Sources.Federation/Federation.cs b/src/Nexus.Sources.Federation/Federation.cs index a451fb9..4d9cb53 100644 --- a/src/Nexus.Sources.Federation/Federation.cs +++ b/src/Nexus.Sources.Federation/Federation.cs @@ -6,141 +6,136 @@ using Nexus.DataModel; using Nexus.Extensibility; -namespace Nexus.Sources +namespace Nexus.Sources; + +[ExtensionDescription( + "Provides access to other Nexus databases.", + "https://github.com/Apollo3zehn/nexus-sources-federation", + "https://github.com/Apollo3zehn/nexus-sources-federation")] +public class Federation : IDataSource { - [ExtensionDescription( - "Provides access to other Nexus databases.", - "https://github.com/Apollo3zehn/nexus-sources-federation", - "https://github.com/Apollo3zehn/nexus-sources-federation")] - public class Federation : IDataSource - { - private DataSourceContext _context = default!; - private Api.INexusClient _nexusClient = default!; - private string _sourcePath = "/"; - private string _mountPoint = "/"; - private string _includePattern = default!; + private DataSourceContext _context = default!; + private Api.INexusClient _nexusClient = default!; + private string _sourcePath = "/"; + private string _mountPoint = "/"; + private string _includePattern = default!; - private static JsonSerializerOptions _jsonSerializerOptions; + private static readonly JsonSerializerOptions _jsonSerializerOptions; - static Federation() - { - _jsonSerializerOptions = new JsonSerializerOptions(); - _jsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); - } + static Federation() + { + _jsonSerializerOptions = new JsonSerializerOptions(); + _jsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); + } - public Func CreateNexusClient { get; set; } - = httpClient => new Api.NexusClient(httpClient); + public Func CreateNexusClient { get; set; } + = httpClient => new Api.NexusClient(httpClient); - public Task SetContextAsync(DataSourceContext context, ILogger logger, CancellationToken cancellationToken) - { - _context = context; + public Task SetContextAsync(DataSourceContext context, ILogger logger, CancellationToken cancellationToken) + { + _context = context; - // http client - if (_context.ResourceLocator is null) - throw new Exception("The resource locator must be set."); + // http client + if (_context.ResourceLocator is null) + throw new Exception("The resource locator must be set."); - var httpClient = new HttpClient() - { - BaseAddress = _context.ResourceLocator - }; + var httpClient = new HttpClient() + { + BaseAddress = _context.ResourceLocator + }; - // token - var token = _context.SourceConfiguration?.GetStringValue($"access-token"); + // token + var token = (_context.SourceConfiguration?.GetStringValue($"access-token")) ?? throw new Exception("The access-token property is not set."); + httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token); - if (token is null) - throw new Exception("The access-token property is not set."); + _nexusClient = CreateNexusClient(httpClient); - httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token); + // source-path + var sourcePath = _context.SourceConfiguration?.GetStringValue($"source-path"); - _nexusClient = CreateNexusClient(httpClient); + if (sourcePath is not null) + _sourcePath = '/' + sourcePath.Trim('/'); - // source-path - var sourcePath = _context.SourceConfiguration?.GetStringValue($"source-path"); + // mount-point + var mountPoint = _context.SourceConfiguration?.GetStringValue($"mount-point"); - if (sourcePath is not null) - _sourcePath = '/' + sourcePath.Trim('/'); + if (mountPoint is not null) + _mountPoint = '/' + mountPoint.Trim('/'); - // mount-point - var mountPoint = _context.SourceConfiguration?.GetStringValue($"mount-point"); + // include-pattern + var includePattern = _context.SourceConfiguration?.GetStringValue($"include-pattern"); + _includePattern = includePattern ?? ""; - if (mountPoint is not null) - _mountPoint = '/' + mountPoint.Trim('/'); + return Task.CompletedTask; + } - // include-pattern - var includePattern = _context.SourceConfiguration?.GetStringValue($"include-pattern"); - _includePattern = includePattern ?? ""; + public async Task GetCatalogRegistrationsAsync(string path, CancellationToken cancellationToken) + { + if (path == "/") + path = _mountPoint; - return Task.CompletedTask; - } + var catalogInfos = await _nexusClient.Catalogs.GetChildCatalogInfosAsync(ToSourcePathPrefixedCatalogId(path), cancellationToken); - public async Task GetCatalogRegistrationsAsync(string path, CancellationToken cancellationToken) - { - if (path == "/") - path = _mountPoint; + return catalogInfos + .Where(catalogInfo => Regex.IsMatch(catalogInfo.Id, _includePattern)) + .Select(catalogInfo => new CatalogRegistration(ToMountPointPrefixedCatalogId(catalogInfo.Id), catalogInfo.Title, IsTransient: true)) + .ToArray(); + } - var catalogInfos = await _nexusClient.Catalogs.GetChildCatalogInfosAsync(ToSourcePathPrefixedCatalogId(path), cancellationToken); + public async Task GetCatalogAsync(string catalogId, CancellationToken cancellationToken) + { + var resourceCatalog = await _nexusClient.Catalogs.GetAsync(ToSourcePathPrefixedCatalogId(catalogId), cancellationToken); + resourceCatalog = resourceCatalog with { Id = catalogId }; - return catalogInfos - .Where(catalogInfo => Regex.IsMatch(catalogInfo.Id, _includePattern)) - .Select(catalogInfo => new CatalogRegistration(ToMountPointPrefixedCatalogId(catalogInfo.Id), catalogInfo.Title, IsTransient: true)) - .ToArray(); - } + var jsonString = JsonSerializer.Serialize(resourceCatalog, _jsonSerializerOptions); + var actualResourceCatalog = JsonSerializer.Deserialize(jsonString, _jsonSerializerOptions)!; - public async Task GetCatalogAsync(string catalogId, CancellationToken cancellationToken) - { - var resourceCatalog = await _nexusClient.Catalogs.GetAsync(ToSourcePathPrefixedCatalogId(catalogId)); - resourceCatalog = resourceCatalog with { Id = catalogId }; + return actualResourceCatalog; + } - var jsonString = JsonSerializer.Serialize(resourceCatalog, _jsonSerializerOptions); - var actualResourceCatalog = JsonSerializer.Deserialize(jsonString, _jsonSerializerOptions)!; + public async Task GetAvailabilityAsync(string catalogId, DateTime begin, DateTime end, CancellationToken cancellationToken) + { + var availability = await _nexusClient.Catalogs + .GetAvailabilityAsync(ToSourcePathPrefixedCatalogId(catalogId), begin, end, end - begin, cancellationToken); - return actualResourceCatalog; - } + return availability.Data[0]; + } - public async Task GetAvailabilityAsync(string catalogId, DateTime begin, DateTime end, CancellationToken cancellationToken) - { - var availability = await _nexusClient.Catalogs - .GetAvailabilityAsync(ToSourcePathPrefixedCatalogId(catalogId), begin, end, end - begin, cancellationToken); + public async Task<(DateTime Begin, DateTime End)> GetTimeRangeAsync(string catalogId, CancellationToken cancellationToken) + { + var timeRange = await _nexusClient.Catalogs + .GetTimeRangeAsync(ToSourcePathPrefixedCatalogId(catalogId), cancellationToken); - return availability.Data[0]; - } + return (timeRange.Begin, timeRange.End); + } - public async Task<(DateTime Begin, DateTime End)> GetTimeRangeAsync(string catalogId, CancellationToken cancellationToken) + public async Task ReadAsync(DateTime begin, DateTime end, ReadRequest[] requests, ReadDataHandler readData, IProgress progress, CancellationToken cancellationToken) + { + foreach (var request in requests) { - var timeRange = await _nexusClient.Catalogs - .GetTimeRangeAsync(ToSourcePathPrefixedCatalogId(catalogId), cancellationToken); - - return (timeRange.Begin, timeRange.End); - } + var response = await _nexusClient.Data.GetStreamAsync(ToSourcePathPrefixedCatalogId(request.CatalogItem.ToPath()), begin, end, cancellationToken); + var stream = await response.Content.ReadAsStreamAsync(cancellationToken); + var targetBuffer = request.Data; - public async Task ReadAsync(DateTime begin, DateTime end, ReadRequest[] requests, ReadDataHandler readData, IProgress progress, CancellationToken cancellationToken) - { - foreach (var request in requests) + while (targetBuffer.Length > 0) { - var response = await _nexusClient.Data.GetStreamAsync(ToSourcePathPrefixedCatalogId(request.CatalogItem.ToPath()), begin, end, cancellationToken); - var stream = await response.Content.ReadAsStreamAsync(); - var targetBuffer = request.Data; - - while (targetBuffer.Length > 0) - { - var bytesRead = await stream.ReadAsync(targetBuffer); - targetBuffer = targetBuffer.Slice(bytesRead); - } - - request.Status.Span.Fill(1); + var bytesRead = await stream.ReadAsync(targetBuffer, cancellationToken); + targetBuffer = targetBuffer[bytesRead..]; } - } - private string ToMountPointPrefixedCatalogId(string catalogId) - { - // absolute, relative - return Path.Combine(_mountPoint, catalogId.Substring(_sourcePath.Length).TrimStart('/')); + request.Status.Span.Fill(1); } + } - private string ToSourcePathPrefixedCatalogId(string catalogId) - { - // absolute, relative - return Path.Combine(_sourcePath, catalogId.Substring(_mountPoint.Length).TrimStart('/')); - } + private string ToMountPointPrefixedCatalogId(string catalogId) + { + // absolute, relative + return Path.Combine(_mountPoint, catalogId[_sourcePath.Length..].TrimStart('/')); + } + + private string ToSourcePathPrefixedCatalogId(string catalogId) + { + // absolute, relative + return Path.Combine(_sourcePath, catalogId[_mountPoint.Length..].TrimStart('/')); } } diff --git a/src/Nexus.Sources.Federation/Nexus.Sources.Federation.csproj b/src/Nexus.Sources.Federation/Nexus.Sources.Federation.csproj index b216f94..d044c2b 100644 --- a/src/Nexus.Sources.Federation/Nexus.Sources.Federation.csproj +++ b/src/Nexus.Sources.Federation/Nexus.Sources.Federation.csproj @@ -6,8 +6,8 @@ - - + + runtime;native diff --git a/tests/Nexus.Sources.Federation.Tests/FederationTests.cs b/tests/Nexus.Sources.Federation.Tests/FederationTests.cs index f01de5b..ce7d9bb 100644 --- a/tests/Nexus.Sources.Federation.Tests/FederationTests.cs +++ b/tests/Nexus.Sources.Federation.Tests/FederationTests.cs @@ -32,7 +32,7 @@ public async Task ProvidesCatalogRegistrations(string? sourcePath, string? mount It.IsAny(), It.IsAny() )) - .ReturnsAsync((string catalogId, CancellationToken cancellationToken) => + .ReturnsAsync((string catalogId, CancellationToken cancellationToken) => { Assert.True(catalogId.StartsWith('/')); diff --git a/tests/Nexus.Sources.Federation.Tests/Nexus.Sources.Federation.Tests.csproj b/tests/Nexus.Sources.Federation.Tests/Nexus.Sources.Federation.Tests.csproj index f89d76e..ebea1a0 100644 --- a/tests/Nexus.Sources.Federation.Tests/Nexus.Sources.Federation.Tests.csproj +++ b/tests/Nexus.Sources.Federation.Tests/Nexus.Sources.Federation.Tests.csproj @@ -8,7 +8,7 @@ - + all