question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Not Found (404) Error with Service Discovery - Docker / Consul

See original GitHub issue

Expected Behavior

Reroute to the downstream path.

Actual Behavior

Any request return a Not Found Error(404) with the following message in the VS output window:

warn: Ocelot.Responder.Middleware.ResponderMiddleware[0]  requestId: 0HM2E7R13PE70:00000001, previousRequestId: no previous request id, message: Error Code: ServicesAreEmptyError Message: services were empty for SharepointAPI errors found in ResponderMiddleware. Setting error response for request path:/File, request method: GET

Ocelot.Responder.Middleware.ResponderMiddleware: Warning: requestId: 0HM2E7R13PE70:00000001, previousRequestId: no previous request id, message: Error Code: ServicesAreEmptyError Message: services were empty for SharepointAPI errors found in ResponderMiddleware. Setting error response for request path:/File, request method: GET

Steps to Reproduce the Problem

I created two ASP Net Core Web API projects. The first one implement a API Gateway using Ocelot with Consul and the second one is a simple Web API Service with a endpoint routed to /api/v1/File. Both project are initialized by a docker composer project

  1. Ocelot.json file:
"Routes": [
   {
     "DownstreamPathTemplate": "/api/v1/File",      
     "DownstreamScheme": "http",
     "UpstreamPathTemplate": "/File",
     "UpstreamHttpMethod": [ "Get" ],
     "ServiceName": "SharepointAPI",
     "LoadBalancerOptions": {
       "Type": "LeastConnection"
     }
   }
 ],
 "GlobalConfiguration": {
   "ServiceDiscoveryProvider": {
     "Scheme": "http",
     "Host": "consul",
     "Port": 8500,
     "Type": "PollConsul"
   }
 }
  1. Docker composer file
version: '3.4'

services:
    sharepoint.api:
       image: ${DOCKER_REGISTRY-}orderingapi
       hostname: sharepointapi
       build:
           context: .
           dockerfile: Sharepoint.API/Dockerfile
       ports:
           - "8002:80"

   private.gtw:
       image: ${DOCKER_REGISTRY-}privategtw
       build:
           context: .
           dockerfile: Private.Gtw/Dockerfile
      ports:
           - "7000:80"

   consul:
       image: consul:latest
       command: consul agent -dev -log-level=warn -ui -client=0.0.0.0 -bind='{{ GetPrivateIP }}'        
       hostname: consul
       ports:
           - "8500:8500"
  1. Startup file
        public void ConfigureServices(IServiceCollection services)
        {
            services
                .AddOcelot()
                .AddConsul(); 
        }

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

            app.UseRouting();

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

            //ocelot
            app.UseOcelot().Wait();
        }
  1. Output from Consul Monitor
/ # consul monitor
2020-09-01T06:54:40.712Z [INFO]  agent: Deregistered service: service=SharepointAPI
2020-09-01T06:54:40.911Z [INFO]  agent: Synced service: service=SharepointAPI

Specifications

The service looks registered in the web client. If I ping beetwen the consul container, the private gateway and the service container they can be reached each other.

  • Nuget Ocelot Version: 16.0.1
  • Nuget Ocelot.Provider.Consul Version: 16.0.1
  • Nuget Consul Version: 1.6.1.1
  • Platform: Net Core 3.1
  • Subsystem: Windows 10

How can I solve this problem?

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:14 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
johha86commented, Sep 15, 2021

Hello @ggnaegi

If you want to “Avoid polling” I think that you only need to setup Ocelot following the instruction: "ServiceDiscoveryProvider": { "Scheme": "https", "Host": "localhost", "Port": 8500, "Type": "Consul" } The type Consul retrieve the services until they are available on every request. You can found more details here. The problem that I faced in this issue is when the Type PollConsul is used in the service discovery configuration

2reactions
johha86commented, Aug 14, 2021

Hi, I had found the reason of the problem and how to fixe it. When you configure Ocelot to use Service Discovery as PollConsul mode, an IServiceDiscoveryProvider is created with a timer in the Constructor. In the callback of the timer, happens the Poll of the available services in Consul into a collection. But the initialization of this timer happens at the first time you call Ocelot. So, the first time you call ocelot, such collection is empty and you receive a Not Found 404. The repository with this code is Archived so I can’t do a PR with the Fix. What I did was do a Fork of the repository ,add the fix and use my forked project instead the Nuget Package. This is how the constructor in my Forked project is:

public PollConsul(int pollingInterval, IOcelotLoggerFactory factory, IServiceDiscoveryProvider consulServiceDiscoveryProvider)
{
   _logger = factory.CreateLogger<PollConsul>();
   _consulServiceDiscoveryProvider = consulServiceDiscoveryProvider;
   _services = new List<Service>();

   //  Do a first Poll before the first Timer callback.
   Poll().Wait();

  _timer = new Timer(async x =>
   {
     if (_polling)
     {
        return;
     }
  
     _polling = true;
     await Poll();
     _polling = false;
   }, null, pollingInterval, pollingInterval);
}

Other option is implement an IHostedService that perform calls to an endpoint at the beginning of the execution of the application.

I will keep this issue open because the original code doesn’t have a solution yet. Maybe I could maintain the original repository.

Read more comments on GitHub >

github_iconTop Results From Across the Web

docker swarm throws 404 page not found error while ...
I am currently using docker swarm with service discovery(consul). docker swarm node management is available on new docker swarm ...
Read more >
Common Error Messages - Troubleshoot | Consul
Troubleshoot issues based on the error message. Common errors result from failed actions, timeouts, multiple entries, bad and expired certificates, ...
Read more >
docker swarm throws 404 page not found error while checking ...
I am currently using docker swarm with service discovery(consul). docker swarm node management is available on new docker swarm mode(natively supported by ...
Read more >
Docker Error response from daemon: manifest not found ...
I am attempting to follow the docker get-started tutorial and have encountered a problem on part 2 under the section Pull and run...
Read more >
Troubleshooting errors with Docker commands when using ...
You may receive the error 404: Image not found when you are using Docker versions before 1.9. Some possible reasons and their explanations...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found