ThreeMammals / Ocelot

.NET API Gateway
https://www.nuget.org/packages/Ocelot
MIT License
8.32k stars 1.63k forks source link

Why doesn't AddConfigStoredInConsul() work as normal Consul config? #1761

Closed ArchitectAllenGitHub closed 10 months ago

ArchitectAllenGitHub commented 10 months ago

Expected Behavior / New Feature

The same configuration is used. AddConfigStoredInConsul() request 404, Normal if not in use. Program.cs It is shown below:

using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using Ocelot.Provider.Consul;

var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddJsonFile("ocelot.json");
builder.Services
    .AddOcelot()
    .AddConsul()
    .AddConfigStoredInConsul();

var app = builder.Build();

app.UseOcelot();

app.Run();

ocelot.json It is shown below

{
"Routes": [
    {
      "UpstreamPathTemplate": "/Ocelot/{url}",
      "UpstreamHttpMethod": [
        "Get",
        "Post"
      ],
      "DownstreamPathTemplate": "/{url}",
      "DownstreamScheme": "http",
      "ServiceName": "MagicCore.API",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      }
    }
  ],
  "GlobalConfiguration": {
    "ServiceDiscoveryProvider": {
      "Host": "localhost",
      "Port": 8500
    }
  }
}
ggnaegi commented 10 months ago

Hello @ArchitectAllenGitHub could you provide more details? Thanks!

raman-m commented 10 months ago

Hello @ArchitectAllenGitHub could you provide more details? Thanks!

@ggnaegi Look at "ServiceDiscoveryProvider" options in global config! They have no a Type property defined! I would say, this is border conditions case when no Type in the options, but developer has added Consul via AddConsul. We should substitute default type of discovery provider: Consul or PollConsul. To be discussed...

raman-m commented 10 months ago

Second, our docs for Load Balancer says nothing about coupling Service Discovery vs Load Balancer. The author was confused. We don't explain correct instructions...

raman-m commented 10 months ago

.AddConfigStoredInConsul();

What's the strange method? Is it from Ocelot code base? Or, is it a custom author's extension?

ggnaegi commented 10 months ago

.AddConfigStoredInConsul();

What's the strange method? Is it from Ocelot code base? Or, is it a custom author's extension?

@raman-m it's for the consul key value store. You could have dynamic configuration, the ocelot config being stored in consul. It starts an IHostedService instance called FileConfigurationPoller. https://developer.hashicorp.com/consul/docs/dynamic-app-config/kv and the funny thing, I'm using it... 😹

public static IOcelotBuilder AddConsul(this IOcelotBuilder builder)
    {
        builder.Services
            .AddSingleton(ConsulProviderFactory.Get)
            .AddSingleton<IConsulClientFactory, ConsulClientFactory>()
            .RemoveAll(typeof(IFileConfigurationPollerOptions))
            .AddSingleton<IFileConfigurationPollerOptions, ConsulFileConfigurationPollerOption>();
        return builder;
    }

    public static IOcelotBuilder AddConfigStoredInConsul(this IOcelotBuilder builder)
    {
        builder.Services
            .AddSingleton(ConsulMiddlewareConfigurationProvider.Get)
            .AddHostedService<FileConfigurationPoller>()
            .AddSingleton<IFileConfigurationRepository, ConsulFileConfigurationRepository>();
        return builder;
    }
ArchitectAllenGitHub commented 10 months ago

@ggnaegi @raman-m Thank you for your help.Here's my demo https://github.com/ArchitectAllenGitHub/OcelotDemo

ggnaegi commented 10 months ago

@ArchitectAllenGitHub could you try a config like this one? like @raman-m mentioned we might have a problem with the configuration since the ServiceDiscoveryProvider type is not defined.

"GlobalConfiguration": {
    "ServiceDiscoveryProvider": {
      "Host": "consul",
      "Port": 8500,
      "Type": "PollConsul",
      "PollingInterval": 3600000
    }
  }

Ok, I'm using a docker environment, so Host would be localhost or 127.0.0.1 for you ;-)

ArchitectAllenGitHub commented 10 months ago

你能试试这样的配置吗?如前所述,由于未定义 ServiceDiscoveryProvider 类型,因此我们的配置可能存在问题。

"GlobalConfiguration": {
    "ServiceDiscoveryProvider": {
      "Host": "consul",
      "Port": 8500,
      "Type": "PollConsul",
      "PollingInterval": 3600000
    }
  }

好的,我正在使用 docker 环境,所以 Host 将是 localhost 或 127.0.0.1 ;-)

Following the configuration above, I added the Type and PollingInterval. All else being equal. The AddConfigStoredInConsul() method is not used

image

