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.

Consul Service Discovery Not Working With Dynamic Routing

See original GitHub issue

Expected Behavior

Use Ocelot and Consul for service discovery and dynamic routing.

Actual Behavior

Without defining ReRoutes an error occurs.

Steps to Reproduce the Problem

  1. Setup Consul and register a service
  2. Setup Ocelot and provide configuration to talk to Consul with Ocelot.Provider.Consul
  3. Attempt to go to the route which should be dynamically routed.

Specifications

  • Version: 12.0.1
  • Platform: .Windows
  • Subsystem: NET Core 2.1

Error

dbug: Ocelot.Errors.Middleware.ExceptionHandlerMiddleware[0]
      requestId: 0HLHEQFFHMBL6:00000002, previousRequestId: no previous request id, message: ocelot pipeline started
dbug: Ocelot.DownstreamRouteFinder.Middleware.DownstreamRouteFinderMiddleware[0]
      requestId: 0HLHEQFFHMBL6:00000002, previousRequestId: no previous request id, message: Upstream url path is /background-forms-api/api/values
info: Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteProviderFactory[0]
      requestId: 0HLHEQFFHMBL6:00000002, previousRequestId: no previous request id, message: Selected DownstreamRouteCreator as DownstreamRouteProvider for this request
dbug: Ocelot.Errors.Middleware.ExceptionHandlerMiddleware[0]
      requestId: 0HLHEQFFHMBL6:00000002, previousRequestId: no previous request id, message: error calling middleware
fail: Ocelot.Errors.Middleware.ExceptionHandlerMiddleware[0]
      requestId: 0HLHEQFFHMBL6:00000002, previousRequestId: no previous request id, message: Exception caught in global error handler, exception message: The given key 'DownstreamRouteCreator' was not present in the dictionary., exception stack:    at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
         at Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteProviderFactory.Get(IInternalConfiguration config) in C:\projects\Ocelot\src\Ocelot\DownstreamRouteFinder\Finder\DownstreamRouteProviderFactory.cs:line 28
         at Ocelot.DownstreamRouteFinder.Middleware.DownstreamRouteFinderMiddleware.Invoke(DownstreamContext context) in C:\projects\Ocelot\src\Ocelot\DownstreamRouteFinder\Middleware\DownstreamRouteFinderMiddleware.cs:line 39
         at Ocelot.Responder.Middleware.ResponderMiddleware.Invoke(DownstreamContext context) in C:\projects\Ocelot\src\Ocelot\Responder\Middleware\ResponderMiddleware.cs:line 34
         at Ocelot.Middleware.Pipeline.MapWhenMiddleware.Invoke(DownstreamContext context) in C:\projects\Ocelot\src\Ocelot\Middleware\Pipeline\MapWhenMiddleware.cs:line 40
         at Ocelot.Errors.Middleware.ExceptionHandlerMiddleware.Invoke(DownstreamContext context) in C:\projects\Ocelot\src\Ocelot\Errors\Middleware\ExceptionHandlerMiddleware.cs:line 53 RequestId: 0HLHEQFFHMBL6:00000002, exception: System.Collections.Generic.KeyNotFoundException: The given key 'DownstreamRouteCreator' was not present in the dictionary.
         at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
         at Ocelot.DownstreamRouteFinder.Finder.DownstreamRouteProviderFactory.Get(IInternalConfiguration config) in C:\projects\Ocelot\src\Ocelot\DownstreamRouteFinder\Finder\DownstreamRouteProviderFactory.cs:line 28
         at Ocelot.DownstreamRouteFinder.Middleware.DownstreamRouteFinderMiddleware.Invoke(DownstreamContext context) in C:\projects\Ocelot\src\Ocelot\DownstreamRouteFinder\Middleware\DownstreamRouteFinderMiddleware.cs:line 39
         at Ocelot.Responder.Middleware.ResponderMiddleware.Invoke(DownstreamContext context) in C:\projects\Ocelot\src\Ocelot\Responder\Middleware\ResponderMiddleware.cs:line 34
         at Ocelot.Middleware.Pipeline.MapWhenMiddleware.Invoke(DownstreamContext context) in C:\projects\Ocelot\src\Ocelot\Middleware\Pipeline\MapWhenMiddleware.cs:line 40
         at Ocelot.Errors.Middleware.ExceptionHandlerMiddleware.Invoke(DownstreamContext context) in C:\projects\Ocelot\src\Ocelot\Errors\Middleware\ExceptionHandlerMiddleware.cs:line 53
