ThreeMammals / Ocelot

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

Ocelot with Eureka Middleware Error #568

Closed deadmandrive closed 6 years ago

deadmandrive commented 6 years ago

Expected Behavior / New Feature

HttpStatus 500, Unable to Handle Request

I checked output log it said

Ocelot.Errors.Middleware.ExceptionHandlerMiddleware:Debug: requestId: 0HLG7TAMB8J5G:00000002, previousRequestId: no previous request id, message: error calling middleware

Ocelot.Errors.Middleware.ExceptionHandlerMiddleware:Error: requestId: 0HLG7TAMB8J5G:00000002, previousRequestId: no previous request id, message: Exception caught in global error handler, exception message: Value cannot be null.

Actual Behavior / Motivation for New Feature

Returns actual answer from API Server

Steps to Reproduce the Problem

Hi. I try to use ocelot with eureka service Discovery this is how i set it up.

  1. ocelot Startup
 public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

  public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseUrls("http://localhost:9100")
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config
                        .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
                        .AddJsonFile("appsettings.json", true, true)
                        .AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true)
                        .AddJsonFile("ocelot.json", false, false)
                        .AddEnvironmentVariables();
                })
                .ConfigureServices(s =>
                {
                    s.AddOcelot().AddEureka();
                })
                .Configure(a =>
                {
                    a.UseOcelot().Wait();
                })
                .Build();
  1. ocelot.json
"ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/values",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/servicea",
      "UseServiceDiscovery": true,
      "ServiceName": "service-test-A",
      "UpstreamHttpMethod": [ "Get" ],
      "QoSOptions": {
        "ExceptionsAllowedBeforeBreaking": 3,
        "DurationOfBreak": 10000,
        "TimeoutValue": 5000
      },
      "FileCacheOptions": { "TtlSeconds": 15 }

    },
    {
      "DownstreamPathTemplate": "/api/values",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/serviceb",
      "UseServiceDiscovery": true,
      "ServiceName": "service-test-B",
      "UpstreamHttpMethod": [ "Get" ],
      "QoSOptions": {
        "ExceptionsAllowedBeforeBreaking": 3,
        "DurationOfBreak": 10000,
        "TimeoutValue": 5000
      },
      "FileCacheOptions": { "TtlSeconds": 15 }

    }
  ],
  "GlobalConfiguration": {
    "RequestIdKey": "null",
    "AdministrationPath": "/administration",
    "ServiceDiscoveryProvider": {
      "Host": "localhost",
      "Port": 8761,
      "Type": "Eureka",
      "Token": null,
      "ConfigurationKey": null
    }
  }
  1. appsettings.json
- OcelotAPIGateway

  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "spring": {
    "application": { "name": "Arcadia-Ocelot-Gateway" },
    "cloud": {
      "config": {
        "uri": "http://localhost:9100",
        "validateCertificates": false
      }
    }
  },
  "eureka": {
    "client": {
      "serviceUrl": "http://localhost:8761/eureka/",
      "shouldRegisterWithEureka": true,
      "shouldFetchRegistry": true,
      "validateCertificates": false
    },
    "instance": {
      "port": 9100,
      "instanceId": "localhost:9100"
    }
  },
  "AllowedHosts": "*"
}
- service-test-A
{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "spring": {
    "application": { "name": "service-test-A" },
    "cloud": {
      "config": {
        "uri": "http://localhost:9500",
        "validate_certificates": false
      }
    }
  },
  "eureka": {
    "client": {
      "serviceUrl": "http://localhost:8761/eureka/",
      "shouldFetchRegistry": true,
      "validateCertificates": false
    },
    "instance": {
      "port": 9500,
      "instanceId": "localhost:9500",
      "hostName": "localhost",
      "healthCheckUrlPath": "/api/values/healthcheck",
      "statusPageUrlPath": "/api/values/info"
    }
  },
  "AllowedHosts": "*"
}
- service-test-B
{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "spring": {
    "application": { "name": "service-test-A" },
    "cloud": {
      "config": {
        "uri": "http://localhost:9500",
        "validate_certificates": false
      }
    }
  },
  "eureka": {
    "client": {
      "serviceUrl": "http://localhost:8761/eureka/",
      "shouldFetchRegistry": true,
      "validateCertificates": false
    },
    "instance": {
      "port": 9500,
      "instanceId": "localhost:9500",
      "hostName": "localhost",
      "healthCheckUrlPath": "/api/values/healthcheck",
      "statusPageUrlPath": "/api/values/info"
    }
  },
  "AllowedHosts": "*"
}