Use the AddConfigStoredInConsul() method image image The specific json in Consul is as follows

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/{url}",
      "UpstreamPathTemplate": "/Ocelot/{url}",
      "UpstreamHttpMethod": [
        "Get",
        "Post"
      ],
      "DownstreamHttpMethod": null,
      "AddHeadersToRequest": {},
      "UpstreamHeaderTransform": {},
      "DownstreamHeaderTransform": {},
      "AddClaimsToRequest": {},
      "RouteClaimsRequirement": {},
      "AddQueriesToRequest": {},
      "ChangeDownstreamPathTemplate": {},
      "RequestIdKey": null,
      "FileCacheOptions": {
        "TtlSeconds": 0,
        "Region": null
      },
      "RouteIsCaseSensitive": false,
      "ServiceName": "MagicCore.API",
      "ServiceNamespace": null,
      "DownstreamScheme": "http",
      "QoSOptions": {
        "ExceptionsAllowedBeforeBreaking": 0,
        "DurationOfBreak": 0,
        "TimeoutValue": 0
      },
      "LoadBalancerOptions": {
        "Type": "RoundRobin",
        "Key": null,
        "Expiry": 0
      },
      "RateLimitOptions": {
        "ClientWhitelist": [],
        "EnableRateLimiting": false,
        "Period": null,
        "PeriodTimespan": 0.0,
        "Limit": 0
      },
      "AuthenticationOptions": {
        "AuthenticationProviderKey": null,
        "AllowedScopes": []
      },
      "HttpHandlerOptions": {
        "AllowAutoRedirect": false,
        "UseCookieContainer": false,
        "UseTracing": false,
        "UseProxy": true,
        "MaxConnectionsPerServer": 2147483647
      },
      "DownstreamHostAndPorts": [],
      "UpstreamHost": null,
      "Key": null,
      "DelegatingHandlers": [],
      "Priority": 1,
      "Timeout": 0,
      "DangerousAcceptAnyServerCertificateValidator": false,
      "SecurityOptions": {
        "IPAllowedList": [],
        "IPBlockedList": [],
        "ExcludeAllowedFromBlocked": false
      },
      "DownstreamHttpVersion": null
    }
  ],
  "DynamicRoutes": [],
  "Aggregates": [],
  "GlobalConfiguration": {
    "RequestIdKey": null,
    "ServiceDiscoveryProvider": {
      "Scheme": null,
      "Host": "localhost",
      "Port": 8500,
      "Type": "PollConsul",
      "Token": null,
      "ConfigurationKey": null,
      "PollingInterval": 3600000,
      "Namespace": null
    },
    "RateLimitOptions": {
      "ClientIdHeader": "ClientId",
      "QuotaExceededMessage": null,
      "RateLimitCounterPrefix": "ocelot",
      "DisableRateLimitHeaders": false,
      "HttpStatusCode": 429
    },
    "QoSOptions": {
      "ExceptionsAllowedBeforeBreaking": 0,
      "DurationOfBreak": 0,
      "TimeoutValue": 0
    },
    "BaseUrl": null,
    "LoadBalancerOptions": {
      "Type": null,
      "Key": null,
      "Expiry": 0
    },
    "DownstreamScheme": null,
    "HttpHandlerOptions": {
      "AllowAutoRedirect": false,
      "UseCookieContainer": false,
      "UseTracing": false,
      "UseProxy": true,
      "MaxConnectionsPerServer": 2147483647
    },
    "DownstreamHttpVersion": null
  }
}
ggnaegi commented 10 months ago

Yeah, but wait a minute, do you have registered your services to consul? Otherwise it's useless... The idea here is the following, you register your services to consul and then you query consul for the service addresses. I have an example here: https://github.com/ggnaegi/SwizlyPeasy.Gateway/blob/master/SwizlyPeasy.Consul/README.md Then, you can register several service instances to consul and then it will allow the load balancing.

But, @ArchitectAllenGitHub you are right, there is something not consistent here...

ArchitectAllenGitHub commented 10 months ago

Yeah, but wait a minute, do you have registered your services to consul? Otherwise it's useless... The idea here is the following, you register your services to consul and then you query consul for the service addresses. I have an example here: https://github.com/ggnaegi/SwizlyPeasy.Gateway/blob/master/SwizlyPeasy.Consul/README.md Then, you can register several service instances to consul and then it will allow the load balancing.

But, @ArchitectAllenGitHub you are right, there is something not consistent here...

The service is registered, Ocelot can be forwarded normally without adding the AddConfigStoredInConsul() method. Add this method and it's 404, which is very strange image

raman-m commented 10 months ago

@ArchitectAllenGitHub Disable AddConfigStoredInConsul() for now, remove it. And let's check classic setup of Consul config...

Show us what have you registered in Consul Services?

And, make screenshots of response & HTTP status code of direct connection from Ocelot's machine in Postman tool to your downstream service MagicCore.API please.

What is your Ocelot's machine? How did you deploy the machine? How do you host Ocelot app? Is it deployed to Docker image/container or not?

ggnaegi commented 10 months ago

@ArchitectAllenGitHub It's very strange, and even more for me since i'm using this in production... 😆 @ArchitectAllenGitHub And you are starting your ocelot instance on port 8000, right?

ArchitectAllenGitHub commented 10 months ago

@ArchitectAllenGitHub Disable AddConfigStoredInConsul() for now, remove it. And let's check classic setup of Consul config...

Show us what have you registered in Consul Services?

And, make screenshots of response & HTTP status code of direct connection from Ocelot's machine in Postman tool to your downstream service MagicCore.API please.

What is your Ocelot's machine? How did you deploy the machine? How do you host Ocelot app? Is it deployed to Docker image/container or not?

I'm running on Windows. This is the configuration of the Consul image image This is the case with the request through the Ocelot gateway, you can see if it is clear enough image

raman-m commented 10 months ago

Go to Discussions space!...