dbug: Ocelot.Errors.Middleware.ExceptionHandlerMiddleware[0]
      requestId: 0HLHEQFFHMBL6:00000002, previousRequestId: no previous request id, message: ocelot pipeline finished

Configuration

Ocelot

The configuration is pulled from appsettings.json:

{
  "ReRoutes": [],
  "Aggregates": [],
  "GlobalConfiguration": {
    "RequestIdKey": null,
    "ServiceDiscoveryProvider": {
      "ConfigurationKey": "Ocelot",
      "Host": "localhost",
      "Port": 8500,
      "Type": "Consul"
    },
    "RateLimitOptions": {
      "ClientIdHeader": "ClientId",
      "QuotaExceededMessage": null,
      "RateLimitCounterPrefix": "ocelot",
      "DisableRateLimitHeaders": false,
      "HttpStatusCode": 429
    },
    "QoSOptions": {
      "ExceptionsAllowedBeforeBreaking": 0,
      "DurationOfBreak": 0,
      "TimeoutValue": 0
    },
    "LoadBalancerOptions": {
      "Type": "LeastConnection"
    },
    "DownstreamScheme": "http",
    "HttpHandlerOptions": {
      "AllowAutoRedirect": false,
      "UseCookieContainer": false,
      "UseTracing": false
    }
  }
}

Consul

The service self-registers with Consul on startup.

{
	"ID": "098a60b3-9e77-d3e1-ccb7-56580afadb74",
	"Node": "54060bfe6310",
	"Address": "127.0.0.1",
	"Datacenter": "dc1",
	"TaggedAddresses": {
		"lan": "127.0.0.1",
		"wan": "127.0.0.1"
	},
	"NodeMeta": {
		"consul-network-segment": ""
	},
	"ServiceKind": "",
	"ServiceID": "background-forms-api-v1-final-01-192.168.1.203-5000",
	"ServiceName": "background-forms-api",
	"ServiceTags": [
		"Forms"
	],
	"ServiceAddress": "192.168.1.203",
	"ServiceWeights": {
		"Passing": 1,
		"Warning": 1
	},
	"ServiceMeta": {
		"BoolTest": "\"True\"",
		"DecimalTest": "\"12.3\"",
		"Scopes": "[\"oidc\",\"name\",\"email\",\"gender\",\"birthdate\",\"zoneinfo\",\"locale\",\"phone_number\",\"address\"]",
		"StringTest": "\"Hello\""
	},
	"ServicePort": 5000,
	"ServiceEnableTagOverride": false,
	"ServiceProxyDestination": "",
	"ServiceConnect": {
		"Native": false,
		"Proxy": null
	},
	"CreateIndex": 396,
	"ModifyIndex": 580
}

Description

I’ve setup a basic API gateway in .NET Core 2.1 using Ocelot. The goal is to have the API gateway configure its routing based on the information inside of a service registry.

To meet this I’ve setup Consul and have services self-register as they come on-line. Ocelot should then be able to use Consul to determine the routes for downstream services.

When I attempt to do this per the configuration I get the above error. If I change my configuration to manually put the route information into ReRoutes Ocelot will detect the host and port information from Consul and redirect the request.

I tried to trace what is going on during the configuration of Ocelot. To me it seems that the ConsulProviderFactory.Get is never executed in the case where the ReRoutes array is empty.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:12 (4 by maintainers)

github_iconTop GitHub Comments

4reactions
Loonglecommented, Oct 17, 2018

When will it be updated to the nuget repository?

1reaction
mickeygocommented, Nov 29, 2018

The same problem,I have to downgrade from 12.0.1 version to 12.0.0

Read more comments on GitHub >

github_iconTop Results From Across the Web

API Gateway using Spring Cloud + Zuul + Consul
In a first version, routes to each service was registered in the gateway configuration using zuul.routes.myApiName.url and it was working fine.
Read more >
Service Router Configuration Entry Reference | Consul
This page provides reference information for service router configuration entries. Service routers use L7 network information to redirect a traffic request ...
Read more >
Dynamic routing based on URL - Consul
I have multiple dynamic services running on a node and they have their own dynamic local IP addresses (for example 192.168.1.3). They are...
Read more >
Service Discovery — Ocelot 1.0.0 documentation
In order to enable dynamic routing you need to have 0 Routes in your config. At the moment you cannot mix dynamic and...
Read more >
How to configure dynamic routing of gRPC requests with ...
The decision to which endpoint/task to route is currently based on the host header and every task is registered as a service under...
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