I noticed that eureka can register all service that i want and can successfully give the right url to route

Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:9100/servicea  
Ocelot.Errors.Middleware.ExceptionHandlerMiddleware:Debug: requestId: 0HLG7TAMB8J5G:00000002, previousRequestId: no previous request id, message: ocelot pipeline started
Ocelot.DownstreamRouteFinder.Middleware.DownstreamRouteFinderMiddleware:Debug: requestId: 0HLG7TAMB8J5G:00000002, previousRequestId: no previous request id, message: Upstream url path is /servicea
Ocelot.DownstreamRouteFinder.Middleware.DownstreamRouteFinderMiddleware:Debug: requestId: 0HLG7TAMB8J5G:00000002, previousRequestId: no previous request id, message: downstream templates are /api/values
'dotnet.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\2.1.1\Microsoft.AspNetCore.Http.Extensions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Ocelot.RateLimit.Middleware.ClientRateLimitMiddleware:Information: requestId: 0HLG7TAMB8J5G:00000002, previousRequestId: no previous request id, message: EndpointRateLimiting is not enabled for /api/values
'dotnet.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.1.1\System.Security.Principal.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Ocelot.Authentication.Middleware.AuthenticationMiddleware:Information: requestId: 0HLG7TAMB8J5G:00000002, previousRequestId: no previous request id, message: No authentication needed for /servicea
Ocelot.Authorisation.Middleware.AuthorisationMiddleware:Information: requestId: 0HLG7TAMB8J5G:00000002, previousRequestId: no previous request id, message: /api/values route does not require user to be authorised
Steeltoe.Discovery.Eureka.DiscoveryClient:Debug: GetInstances returning: Instance[InstanceId=localhost:9500,HostName=localhost,IpAddr=10.0.75.1,Status=UP,IsUnsecurePortEnabled=True,Port=9500,IsSecurePortEnabled=False,SecurePort=443,VipAddress=service-test-A,SecureVipAddress=service-test-A,ActionType=ADDED]
Ocelot.DownstreamUrlCreator.Middleware.DownstreamUrlCreatorMiddleware:Debug: requestId: 0HLG7TAMB8J5G:00000002, previousRequestId: no previous request id, message: Downstream url is http://localhost:9500/api/values
Ocelot.Cache.Middleware.OutputCacheMiddleware:Debug: requestId: 0HLG7TAMB8J5G:00000002, previousRequestId: no previous request id, message: Started checking cache for GET-http://localhost:9100/servicea
Ocelot.Cache.Middleware.OutputCacheMiddleware:Debug: requestId: 0HLG7TAMB8J5G:00000002, previousRequestId: no previous request id, message: no resonse cached for GET-http://localhost:9100/servicea
Ocelot.Requester.HttpClientHttpRequester:Debug: requestId: 0HLG7TAMB8J5G:00000002, previousRequestId: no previous request id, message: Cache key for request is GET:http://localhost:9100/servicea

but in the web ui it not response as it should.

Specifications

deadmandrive commented 6 years ago

Is there anyway i can do to fix this? also i try this sample in Visual studio it didn't work too.

TomPallister commented 6 years ago

@deadmandrive the eureka sample is out of date now :( it needs to be moved to the Ocelot.Provider.Eureka repo I think.

All I can think of is get the Oceot source code and use this and do some debugging to see if you can work out what the problem is.

deadmandrive commented 6 years ago

@TomPallister Thank you for your reply.

deadmandrive commented 6 years ago

@TomPallister Hi Tom I think i found the problem. I try remove

"QoSOptions": {
        "ExceptionsAllowedBeforeBreaking": 3,
        "DurationOfBreak": 10000,
        "TimeoutValue": 5000
      },
      "FileCacheOptions": { "TtlSeconds": 15 }

from every route and now it working. just wonder why is this happening? but i guess i try using it for now.

TomPallister commented 6 years ago

@deadmandrive ahhh this might be a bug. Ocelot.Provider.Polly package referenced?

deadmandrive commented 6 years ago

@TomPallister Oh. I see it now. it was my mistake to reference the wrong package thank again Tom

TomPallister commented 6 years ago

Fixed in version 11.0.0

TomPallister commented 6 years ago

make sure also using 0.1.1 of Ocelot.Provider.Consul if upgrading.