Burgyn / MMLib.SwaggerForOcelot

This repo contains swagger extension for ocelot.
MIT License
352 stars 94 forks source link

Programmatic attempt to add Swagger Endpoints #152

Closed kurtisane closed 3 years ago

kurtisane commented 3 years ago

Hi, I kind of followed following issue : https://github.com/Burgyn/MMLib.SwaggerForOcelot/pull/105 https://github.com/Burgyn/MMLib.SwaggerForOcelot/issues/104

I just get a blank view. So opening localhost/swagger/docs goes somewhere, but its just white background. What am I missing ?

And implemented as follows :

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using MMLib.SwaggerForOcelot.Configuration;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using MyDomain.Common.Extensions;
using MyDomain.Common.Logic.Extensions;
using Serilog;

namespace OcelotAPIGateway
{
    public class Program
    {
        static readonly string AllowedOrigins = "_allowedOrigins";

        private static List<string> origins =
            new List<string>()
            {
                "http://localhost:4200"
            };

        public static void Main(string[] args)
        {
            var configuration = new ConfigurationBuilder().Build();
            new WebHostBuilder()
                .UseKestrel()
                .UseSerilog()
                .ConfigureKestrel((context, options) =>
                {
                    options.Listen(IPAddress.Any, 80);
                })
                .UseContentRoot(Directory.GetCurrentDirectory())
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config
                        .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
                        .AddJsonFile("appsettings.json", true, true)
                        .AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true,
                            true)
                        .AddJsonFile("ocelotConfiguration.json")
                        .AddEnvironmentVariables();
                    configuration = config.Build();
                })
                .ConfigureServices(s =>
                {
                    s.AddSwaggerForOcelot(configuration);
                    s.Configure<List<SwaggerEndPointOptions>>(options =>
                    {
                        options.AddRange(CreateSwaggerEndPointOption(configuration));
                    });
                    s.AddOcelot();
                    s.AddCors(options =>
                    {
                        options.AddPolicy(name: AllowedOrigins,
                            builder =>
                            {
                                if (Environment.GetEnvironmentVariable("CORS_ALLOW_ALL") == "True")
                                {
                                    builder
                                        .AllowAnyOrigin()
                                        .AllowAnyMethod()
                                        .AllowAnyHeader();
                                }
                                else
                                {
                                    builder
                                        .WithOrigins(origins.ToArray())
                                        .SetIsOriginAllowedToAllowWildcardSubdomains()
                                        .AllowAnyMethod()
                                        .AllowAnyHeader();
                                }
                            });
                    });
                })
                .Configure(app =>
                {
                    app.UseSwagger();
                    app.UseWebSockets();
                    app.UseCors(AllowedOrigins);
                    app.UseOcelot().Wait();
                    app.UseSwaggerForOcelotUI(opt =>
                    {
                        opt.PathToSwaggerGenerator = "/swagger/docs";
                    });
                })
                .Build()
                .Run();
        }

        private static IEnumerable<SwaggerEndPointOptions> CreateSwaggerEndPointOption(IConfiguration configuration)
        {
            const string defaultSwaggerPath = "/swagger/v1/swagger.json";
            var routesSection = configuration.GetSection("Routes");
            var resultList = new List<SwaggerEndPointOptions>();
            var first = true;
            routesSection.GetChildren().ForEach(eachRoute =>
            {
                var swaggerEndpointOptions = new SwaggerEndPointOptions
                {
                    Key = eachRoute.GetValue<string>("SwaggerKey"),
                    Config = new List<SwaggerEndPointConfig>()
                };
                if (swaggerEndpointOptions.Key.IsNullOrEmpty()) return;
                var hpSections = eachRoute.GetSection("DownstreamHostAndPorts").GetChildren();
                var version = 1;
                hpSections.ForEach(eachHP =>
                {
                    var host = eachHP.GetValue<string>("Host");
                    var port = eachHP.GetValue<string>("Port");

                    swaggerEndpointOptions.Config.Add(
                        new SwaggerEndPointConfig()
                        {
                            Name = $"{swaggerEndpointOptions.Key} API",
                            Version = $"v{version}",
                            Url = $"http://{host}:{port}{defaultSwaggerPath}"
                        });
                    version++;
                });
                Console.WriteLine(swaggerEndpointOptions.AsIndentedJson());
                resultList.Add(swaggerEndpointOptions);
            });
            return resultList;
        }
    }
}

My Ocelot Config (Shortend) :

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "my-service-api",
          "Port": 80
        }
      ],
      "UpstreamPathTemplate": "/MyService/{everything}",
      "UpstreamHttpMethod": ["POST", "PUT", "GET", "DELETE"],
      "SwaggerKey": "MyService"
    }
  ],
  "GlobalConfiguration": {},
  "Logging": {
    "LogLevel": {
      "Default": "Trace"
    }
  },
  "AllowedHosts": "*"
}
Burgyn commented 3 years ago

Hi @kurtisane,

I am not currently at the PC. At first glance (from mobile) it's look that you have incorrect order in Configuration section. When registering middleware depends on the order. Ocelot middlewate should be the last.

app.UseSwaggerForOcelotUI(opt =>
{
      opt.PathToSwaggerGenerator = "/swagger/docs";
 });
app.UseOcelot().Wait()