asp.net-core.net-coreapi-gatewayservice-discoveryocelot

Redirect to secondary host when primary host is unavailable in Ocelot API Gateway (C#, .NET Core, Ocelot)


I would like to use Ocelot API Gateway to connect services, but if the primary host is unavailable it needs to redirect to secondary host.

For example in below configuration i have two ports one is 5023 and 5102, So when 5023 is unavailable i want it to redirect to 5102.

Please help, Thanks in advance.

configuration.json

{
  "Routes": [
    {
       "DownstreamPathTemplate": "/GetProductDetails",
       "DownstreamScheme": "http",
       "DownstreamHostAndPorts": [
         {
           "Host": "localhost",
           "Port": 5023
         },
         {
           "Host": "localhost",
           "Port": 5102
         }
       ],

       "UpstreamPathTemplate": "/",
       "LoadBalancerOptions": {
         "Type": "RoundRobin" 
       },
      "UpstreamHttpMethod": [ "GET" ]
    }
  ]
}

Program.cs

using Ocelot.DependencyInjection;
using Ocelot.Middleware;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration.AddJsonFile(
"configuration.json",optional:false,reloadOnChange:true);

builder.Services.AddOcelot(builder.Configuration);

var app = builder.Build();


app.MapControllers();

var ocelotConf = new OcelotPipelineConfiguration()
{
    PreErrorResponderMiddleware = async (context, next) =>
    {
        if (context.Response != null)
        {

        }
        await next.Invoke();
    }
};

await app.UseOcelot(ocelotConf);

app.Run();

Either can we write custom load balancer?


Solution

  • Finally after thinking so much i have understood that from request pipeline we can process to next invoke if the current host is not active.

    Code is below.

    var ocelotConf = new OcelotPipelineConfiguration()
    {
        PreErrorResponderMiddleware = async (context, next) =>
        {
            // Initial invoke
            await next.Invoke();
            if (context.Response != null)
            {
                // Checking if the initial invoke is throwing 502
                //(Means service is down)
                if(context.Response.StatusCode == 502)
                {
                    // If service is down forwarding to next host
                    await next.Invoke();
                }
            }
        }
    };
    
    await app.UseOcelot(ocelotConf);