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

Ocelot with Consul, 404 Not Found #1487

Closed
heyruyn23 opened this issue Jun 21, 2021 · 4 comments · Fixed by #1670
Closed

Ocelot with Consul, 404 Not Found #1487

heyruyn23 opened this issue Jun 21, 2021 · 4 comments · Fixed by #1670
Assignees
Labels
bug Identified as a potential bug merged Issue has been merged to dev and is waiting for the next release Service Discovery Ocelot feature: Service Discovery

Comments

@heyruyn23
Copy link

heyruyn23 commented Jun 21, 2021

Hello, I am very new to Microservice architecture, and I am stuck at this problem for a week.
I really appreciate your help in advance..!

Expected Behavior / New Feature

I am trying to use Ocelot with Consul.
I am not using docker, I am running consul in windows cli.
I have three projects in one solution,
image

Actual Behavior / Motivation for New Feature

API is running successfully, the service is registered in consul.
image
image

But when I tried to call the API from the consul, I get '404 Not Found'.
image

I think the whatever routing setting in ocelot.json is not working properly... I don't know why..

Steps to Reproduce the Problem

In API Gateway Project

  1. Ocelot.Development.json
      "Routes": [
          {
            "DownstreamPathTemplate": "/api/contact/findall",
            "DownstreamScheme": "http",
            "ServiceName": "contactService",
            "UpstreamPathTemplate": "/contact/findall",
            "UpstreamHttpMethod": [ "Get" ],
            "UseServiceDiscovery": true,
            "ReRouteIsCaseSensitive": false,
            "LoadBalancerOptions": {
              "Type": "RoundRobin"
            }
          }
        ],
      
        "GlobalConfiguration": {
          "ServiceDiscoveryProvider": {
            "Scheme": "http",
            "Host": "localhost",
            "Port": 8500,
            "Type": "Consul"
          }
        }
  1. Program.cs
        public static void Main(string[] args)
              {
                  new WebHostBuilder()
                      .UseKestrel()
                      .UseContentRoot(Directory.GetCurrentDirectory())
                      .ConfigureAppConfiguration((hostingContext, config) =>
                      {
                          config
                              .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
                              .AddJsonFile($"ocelot.{hostingContext.HostingEnvironment.EnvironmentName}.json")
                              .AddEnvironmentVariables();
                      })
                      .ConfigureServices(s => {
                          s.AddOcelot().AddConsul();
                      })
                      .ConfigureLogging((hostingContext, logging) =>
                      {
                          logging.AddConsole();
                      })
                      .UseIISIntegration()
                      .Configure(app =>
                      {
                          app.UseOcelot().Wait();
                      })
                      .Build()
                      .Run();
              }
  1. Startup

In my Common Library


    public static class AppExtensions
        {
            public static IServiceCollection AddConsulConfig(this IServiceCollection services, IConfiguration configuration)
            {
                services.AddSingleton<IConsulClient, ConsulClient>(p => new ConsulClient(consulConfig
                     =>
                 {
                     var address = configuration["Consul:ConsulAddress"];
                     consulConfig.Address = new Uri(address);
    
                 }));
                return services;
            }
    
            public static IApplicationBuilder UseConsul(this IApplicationBuilder app, IConfiguration configuration)
            {
                var consulClient = app.ApplicationServices.GetRequiredService<IConsulClient>();
                var logger = app.ApplicationServices.GetRequiredService<ILoggerFactory>().CreateLogger("AppExtensions");
                var lifetime = app.ApplicationServices.GetRequiredService<IApplicationLifetime>();
    
                var registration = new AgentServiceRegistration()
                {
                    ID = configuration["Consul:ServiceId"],
                    Name = configuration["Consul:ServiceName"],
                    Address = configuration["Consul:ServiceHost"],
                    Port = int.Parse(configuration["Consul:ServicePort"])
                };
    
                logger.LogInformation("Registering with Consul");
                consulClient.Agent.ServiceDeregister(registration.ID).ConfigureAwait(true);
                consulClient.Agent.ServiceRegister(registration).ConfigureAwait(true);
    
                lifetime.ApplicationStopping.Register(() =>
                {
                    logger.LogInformation("Unregistering from Consul");
                });
    
                return app;
            }
        }

