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

Automatic route creation based on microservices registered to Consul, Eureka #340

Closed
marchermans opened this issue May 2, 2018 · 17 comments · Fixed by #351
Closed

Automatic route creation based on microservices registered to Consul, Eureka #340

marchermans opened this issue May 2, 2018 · 17 comments · Fixed by #351
Labels
feature A new feature Routing Ocelot feature: Routing Service Discovery Ocelot feature: Service Discovery

Comments

@marchermans
Copy link

marchermans commented May 2, 2018

Expected Behavior / New Feature

It would be amazing if Ocelot could create and remove routes depending on the services registered in Eureka and/or Consul. We are currently looking to move most of our Microservices to .Net Core and we are currently looking for a replacement for the Zuul-Eureka-Combo that automatically routes all request for a given service to it:

Example:

https://system.com:80/auth/<request_for_auth_service>
--> Here the /auth/ is the service name registered in Consul and/or Eureka
http://auth:5000/<request_for_auth_service>
--> Here the root address: http://auth:5000/ gets pulled from consul and/or eureka.

Actual Behavior / Motivation for New Feautre

As of now we could not find a away to do this without additional software which called the administration API and updated the routes on its own.

Specifications

  • Version: Current Release.
  • Platform: Windows .Net Core 2.1 - Preview 2 / Linux Alpine Docker .Net Core 2.1 - Preview 2
  • Subsystem: ReRoute, Administration.

Docs

@TomPallister
Copy link
Member

@OrionDevelopment thanks for your interest in the project! I think that this could be done!

Ocelot could definitely be configured to use first segment of request path as a key when looking up the service to call. The only annoying thing would be changing the validation and ReRoute creation code to not need pre configured ReRoutes but this might be easier than I imagine!

I'll take a look when I get some free time 😄

@TomPallister TomPallister added feature A new feature help wanted Not actively being worked on. If you plan to contribute, please drop a note. medium effort Likely a few days of development effort labels May 2, 2018
@marchermans
Copy link
Author

marchermans commented May 4, 2018

@TomPallister If you need help, point me in the right direction. Would be amazing if this can be controlled via DI as well.

@TomPallister
Copy link
Member

@OrionDevelopment I think that the main thing is the DownstreamRouteFinderMiddleware + deps, this will not find a ReRoute and then return a 404. It needs to be changed to handle requests that dont have a ReRoute. Then LoadBalancingMiddleware.cs + deps would need to be changed to use the first path segment as a key and that is pretty much all you have to change (I think!).

@TomPallister TomPallister changed the title Automatic Route creation based on Microservices registered to Consul / Eureka New Feature - Automatic Route creation based on Microservices registered to Consul / Eureka May 4, 2018
@marchermans
Copy link
Author

@TomPallister Are you guys using the normal DI injection from .Net Core (so IServiceCollection/IServiceProvider), if so we might be able to do this nicely with a decorator pattern?

@marchermans
Copy link
Author

@TomPallister

@TomPallister
Copy link
Member

@OrionDevelopment sorry I missed this, so many issues!! I just started a new job so I don't have much time at the moment either :(

Yes we use normal DI but I would not do this using decorator pattern as we havent used it anywhere else in Ocelot now and I'm not sure I would want to introduce a way of solving problems that isn't consistent. The way this would normally be done in the Ocelot code base is with factory returns different implementation of some interface based on some values. In this case I would look at the condig decide that we were not using typical routing and do whatever needs to be done. It might even be easier than this! I dont have the whole code base in my head I'm afraid :(

@marchermans
Copy link
Author

Ah Okey. Good to know. Will take a look.

TomPallister pushed a commit that referenced this issue May 10, 2018
@TomPallister TomPallister changed the title New Feature - Automatic Route creation based on Microservices registered to Consul / Eureka Automatic Route creation based on Microservices registered to Consul / Eureka May 14, 2018
TomPallister added a commit that referenced this issue May 14, 2018
* #340 started looking at supporting automatic routing when using service discovery

* #340 getting old routing tests to pass

* #340 renamed stuff to provider rather than finder, as its not longer finding anything

* #340 working towards supporting dynamic routing

* #340 loads of refactoring to make configuration work with dynamic routing

* #340 refactor consul config code so the registry class owns it

* #340 default to consul to maintain backwards compat

* #340 added docs, finished this branches todos
@TomPallister TomPallister reopened this May 14, 2018
@TomPallister TomPallister added the merged Issue has been merged to dev and is waiting for the next release label May 14, 2018
@TomPallister
Copy link
Member

@OrionDevelopment Ive just pushed version 7.0.1 and this has the changes for dynamic routing with service discovery. Check out the docs here.

Let me know if this works for you or if you think we could make it better.

@marchermans
Copy link
Author

To clearify.
The documentation specifies that this works with consul. Does this work with Eureka as well?

@TomPallister
Copy link
Member

@OrionDevelopment yes it does, consul is just used as an example. I will make that clearer.

@marchermans
Copy link
Author

Okey. Cool.

@liuyuedeyv
Copy link
Contributor

Well done!

But I have another plan, and it works pretty well. I store the configuration files to consul, and then write a common API server boot container, read the configuration from consul when the service starts, and update it dynamically!

Example:
` using (var client = new Consul.ConsulClient((config) =>
{
config.Address = new Uri(serviceCenter);
}))
{
FileConfiguration fileConfiguration = null;
JsonConverter json = new JsonConverter();
var response = client.KV.Get("InternalConfiguration").GetAwaiter().GetResult().Response;
if (null != response)
{
var tmpStr = Encoding.UTF8.GetString(response.Value, 0, response.Value.Length);
Console.WriteLine(tmpStr);

                    fileConfiguration = json.Deserialize<FileConfiguration>(tmpStr);
                }
                else
                {
                    fileConfiguration = new FileConfiguration();
                }
                var routeRule = fileConfiguration.ReRoutes.Where(d => d.ServiceName == dllName).FirstOrDefault();
                if (routeRule == null)
                {
                    routeRule = new FileReRoute();
                    fileConfiguration.ReRoutes.Add(routeRule);
                }
                List<string> listUpMethod = new List<string>();
                listUpMethod.Add("GET");
                routeRule.UpstreamPathTemplate = $"/{dllName.Split('.')[0]}/{{url}}";
                routeRule.UpstreamHttpMethod = listUpMethod;
                routeRule.ServiceName = dllName;
                routeRule.UseServiceDiscovery = true;
                routeRule.DownstreamPathTemplate = $"/{{url}}";
                routeRule.DownstreamScheme = "http";
                routeRule.LoadBalancerOptions = new FileLoadBalancerOptions()
                {
                    Type = "LeastConnection"
                };
                var putPair = new KVPair("InternalConfiguration")
                {
                    Value = Encoding.UTF8.GetBytes(json.Serialize(fileConfiguration))
                };
                var ss = client.KV.Put(putPair).GetAwaiter().GetResult();

            }`

@ignite-404
Copy link

how to deal with the api start with “api”
Like api/product/xxx
We use second segment to look up the upstream
Then proxy to upstream.com/api/product/xxx

@marchermans
Copy link
Author

As far as I know that is not possible at the moment.

@ShvetsovAU
Copy link

ShvetsovAU commented Jun 1, 2021

Hi! As i understand, this feature work only with Consul / Eureka? If i don't use Consul / Eureka, this setting in GlobalConfigurations don't work and then application start i get next error: "Exception: Unable to start Ocelot, errors are: When not using service discovery DownstreamHostAndPorts must be set and not empty or Ocelot cannot find your service!"

Configuration example:

{
"Routes": [
{
"DownstreamPathTemplate": "/api/v1/Speciality",
//"DownstreamHostAndPorts": [
// {
// "Host": "localhost",
// "Port": 5888 //telemedapigateway port
// }
//],
"UpstreamPathTemplate": "/api/v1/Speciality",
"UpstreamHttpMethod": [ "GET" ]
}
],
//The Global configuration allows overrides of ReRoute (now is Route) specific settings in case, you don’t want to manage lots of ReRoute specific settings.
"GlobalConfiguration": {
"AuthenticationOptions": {
"AuthenticationProviderKey": "Bearer",
"AllowedScopes": [ "api.telemedapigateway.full" ]
},
"DownstreamScheme": "http",

//https://ocelot.readthedocs.io/en/latest/features/servicediscovery.html
"ServiceDiscoveryProvider": {
  "Host": "localhost",
  "Port": 5888
}

}
}

@shubham-jain-amla
Copy link

shubham-jain-amla commented Jan 23, 2024

can I get conventional routing i.e it automatically maps all the routes in the ocelot.json

@raman-m
Copy link
Member

raman-m commented Feb 23, 2024

@raman-m raman-m changed the title Automatic Route creation based on Microservices registered to Consul / Eureka Automatic route creation based on microservices registered to Consul, Eureka Aug 15, 2024
@raman-m raman-m added Service Discovery Ocelot feature: Service Discovery Routing Ocelot feature: Routing and removed help wanted Not actively being worked on. If you plan to contribute, please drop a note. medium effort Likely a few days of development effort merged Issue has been merged to dev and is waiting for the next release labels Aug 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature A new feature Routing Ocelot feature: Routing Service Discovery Ocelot feature: Service Discovery
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants