Eureka integration

I’m setting up Eureka to integrate with Tyk. I didn’t find any example and my attempts failed so far. In order to get a JSON reply from Eureka, I configured the endpoint to be a Tyk endpoint that inserts the header “Accept: application/json” in order to retrieve the JSON reply. But fails with a 502 Bad Gateway reply and the log file reads:
http: panic serving 127.0.0.1:51107: runtime error: invalid memory address or nil pointer dereference
goroutine 10607011 [running]:
net/http.(*conn).serve.func1(0xc8231ae000, 0x7f2291d67f58, 0xc82301eaf0)
/usr/local/go/src/net/http/server.go:1287 +0xb5
main.(*ServiceDiscovery).GetSubObjectFromList(0xc8232d49c8, 0xc822ad4ab0, 0x2)
/home/tyk/go/src/github.com/lonelycode/tyk/service_discovery.go:181 +0x5b5
main.(*ServiceDiscovery).ProcessRawData(0xc8232d49c8, 0xc8226f6800, 0x76d, 0x0, 0x0, 0x0, 0x0)
/home/tyk/go/src/github.com/lonelycode/tyk/service_discovery.go:254 +0xa82
main.(*ServiceDiscovery).GetTarget(0xc8232d49c8, 0xc821e227b0, 0x2e, 0x0, 0x0, 0x0, 0x0)
/home/tyk/go/src/github.com/lonelycode/tyk/service_discovery.go:271 +0xc4
main.GetURLFromService(0xc8226ff900, 0x0, 0x0, 0x0, 0x0)
/home/tyk/go/src/github.com/lonelycode/tyk/tyk_reverse_proxy_clone.go:29 +0x1a6

I used the test cases (service_discovery_test.go) in the source code to validate my configuration options. (BTW. there seems to be a bug in the UI that the parent path configuration disappears if “nested reply” is not selected - although both are independent of each other):
sd.isNested = false
sd.isTargetList = true
sd.endpointReturnsList = false
sd.portSeperate = true
sd.dataPath = “hostName”
sd.parentPath = “application.instance”
sd.portPath = “port.$”
for the Eureka-Reply that looks like
{
“application”: {
“name”: “ROUTE”,
“instance”: [
{
“hostName”: “ip-172-31-57-136”,
“ipAddr”: “172.31.57.136”,
“port”: {
@enabled”: “true”,
“$”: “47954”
},

},
{
“hostName”: “ip-172-31-13-37”,
“app”: “ROUTE”,
“ipAddr”: “172.31.13.37”,
“port”: {
@enabled”: “true”,
“$”: “34406”
}, …

which returns &[ip-172-31-57-136:47954 ip-172-31-13-37:34406]. Looks fine to me.

Any idea what’s happening here? Anybody with a successful Eureka integration?

Cheers,
Jörg

Hi,

I’ve set up a test case for your eureka response data and settings - and you’re right, they do indeed seem to work, though I’d ask that next time please use the code formatting tools available (markdown) as it makes these things so much easier to read.

What fails? The new Tyk endpoint getting your Eureka JSON data, or when you try to access the API that is configured to use this URL as a service discovery service?

Some questions:

  1. What version are you running?
  2. The Tyk Endpoint that returns the Eureka JSON response, it isn’t on the same API as that using service discovery, right? It’s a separate API definition?

They aren’t independent, the parent path defines the path of the data-holding object’s parent, so you only define it if the object you are trying to extract is nested, i.e. “nested reply” is true. So:

  • The parent path = the container that holds the object that holds your data (parentObj in the below case)
  • data path = the data you are looking for (nestedObj.hostname etc.):
{
    "parentObj": {
    	"nestedObj": {
    		"hostname": "foo",
    		"port": "bar" 
    	}
    }
}

Thanks Martin, for the quick reply.
I configured http://[tykhost]/eureka as the endpoint that enriches the request with the Accept:-header. The real eureka url is http://[eurekahost]/eureka/apps/ROUTE.
When I query http://[tykhost]/eureka, I get the JSON back as intended.

I configure the ROUTE-Endpoint in tyk so that it uses service discovery via http://[tykhost]/eureka. And when I set a request to http://[tykhost]/MyROUTE, the answer is 502 Bad Gateway. (BTW: If I hardcode the ROUTE-services as the target URL in tyk, it works).

Concerning “nested”: My understanding about “nested” was to parse the content of a JSON value as another JSON object, something like this:
"value": "{\"hostname\": \"httpbin.org\", \"port\": \"80\"}",

I’m running 1.9.1.1. I ran tyk in --debug and the log file reads (sorry for the bad formatting - but that’s directly from the logfile. I inserted a blank line after each line, hope that makes it more readable…):

Parsing raw data: {“application”:{“name”:“ROUTE”,“instance”:[{“hostName”:“ip-172-31-57-136”,“app”:“ROUTE”,“ipAddr”:“172.31.57.136”,“status”:“UP”,“overriddenstatus”:“UNKNOWN”,“port”:{“@enabled”:“true”,“$”:“60565”},“securePort”:{“@enabled”:“false”,“$”:“443”},“countryId”:1,“dataCenterInfo”:{“@class”:“com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo”,“name”:“MyOwn”},“leaseInfo”:{“renewalIntervalInSecs”:10,“durationInSecs”:10,“registrationTimestamp”:1460471383902,“lastRenewalTimestamp”:1460471403565,“evictionTimestamp”:0,“serviceUpTimestamp”:1460471383340},“metadata”:{“instanceId”:“route:f673c15eebfc456a3c679a55d234a8ca”,“payment”:“perCall”,“providerName”:“MisterA”},“homePageUrl”:“http://ip-172-31-57-136:60565/”,“statusPageUrl”:“http://ip-172-31-57-136:60565/info”,“healthCheckUrl”:“http://ip-172-31-57-136:60565/health”,“vipAddress”:“route”,“isCoordinatingDiscoveryServer”:false,“lastUpdatedTimestamp”:1460471383902,“lastDirtyTimestamp”:1460471429751,“actionType”:“ADDED”},{“hostName”:“ip-172-31-13-37”,“app”:“ROUTE”,“ipAddr”:“172.31.13.37”,“status”:“UP”,“overriddenstatus”:“UNKNOWN”,“port”:{“@enabled”:“true”,“$”:“50045”},“securePort”:{“@enabled”:“false”,“$”:“443”},“countryId”:1,“dataCenterInfo”:{“@class”:“com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo”,“name”:“MyOwn”},“leaseInfo”:{“renewalIntervalInSecs”:10,“durationInSecs”:10,“registrationTimestamp”:1460471387114,“lastRenewalTimestamp”:1460471407062,“evictionTimestamp”:0,“serviceUpTimestamp”:1460471386750},“metadata”:{“instanceId”:“route:838ba7845f1fd63d94c10ca9efdf77a5”,“payment”:“flat”,“providerName”:“MissB”},“homePageUrl”:“http://ip-172-31-13-37:50045/”,“statusPageUrl”:“http://ip-172-31-13-37:50045/info”,“healthCheckUrl”:“http://ip-172-31-13-37:50045/health”,“vipAddress”:“route”,“isCoordinatingDiscoveryServer”:false,“lastUpdatedTimestamp”:1460471387114,“lastDirtyTimestamp”:1460471360189,“actionType”:“ADDED”}]}}

^[[37mDEBU^[[0m[0351] Got:{“application”:{“instance”:[{“actionType”:“ADDED”,“app”:“ROUTE”,“countryId”:1,“dataCenterInfo”:{“@class”:“com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo”,“name”:“MyOwn”},“healthCheckUrl”:“http://ip-172-31-57-136:60565/health",“homePageUrl”:“http://ip-172-31-57-136:60565/”,“hostName”:“ip-172-31-57-136”,“ipAddr”:“172.31.57.136”,“isCoordinatingDiscoveryServer”:false,“lastDirtyTimestamp”:1.460471429751e+12,“lastUpdatedTimestamp”:1.460471383902e+12,“leaseInfo”:{“durationInSecs”:10,“evictionTimestamp”:0,“lastRenewalTimestamp”:1.460471403565e+12,“registrationTimestamp”:1.460471383902e+12,“renewalIntervalInSecs”:10,“serviceUpTimestamp”:1.46047138334e+12},“metadata”:{“instanceId”:“route:f673c15eebfc456a3c679a55d234a8ca”,“payment”:“perCall”,“providerName”:“MisterA”},“overriddenstatus”:“UNKNOWN”,“port”:{“$”:“60565”,“@enabled”:“true”},“securePort”:{“$”:“443”,“@enabled”:“false”},“status”:“UP”,“statusPageUrl”:“http://ip-172-31-57-136:60565/info”,“vipAddress”:“route”},{“actionType”:“ADDED”,“app”:“ROUTE”,“countryId”:1,“dataCenterInfo”:{“@class”:“com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo”,“name”:“MyOwn”},“healthCheckUrl”:“http://ip-172-31-13-37:50045/health”,“homePageUrl”:“http://ip-172-31-13-37:50045/”,“hostName”:“ip-172-31-13-37”,“ipAddr”:“172.31.13.37”,“isCoordinatingDiscoveryServer”:false,“lastDirtyTimestamp”:1.460471360189e+12,“lastUpdatedTimestamp”:1.460471387114e+12,“leaseInfo”:{“durationInSecs”:10,“evictionTimestamp”:0,“lastRenewalTimestamp”:1.460471407062e+12,“registrationTimestamp”:1.460471387114e+12,“renewalIntervalInSecs”:10,“serviceUpTimestamp”:1.46047138675e+12},“metadata”:{“instanceId”:“route:838ba7845f1fd63d94c10ca9efdf77a5”,“payment”:“flat”,“providerName”:“MissB”},“overriddenstatus”:“UNKNOWN”,“port”:{“$”:“50045”,“@enabled”:“true”},“securePort”:{“$”:“443”,“@enabled”:“false”},“status”:“UP”,“statusPageUrl”:“http://ip-172-31-13-37:50045/info”,“vipAddress”:“route”}],“name”:"ROUTE”}}

^[[37mDEBU^[[0m[0351] It’s a target list - getting sub object from list

^[[37mDEBU^[[0m[0351] Passing in: {map[application:map[name:ROUTE instance:[map[countryId:1 metadata:map[instanceId:route:f673c15eebfc456a3c679a55d234a8ca payment:perCall providerName:MisterA] isCoordinatingDiscoveryServer:false securePort:map[@enabled:false $:443] homePageUrl:http://ip-172-31-57-136:60565/ healthCheckUrl:http://ip-172-31-57-136:60565/health vipAddress:route actionType:ADDED hostName:ip-172-31-57-136 app:ROUTE ipAddr:172.31.57.136 dataCenterInfo:map[name:MyOwn @class:com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo] statusPageUrl:http://ip-172-31-57-136:60565/info lastDirtyTimestamp:1.460471429751e+12 status:UP overriddenstatus:UNKNOWN port:map[@enabled:true $:60565] leaseInfo:map[lastRenewalTimestamp:1.460471403565e+12 evictionTimestamp:0 serviceUpTimestamp:1.46047138334e+12 renewalIntervalInSecs:10 durationInSecs:10 registrationTimestamp:1.460471383902e+12] lastUpdatedTimestamp:1.460471383902e+12] map[securePort:map[@enabled:false $:443] dataCenterInfo:map[@class:com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo name:MyOwn] metadata:map[instanceId:route:838ba7845f1fd63d94c10ca9efdf77a5 payment:flat providerName:MissB] statusPageUrl:http://ip-172-31-13-37:50045/info healthCheckUrl:http://ip-172-31-13-37:50045/health actionType:ADDED app:ROUTE overriddenstatus:UNKNOWN port:map[$:50045 @enabled:true] homePageUrl:http://ip-172-31-13-37:50045/ hostName:ip-172-31-13-37 ipAddr:172.31.13.37 status:UP countryId:1 isCoordinatingDiscoveryServer:false lastDirtyTimestamp:1.460471360189e+12 leaseInfo:map[registrationTimestamp:1.460471387114e+12 lastRenewalTimestamp:1.460471407062e+12 evictionTimestamp:0 serviceUpTimestamp:1.46047138675e+12 renewalIntervalInSecs:10 durationInSecs:10] vipAddress:route lastUpdatedTimestamp:1.460471387114e+12]]]]}

2016/04/12 14:30:36 http: panic serving 127.0.0.1:52626: runtime error: invalid memory address or nil pointer dereference

Thanks for your help,
Jörg

I would suggest you upgrade to 2.0, there were some very valuable PR’s that stabilised the service discovery module in that release, it’s also the release that successfully runs the Eureka test:

https://github.com/TykTechnologies/tyk/blob/develop/service_discovery_test.go#L191

Jus to be absolutely sure that 2.0 is handling it ok, I updated the test to use your actual data and it passes just fine.