Skip to content

Commit

Permalink
Service Discovery add additional configuration tests, make scheme sel…
Browse files Browse the repository at this point in the history
…ection more intuitive in un-specified case (#3848)

Co-authored-by: Reuben Bond <[email protected]>
  • Loading branch information
github-actions[bot] and ReubenBond committed Apr 22, 2024
1 parent 76b788b commit bf3d887
Show file tree
Hide file tree
Showing 3 changed files with 225 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ internal sealed partial class ConfigurationServiceEndpointProvider : IServiceEnd
private const string DefaultEndpointName = "default";
private readonly string _serviceName;
private readonly string? _endpointName;
private readonly bool _includeAllSchemes;
private readonly string[] _schemes;
private readonly IConfiguration _configuration;
private readonly ILogger<ConfigurationServiceEndpointProvider> _logger;
Expand All @@ -39,6 +40,7 @@ public ConfigurationServiceEndpointProvider(
{
_serviceName = query.ServiceName;
_endpointName = query.EndpointName;
_includeAllSchemes = serviceDiscoveryOptions.Value.AllowAllSchemes && query.IncludedSchemes.Count == 0;
_schemes = ServiceDiscoveryOptions.ApplyAllowedSchemes(query.IncludedSchemes, serviceDiscoveryOptions.Value.AllowedSchemes, serviceDiscoveryOptions.Value.AllowAllSchemes);
_configuration = configuration;
_logger = logger;
Expand Down Expand Up @@ -74,27 +76,17 @@ public ValueTask PopulateAsync(IServiceEndpointBuilder endpoints, CancellationTo
string endpointName;
if (string.IsNullOrWhiteSpace(_endpointName))
{
if (_schemes.Length == 0)
// Treat the scheme as the endpoint name and use the first section with a matching endpoint name which exists
endpointName = DefaultEndpointName;
ReadOnlySpan<string> candidateNames = [DefaultEndpointName, .. _schemes];
foreach (var scheme in candidateNames)
{
// Use the section named "default".
endpointName = DefaultEndpointName;
namedSection = section.GetSection(endpointName);
}
else
{
// Set the ideal endpoint name for error messages.
endpointName = _schemes[0];

// Treat the scheme as the endpoint name and use the first section with a matching endpoint name which exists
foreach (var scheme in _schemes)
var candidate = section.GetSection(scheme);
if (candidate.Exists())
{
var candidate = section.GetSection(scheme);
if (candidate.Exists())
{
endpointName = scheme;
namedSection = candidate;
break;
}
endpointName = scheme;
namedSection = candidate;
break;
}
}
}
Expand Down Expand Up @@ -135,46 +127,60 @@ public ValueTask PopulateAsync(IServiceEndpointBuilder endpoints, CancellationTo
}
}

// Filter the resolved endpoints to only include those which match the specified scheme.
var minIndex = _schemes.Length;
foreach (var ep in resolved)
int resolvedEndpointCount;
if (_includeAllSchemes)
{
if (ep.EndPoint is UriEndPoint uri && uri.Uri.Scheme is { } scheme)
// Include all endpoints.
foreach (var ep in resolved)
{
var index = Array.IndexOf(_schemes, scheme);
if (index >= 0 && index < minIndex)
{
minIndex = index;
}
endpoints.Endpoints.Add(ep);
}

resolvedEndpointCount = resolved.Count;
}

var added = 0;
foreach (var ep in resolved)
else
{
if (ep.EndPoint is UriEndPoint uri && uri.Uri.Scheme is { } scheme)
// Filter the resolved endpoints to only include those which match the specified, allowed schemes.
resolvedEndpointCount = 0;
var minIndex = _schemes.Length;
foreach (var ep in resolved)
{
var index = Array.IndexOf(_schemes, scheme);
if (index >= 0 && index <= minIndex)
if (ep.EndPoint is UriEndPoint uri && uri.Uri.Scheme is { } scheme)
{
++added;
endpoints.Endpoints.Add(ep);
var index = Array.IndexOf(_schemes, scheme);
if (index >= 0 && index < minIndex)
{
minIndex = index;
}
}
}
else

foreach (var ep in resolved)
{
++added;
endpoints.Endpoints.Add(ep);
if (ep.EndPoint is UriEndPoint uri && uri.Uri.Scheme is { } scheme)
{
var index = Array.IndexOf(_schemes, scheme);
if (index >= 0 && index <= minIndex)
{
++resolvedEndpointCount;
endpoints.Endpoints.Add(ep);
}
}
else
{
++resolvedEndpointCount;
endpoints.Endpoints.Add(ep);
}
}
}

if (added == 0)
if (resolvedEndpointCount == 0)
{
Log.ServiceConfigurationNotFound(_logger, _serviceName, configPath);
}
else
{
Log.ConfiguredEndpoints(_logger, _serviceName, configPath, endpoints.Endpoints, added);
Log.ConfiguredEndpoints(_logger, _serviceName, configPath, endpoints.Endpoints, resolvedEndpointCount);
}

return default;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,35 @@ public sealed class ServiceDiscoveryOptions

internal static string[] ApplyAllowedSchemes(IReadOnlyList<string> schemes, IList<string> allowedSchemes, bool allowAllSchemes)
{
if (allowAllSchemes)
if (schemes.Count > 0)
{
if (schemes is string[] array)
if (allowAllSchemes)
{
return array;
}
if (schemes is string[] array && array.Length > 0)
{
return array;
}

return schemes.ToArray();
}
return schemes.ToArray();
}

List<string> result = [];
foreach (var s in schemes)
{
foreach (var allowed in allowedSchemes)
List<string> result = [];
foreach (var s in schemes)
{
if (string.Equals(s, allowed, StringComparison.OrdinalIgnoreCase))
foreach (var allowed in allowedSchemes)
{
result.Add(s);
break;
if (string.Equals(s, allowed, StringComparison.OrdinalIgnoreCase))
{
result.Add(s);
break;
}
}
}

return result.ToArray();
}

return result.ToArray();
// If no schemes were specified, but a set of allowed schemes were specified, allow those.
return allowedSchemes.ToArray();
}
}
Loading

0 comments on commit bf3d887

Please sign in to comment.