-
Notifications
You must be signed in to change notification settings - Fork 98
Open
Description
Hello there,
I suggest adding the [it self gateway first definition] property to ensure that Gateway is the first definition in the list. Full code implementation in the comments, thanks!
using Microsoft.OpenApi.Models;
using MMLib.SwaggerForOcelot.Aggregates;
using System;
using System.Collections.Generic;
namespace MMLib.SwaggerForOcelot.Configuration
{
/// <summary>
/// Options for generating docs of ApiGateway.
/// </summary>
public class OcelotSwaggerGenOptions
{
/// <summary>
/// Gets or sets a value indicating whether [generate docs for aggregates].
/// </summary>
/// <value>
/// <c>true</c> if [generate docs for aggregates]; otherwise, <c>false</c>.
/// </value>
public bool GenerateDocsForAggregates { get; set; } = false;
/// <summary>
/// Gets or sets a value indicating whether [generate docs for gateway it self].
/// </summary>
/// <value>
/// <c>true</c> if [generate docs for gateway it self]; otherwise, <c>false</c>.
/// </value>
public bool GenerateDocsForGatewayItSelf { get; set; } = false;
/// <summary>
/// Gets or sets a value indicating whether [it self gateway first definition].
/// </summary>
/// <value>
/// <c>true</c> if [it self gateway first definition]; otherwise, <c>false</c>.
/// </value>
public bool IsItSelfGatewayFirstDefinition { get; set; } = false;
/// <summary>
/// Gets or sets a value indicating downstream docs cache expire duration in seconds.
/// </summary>
/// <value>
/// <c>0</c> if it won't be cached; otherwise, cache expire duration in seconds.
/// </value>
public TimeSpan DownstreamDocsCacheExpire { get; set; } = TimeSpan.Zero;
/// <summary>
/// Generates docs for gateway it self with options.
/// </summary>
/// <param name="options">Gateway itself docs generation options.</param>
public void GenerateDocsDocsForGatewayItSelf(Action<OcelotGatewayItSelfSwaggerGenOptions> options = null)
{
GenerateDocsForGatewayItSelf = true;
OcelotGatewayItSelfSwaggerGenOptions = new OcelotGatewayItSelfSwaggerGenOptions();
options?.Invoke(OcelotGatewayItSelfSwaggerGenOptions);
GatewayDocsTitle = OcelotGatewayItSelfSwaggerGenOptions.GatewayDocsTitle ?? GatewayDocsTitle;
GatewayDocsOpenApiInfo = OcelotGatewayItSelfSwaggerGenOptions.GatewayDocsOpenApiInfo ?? GatewayDocsOpenApiInfo;
}
/// <summary>
/// Adds a mapping between Ocelot's AuthenticationProviderKey and Swagger's securityScheme
/// If a route has a match, security definition will be added to the endpoint with the provided AllowedScopes from the config.
/// </summary>
/// <param name="authenticationProviderKey"></param>
/// <param name="securityScheme"></param>
public void AddAuthenticationProviderKeyMapping(string authenticationProviderKey, string securityScheme)
{
AuthenticationProviderKeyMap.Add(authenticationProviderKey, securityScheme);
}
/// <summary>
/// Register aggregate docs generator post process.
/// </summary>
public Action<SwaggerAggregateRoute, IEnumerable<RouteDocs>, OpenApiPathItem, OpenApiDocument> AggregateDocsGeneratorPostProcess { get; set; }
= AggregateRouteDocumentationGenerator.DefaultPostProcess;
internal static OcelotSwaggerGenOptions Default { get; } = new OcelotSwaggerGenOptions();
internal const string AggregatesKey = "aggregates";
internal const string GatewayKey = "gateway";
internal string GatewayDocsTitle { get; set; } = "Gateway";
internal OpenApiInfo GatewayDocsOpenApiInfo { get; set; } = new()
{
Title = "Gateway",
Version = GatewayKey,
};
internal OcelotGatewayItSelfSwaggerGenOptions OcelotGatewayItSelfSwaggerGenOptions { get; private set; }
internal Dictionary<string, string> AuthenticationProviderKeyMap { get; } = new();
}
}
using Kros.Utils;
using Microsoft.Extensions.Options;
using MMLib.SwaggerForOcelot.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
namespace MMLib.SwaggerForOcelot.Repositories
{
/// <summary>
/// Provider for obtaining <see cref="SwaggerEndPointOptions"/>.
/// </summary>
public class SwaggerEndPointProvider : ISwaggerEndPointProvider
{
private readonly Lazy<Dictionary<string, SwaggerEndPointOptions>> _swaggerEndPoints;
private readonly IOptionsMonitor<List<SwaggerEndPointOptions>> _swaggerEndPointsOptions;
private readonly OcelotSwaggerGenOptions _options;
/// <summary>
/// Initializes a new instance of the <see cref="SwaggerEndPointProvider"/> class.
/// </summary>
/// <param name="swaggerEndPoints">The swagger end points.</param>
public SwaggerEndPointProvider(
IOptionsMonitor<List<SwaggerEndPointOptions>> swaggerEndPoints,
OcelotSwaggerGenOptions options)
{
_swaggerEndPointsOptions = Check.NotNull(swaggerEndPoints, nameof(swaggerEndPoints));
_swaggerEndPoints = new Lazy<Dictionary<string, SwaggerEndPointOptions>>(Init);
_options = options;
}
/// <inheritdoc/>
public IReadOnlyList<SwaggerEndPointOptions> GetAll()
=> _swaggerEndPoints.Value.Values.ToList();
/// <inheritdoc/>
public SwaggerEndPointOptions GetByKey(string key)
=> _swaggerEndPoints.Value[$"/{key}"];
private Dictionary<string, SwaggerEndPointOptions> Init()
{
var ret = _swaggerEndPointsOptions.CurrentValue.Select(p => KeyValuePair.Create($"/{p.KeyToPath}", p));
if (_options.GenerateDocsForAggregates)
{
ret = ret.Append(AddEndpoint(OcelotSwaggerGenOptions.AggregatesKey, "Aggregates"));
}
if (_options.GenerateDocsForGatewayItSelf)
{
var gateway = AddEndpoint(OcelotSwaggerGenOptions.GatewayKey, _options.GatewayDocsTitle);
ret = _options.IsItSelfGatewayFirstDefinition ?
ret.Prepend(gateway) :
ret.Append(gateway);
}
return ret.ToDictionary(x => x.Key, x => x.Value);
}
private static KeyValuePair<string, SwaggerEndPointOptions> AddEndpoint(string key, string description)
=> KeyValuePair.Create($"/{key}", new SwaggerEndPointOptions()
{
Key = key,
TransformByOcelotConfig = false,
Config = new List<SwaggerEndPointConfig>() {
new SwaggerEndPointConfig()
{
Name = description,
Version = key,
Url = ""
}
}
});
}
}
Metadata
Metadata
Assignees
Labels
No labels