In my ContactService Project

  1. launchSetting.json
        {
        "$schema": "http://json.schemastore.org/launchsettings.json",
        "iisSettings": {
          "windowsAuthentication": false,
          "anonymousAuthentication": true,
          "iisExpress": {
            "applicationUrl": "http://localhost:17300",
            "sslPort": 44324
          }
        },
        "profiles": {
          "IIS Express": {
            "commandName": "IISExpress",
            "launchBrowser": true,
            "launchUrl": "contact",
            "environmentVariables": {
              "ASPNETCORE_ENVIRONMENT": "Development"
            }
          },
          "ContactService": {
            "commandName": "Project",
            "dotnetRunMessages": "true",
            "launchBrowser": true,
            "launchUrl": "contact",
            "applicationUrl": "https://localhost:5001;http://localhost:5000",
            "environmentVariables": {
              "ASPNETCORE_ENVIRONMENT": "Development"
            }
          }
        }
      }
  1. appSettings.json
        {
        "Logging": {
          "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
          }
        },
        "AllowedHosts": "*",
        "Consul": {
          "ConsulAddress": "http://localhost:8500",
          "ServiceHost": "localhost",
          "ServicePort": 17300,
          "ServiceName": "contactService",
          "ServiceId": "contactService-Id"
        }
      }
  1. Startup
public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {

            services.AddControllers();
            services.AddScoped<IContactService, ContactServiceImpl>();
            services.AddConsulConfig(Configuration);
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseConsul(Configuration);

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }

Specifications

  • Version: net5.0
  • Platform: Windows 10
  • Subsystem:
@ghost
Copy link

ghost commented Jun 30, 2021

Please try the following method which takes me 4 hours to fix it.

public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .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("ocelot.json", true, true)
                        .AddEnvironmentVariables();
                })
                .ConfigureLogging((hostingContext, logging) =>
                {
                    //add your logging
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                    webBuilder.UseKestrel();
                });

@johha86
Copy link

johha86 commented Aug 14, 2021

@heyruyn23 Does the error appear at the first request or in any?

@HorjeaCosmin
Copy link

HorjeaCosmin commented Oct 27, 2022

@heyruyn23 Does the error appear at the first request or in any?

Hi @johha86 ,

I have the same problem, got error on any request. I'm using Ocelot v18 (last one).

Any ideea?

@raman-m raman-m added bug Identified as a potential bug Service Discovery Ocelot feature: Service Discovery labels Sep 18, 2023
@raman-m
Copy link
Member

raman-m commented Sep 18, 2023

@heyruyn23 commented on Jun 21, 2021

Hi! Thanks for your interest in Ocelot!
I will help you. 😉 Isn't it too late? 😄
You wrote fantastic description, but it would be better to show logger message from Ocelot's machine/console.
Was it an error like "services were empty"?

raman-m added a commit that referenced this issue Sep 29, 2023
…ements and fix errors (#1670)

* fixing some issues in poll consul:
- Timer is not thread safe, avoiding usage of it
- No Ressources are returned for first call
- Using a providers pool, instead of creating a new provider instance

* line endings

* adding some test cases

* Using a lock instead of SemaphoreSlim

* Improve code readability

* CA2211: Non-constant fields should not be visible

* Use IOcelotLogger to remove warnings & messages of static code analysis (aka IDE0052)

* Fix errors with unit tests discovery. Remove legacy life hacks of discovering tests on .NET Core

* Update unit tests

* Also refactoring the kubernetes provider factory (like consul and eureka)

* shorten references...

* const before...

* Some minor fixes, using Equals Ordinal ignore case and a string constant for provider type definition instead of string litterals. Fixing usings.

* waiting a bit longer then?

* @RaynaldM code review

* renaming PollKubernetes to PollKube

* ... odd...

* ... very odd, we have an issue with configuration update duration...

* IDE0002: Name can be simplified

* All tests passing locally, hopefully it works online

* just a bit of cleanup

* Some missing braces and commas

* Update servicediscovery.rst: Review and update "Consul" section

---------

Co-authored-by: Guillaume Gnaegi <[email protected]>
Co-authored-by: raman-m <[email protected]>
@raman-m raman-m added the merged Issue has been merged to dev and is waiting for the next release label Sep 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Identified as a potential bug merged Issue has been merged to dev and is waiting for the next release Service Discovery Ocelot feature: Service Discovery
Projects
None yet
4 participants