Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SwaggerEndPoints configuration section is missing or empty for merged ocelot jsons #69

Closed
Cichyy7 opened this issue Jan 22, 2020 · 8 comments

Comments

@Cichyy7
Copy link

Cichyy7 commented Jan 22, 2020

Hi,

When I'm using per service ocelot.json configuration and file merging, I get System.InvalidOperationException: "SwaggerEndPoints configuration section is missing or empty."
Approach is described here: https://ocelot.readthedocs.io/en/latest/features/configuration.html#merging-configuration-files

When I put whole configuration in standalone ocelot.json, everything works fine.

I would like to use both configurations merging and swagger on api gateway.

My configuration below:

Startup.cs

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddOcelot();
            services.AddSwaggerForOcelot(Configuration);
            ...
        }
        public async void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
          ...
            app.UseStaticFiles();

            await app.UseSwaggerForOcelotUI(Configuration, opt =>
            {
                opt.PathToSwaggerGenerator = "/swagger/docs";

            }).UseOcelot();
           ...
        }

Program.cs

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.ConfigureAppConfiguration((hostingContext, config) =>
                    {
                        config
                            .AddOcelot("./Ocelot", hostingContext.HostingEnvironment)
                            .AddEnvironmentVariables();
                    });
                    webBuilder.UseStartup<Startup>();
                });

ocelot.service1.json

{
  "ReRoutes": [
    {
      "SwaggerKey": "service1",
      "UpstreamPathTemplate": "/service1/{everything}",
      "UpstreamHttpMethod": [ "GET", "PUT" ],
      "DownstreamPathTemplate": "/service1/{everything}",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 5010
        }
      ]
    }
  ]
}

ocelot.global.json

{
  "SwaggerEndPoints": [
    {
      "Key": "service1",
      "Config": [
        {
          "Name": "Service1 API V1",
          "Version": "v1",
          "Url": "http://localhost:5010/swagger/v1/swagger.json"
        }
      ]
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "http://localhost:5014"
  }
}
@Burgyn
Copy link
Owner

Burgyn commented Jan 22, 2020

Hi,

thanks for your issue. I never test this scenario.

I'll look into it in the near future.

@Burgyn Burgyn added the investigate Investigate this issue label Jan 22, 2020
@Burgyn
Copy link
Owner

Burgyn commented Jan 22, 2020

Hi,

when you use .AddOcelot("./Ocelot", hostingContext.HostingEnvironment) extension, then Ocelot merge configuration by own way and remove unknown elements.

As workaround you can move SwaggerEndPoints section into your appsettings.json file.
I hope, that help you.

@Burgyn Burgyn removed the investigate Investigate this issue label Jan 22, 2020
@Cichyy7
Copy link
Author

Cichyy7 commented Jan 22, 2020

Hi,
Thanks for the quick reply!

Moving SwaggerEndPoints to appsettings.json of gateway indeed helped with SwaggerEndPoints configuration section is missing or empty
but now i'm getting
IndexOutOfRangeException: Index was outside the bounds of the array.
MMLib.SwaggerForOcelot.Middleware.SwaggerForOcelotMiddleware.GetEndPointInfo(string path)

Also, I'm wondering how to move "SwaggerKey": "service1" from ReRoutes of service. From what I saw .AddOcelot() is also removing it from merged ocelot.json.

UPDATE:
IndexOutOfRangeException was caused by accidentally removed /docs suffix from .PathToSwaggerGenerator.
Now swagger page is loaded but with "No operations defined in spec!" info. I guess that's because of missing SwaggerKey in ReRoutes.

@Burgyn
Copy link
Owner

Burgyn commented Jan 23, 2020

Hi,

yes you are right SwaggerKey is removed. Unfortunately now I don't have any workaround for this. I apologize.

@Cichyy7
Copy link
Author

Cichyy7 commented Jan 23, 2020

Hi,

No problem ;)
Thanks for the help anyway ;)

@Navaladi2019
Copy link

Hi,
On such case if we can take ServiceName from route and map it to SwaggerKey.it will work

@habtu12
Copy link

habtu12 commented Aug 18, 2021

You can config teh Program.cs to read ocelot.json or ocelot.dev.json like this:
Screenshot 2021-08-18 141339

@Mostafa-Youssef
Copy link

Mostafa-Youssef commented Oct 22, 2023

Hi,
sorry for the 3 years delay,
i was making a gateway 2 weeks ago with ocelot and MMLib.SwaggerForOcelot and i have faced the same problem when using ocelot merging the swagger properties and swagger endpoints are missing then i read the ocelot implementation

image

image

and i found that they are using specific properties so i have added more my self
image
image
image
in the last image the FileRoute is the for ocelot i have just inherited from it the same as SwaggerEndPointOptions it is for MMLib.SwaggerForOcelot,
and for the implementation with the help of this awesome guy i got the idea from him to add my own swagger end point the link

so as ocelot said in the documentation they use the ocelot.json as the entry point so we made our own extension and put all the files content in the ocelot.json with our extra properties as you can see in the previous images
and for the extension implementation
image

extension implementation

`
public static class ConfigurationBuilderExtensions
{
public static IConfigurationBuilder AddOcelotConfigFiles(this IConfigurationBuilder builder, string folder, string[] appNames, IWebHostEnvironment env)
{
const string primaryConfigFile = "ocelot.json";

     var files = new DirectoryInfo(folder)
         .EnumerateFiles()
         .Where(fi => fi.Name.Contains($"ocelot.{env.EnvironmentName}.json") && appNames.Any(e => fi.Name.Contains(e)))
         .ToList();

     var fileConfiguration = new MyFileConfiguration();

     foreach (var file in files)
     {
         if (files.Count > 1 && file.Name.Equals(primaryConfigFile, StringComparison.OrdinalIgnoreCase))
         {
             continue;
         }

         var lines = File.ReadAllText(file.FullName);

         var config = JsonConvert.DeserializeObject<MyFileConfiguration>(lines);

         fileConfiguration.Aggregates.AddRange(config.Aggregates);
         fileConfiguration.Routes.AddRange(config.Routes);
         fileConfiguration.SwaggerEndPoints.AddRange(config.SwaggerEndPoints);
     }

     var json = JsonConvert.SerializeObject(fileConfiguration);

     File.WriteAllText(primaryConfigFile, json);

     builder.AddJsonFile(primaryConfigFile, true, true);

     return builder;
 }

}
`

and for the programs.cs
image

and that's it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants