Connecting singnalR through Ocelot gateway in .Net 6 - .net-core

I am trying to connect my signalR to my frontend app through Ocelot gateway but failing to achieve it. The rest of the endpoints are completely accessible through the gateway but when I am trying to connect the signalR through gateway it throws localhost is currently unable to handle this request error.
My Ocelot configuration for signalR hub is
{
"DownstreamPathTemplate": "/{everything}",
"DownstreamScheme": "ws",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 5001
}
],
"UpstreamPathTemplate": "/{everything}",
"UpstreamHttpMethod": [ "GET", "POST", "PUT", "DELETE", "OPTIONS" ]
}
here is how I register the Ocelot in the program.cs
builder.Configuration.AddJsonFile("ocelot.json", optional: false, reloadOnChange: true);
builder.Services.AddOcelot(builder.Configuration);
app.UseWebSockets();
app.UseOcelot();
here is my signalR hub endpoint
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<NotificationHub>("/notifications");
});
I just followed the ocelot documentation but could not make it work until now.
here is error ss,

Related

Ocelot - unable to re-route

I have ASP.NET Web API microservices and currently I am implementing API gateway for routing and authentication.
From my 3 APIs, one of them is for User (crud) operations, so I decided to use it for a gateway, as well. And while I was implementing the routing I came across a strange problem.
With this (test) configuration (again, using my User API running on port 7268)
{
"Routes": [
//User API
{
"UpstreamPathTemplate": "/User/Login",
"UpstreamHttpMethod": [ "Post" ],
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 7124
}
],
"DownstreamPathTemplate": "/api/Product",
"DownstreamHttpMethod": "Get"
}
],
"GlobalConfiguration": {
"BaseUrl": "https://localhost:7268"
}
}
... I am able to get list of products from the Product API on port 7124, when I navigate to /User/Login.
Now if I change the configuration to access any endpoint of the same User API (which matches the BaseUrl path), it does not work. Example:
{
"Routes": [
//User API
{
"UpstreamPathTemplate": "/User/Login",
"UpstreamHttpMethod": [ "Post" ],
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 7268
}
],
"DownstreamPathTemplate": "/api/User/Login",
"DownstreamHttpMethod": "Post"
}
],
"GlobalConfiguration": {
"BaseUrl": "https://localhost:7268"
}
}
It gives me 404 Not Found and the following message in the console:
Is this because I am using an existing API to re-route itself and it is expected behavior, or I am doing something wrong?

How to integrate .net core ocelot gateway with rabbitmq

I need to integrate .net core gateway with rabbit mq.
Iam using angular 10 as client.
The architecture is=> Client(Angular 10) -> Gateway(Ocelot) -> Rabbitmq with easy netq -> .Net core Console app.
.Net core gateway route structure is given below
{
"Routes": [
{
"DownstreamPathTemplate": "/api/product",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 44337
}
],
"UpstreamPathTemplate": "/gateway/product",
"UpstreamHttpMethod": [ "POST", "PUT", "GET" ]
},
{
"DownstreamPathTemplate": "/api/product/{id}",
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 44337
}
],
"UpstreamPathTemplate": "/gateway/product/{id}",
"UpstreamHttpMethod": [ "GET", "DELETE" ]
}
],
"GlobalConfiguration": {
"BaseUrl": "http://localhost:44382"
}
}
We know that rabbit mq pattern is messaging with publish and subscribe method.
My question is do i need to add the code of consumer(subscribe) section of rabbit mq in gatway api and publish code in console app?

How post json body in ocelot.json route asp.net core

{
"DownstreamPathTemplate": "/ProceedToBuy/PostWishList",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 8003
}
],
"UpstreamPathTemplate": "/AddToWishlist",
"UpstreamHttpMethod": [ "POST" ]
}
I want to send json body with this route request.
Actually you don't have to route json the request will automatically route to the downstream path, we can just directly make request to upstream path with json and it'll work!

ASP.NET Core gateway ocelot API doesn't work

I'm creating a project with microservices and now I want to be able to test the API gateway that I created as an orchestrator with ocelot, but I can't test it through the browser, the API can't access it, can someone help?
ocelot.json:
{
"Routes": [
// Billing.API
{
"DownstreamPathTemplate": "/api/v1/Billing",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "billingapi",
"Port": "80"
}
],
"UpstreamPathTemplate": "/Billing",
"UpstreamHttpMethod": [ "GET" ]
}
]
}
When I run the project and in the browser URL I pass /api/v1/Billing
as I passed the DownstreamPathTemplate property.
Nothing is returned to me.
I would suggest to first try general template and see if it works:
{
"DownstreamPathTemplate": "/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "billingapi",
"Port": 80,
}
],
"UpstreamPathTemplate": "/billingapi/{everything}",
"UpstreamHttpMethod": [ "Get", "Post" ]
}
From the Ocelot documentation about Downstream:
The DownstreamPathTemplate, DownstreamScheme and DownstreamHostAndPorts define the URL that a request will be forwarded to.
And for the Upstream:
The UpstreamPathTemplate is the URL that Ocelot will use to identify which DownstreamPathTemplate to use for a given request.
You should pass UpstreamPathTemplate URL on the browser to route billing API. In your case, the request HTTP://<gateway.address>/Billings will be routed to HTTP://billingapi/api/v1/Billing.

Redirect to other address if main address is unavailable in Ocelot Gateway API

I'd like to use Ocelot Gateway Api to connect to server, but if server is unavailable (e.g. PC is offline), I want to use local service instead.
For example, if first localhost:7001 failed, use localhost:7002.
{
"Routes": [
{
"DownstreamPathTemplate": "/catalog",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 7001
},
{
"Host": "localhost",
"Port": 7002
}
],
"UpstreamPathTemplate": "/catalog-api"
}
],
"GlobalConfiguration": {
"BaseUrl": "http://localhost:7000"
}
}
Is such thing even possible?
Yes, it is perfectly possible. Ocelot supports load-balancing natively. In fact, by specifying multiple downstream paths, Ocelot will automatically load balance to the service which has the fewest number of active connections.
To have more control over the load-balancer functionality, you can specify the loadBalancerType property:
{
"Routes": [
{
"DownstreamPathTemplate": "/catalog",
"DownstreamScheme": "http",
"LoadBalancerOptions": {
"Type": "<<load balancer type here>>"
},
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 7001
},
{
"Host": "localhost",
"Port": 7002
}
],
"UpstreamPathTemplate": "/catalog-api"
}
]
}
From the docs:
The type of load balancer available are:
LeastConnection - tracks which services are dealing with requests and sends new requests to service with least existing requests. The
algorythm state is not distributed across a cluster of Ocelot’s.
RoundRobin - loops through available services and sends requests. The algorythm state is not distributed across a cluster of
Ocelot’s.
NoLoadBalancer - takes the first available service from config or service discovery.
CookieStickySessions - uses a cookie to stick all requests to a specific server
From this is seems like the one you want is paradoxically called "NoLoadBalancer".
Reference: https://ocelot.readthedocs.io/en/latest/features/loadbalancer.html

Resources