Netflix-Skunkworks/zerotodocker

Eureka docker 1.3.1 instance registrations failing

jquatier opened this issue · 12 comments

I recently started using the netflixoss/eureka:1.3.1 docker image but I'm getting a 400 Bad Request error on all registrations. This issue doesn't seem to exist on 1.1.147, which is very odd.

The error in the response is: {error:'cannot parse request body'}

Here's my POST body:

{
    "instance": {
        "app": "jqservice",
        "hostName": "localhost",
        "ipAddr": "127.0.0.1",
        "port": 8080,
        "vipAddress": "jq.test.something.com",
        "dataCenterInfo": {
            "name": "MyOwn"
        },
        "status": "UP"
    }
}

URL: http://192.168.99.100:8080/eureka/v2/apps/jqservice

Headers:
Content-Type: application/json
Accept: application/json

If I switch back to netflixoss/eureka:1.1.147 the request succeeds with no other changes. Was there any major changes to the request body that I'm missing? I don't see anything in the server log around the bad request when this happens. If there's anything else I should try, let me know. Thanks!

tbak commented

Can you upgrade to the latest Eureka release, and confirm that the error is still there?

@tbak still seeing the issue on 1.4.3 so I turned on DEBUG and found out where it's failing:

java.lang.NullPointerException
        at com.netflix.discovery.converters.EurekaJacksonCodec$InstanceInfoDeserializer.deserialize(EurekaJacksonCodec.java:438)
        at com.netflix.discovery.converters.EurekaJacksonCodec$InstanceInfoDeserializer.deserialize(EurekaJacksonCodec.java:395)

Looked into it some more and found that it looks like port is now an object that needs to have properties of $ and @enabled ? Does this sound right? The wiki doesn't have those but I suppose it could be out of date.

After I added those properties, I ran into another issue were I had to add a @class property under the dataCenterInfo block. In the end, this is the JSON that worked:

{
    "instance": {
        "app": "jqservice",
        "hostName": "localhost",
        "ipAddr": "127.0.0.1",
        "port": {
          "$":8080, 
          "@enabled": true
        },
        "vipAddress": "jq.test.something.com",
        "dataCenterInfo": {
          "@class":"com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo",
          "name": "MyOwn"
        },
        "status": "UP"
    }
}

Anyway I guess I want to make sure that there WAS a schema change in newer Eureka versions that would make the old JSON incompatible. Or, perhaps theres some transform happening that I don't know about.

Thanks for the reply!

tbak commented

The port format is as in the last snippet. This comes from legacy XML
encoding, where port element had enabled. This format is very unfortunate,
but we cannot get away from it.

On Wed, Mar 9, 2016 at 11:41 AM, Jacob Quatier notifications@github.com
wrote:

@tbak https://github.com/tbak still seeing the issue on 1.4.3 so I
turned on DEBUG and found out where it's failing:

java.lang.NullPointerException
at com.netflix.discovery.converters.EurekaJacksonCodec$InstanceInfoDeserializer.deserialize(EurekaJacksonCodec.java:438)
at com.netflix.discovery.converters.EurekaJacksonCodec$InstanceInfoDeserializer.deserialize(EurekaJacksonCodec.java:395)

Looked into it some more and found that it looks like port is now an
object that needs to have properties of $ and @enabled ? Does this sound
right? The wiki doesn't have those but I suppose it could be out of date.

After I added those properties, I ran into another issue were I had to add
a @Class property under the dataCenterInfo block. In the end, this is the
JSON that worked:

{
"instance": {
"app": "jqservice",
"hostName": "localhost",
"ipAddr": "127.0.0.1",
"port": {
"$":8080,
"@enabled": true
},
"vipAddress": "jq.test.something.com",
"dataCenterInfo": {
"@Class":"com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo",
"name": "MyOwn"
},
"status": "UP"
}
}

Anyway I guess I want to make sure that there WAS a schema change in newer
Eureka versions that would make the old JSON incompatible. Or, perhaps
theres some transform happening that I don't know about.

Thanks for the reply!


Reply to this email directly or view it on GitHub
#46 (comment)
.

@tbak thanks! It looks like the format would have changed in version 1.3.8, in this PR. Correct? Versions prior to that would simply want { port: 8080 } because port was just an integer before that release and not an object.

The main reason I ask is because I have a JS Eureka client module on NPM and I might need to make it support both the old and the new formats. No one has run into this issue yet that I know of, which must mean they are on an older Eureka version. Since 1.3.8 only was released about a month ago, that would make sense.

Eh, scratch that, it might be version 1.1.152 when it changed and this PR.

tbak commented

It was never in { port: 8080 } format. We have running different versions
of eureka-client in our environment, some much older then yours, and they
are all working fine. There might be some bad release, that changed this
format one time. I am not aware of it, but if that happened, this could be
your issue.

On Wed, Mar 9, 2016 at 1:01 PM, Jacob Quatier notifications@github.com
wrote:

Eh, scratch that, it might be version 1.1.152 when it changed and this PR
Netflix/eureka#470.


Reply to this email directly or view it on GitHub
#46 (comment)
.

Ok, I must be missing something. I was looking at this diff:
https://github.com/Netflix/eureka/pull/730/files#diff-5c4867f1943cb0c4ed3965e60f55a905L143

That's where the datatype of that field changed from an int to a PortWrapper which deals with the $ and @enabled properties. But I'm sure I'm making some assumptions on that.

In any case, {port: 8080} seems to work on the older versions, at least from my own testing on 1.1.147 and comparing that with the latest and 1.3.1. Perhaps the issue is only a problem with the JSON format and the XML is fine.

tbak commented

This type was introduced to explicitly model transport layer view, which
was previously coded in Jackson codec. So this commit did not change
anything at the REST representation layer.

On Wed, Mar 9, 2016 at 1:13 PM, Jacob Quatier notifications@github.com
wrote:

Ok, I must be missing something. I was looking at this diff:

https://github.com/Netflix/eureka/pull/730/files#diff-5c4867f1943cb0c4ed3965e60f55a905L143

That's where the datatype of that field changed from an int to a
PortWrapper which deals with the $ and @enabled properties. But I'm sure
I'm making some assumptions on that.

In any case, {port: 8080} seems to work on the older versions, at least
from my own testing on 1.1.147 and comparing that with the latest and
1.3.1. Perhaps the issue is only a problem with the JSON format and the
XML is fine.


Reply to this email directly or view it on GitHub
#46 (comment)
.

Yeah, I'm not 100% sure where the change was. It could be the other PR I found, since that also introduced the DataCenterInfoDeserializer which I used to figure out that I needed an @class property on the dataCenterInfo section (which I didn't need prior to that version).

Theres a clear difference between pre 1.1.152 and post 1.1.152 since the simpler port format works on previous versions, but I'm not going to worry about it because those versions are way old anyway. At some point I might take a stab at posting some kind of JSON spec or schema in the wiki since all that's there now is the XSD and without reading the code its hard to tell what should get posted for JSON (especially the port and datacenter stuff). But I'll leave it for now. Thanks again for the help @tbak!

I'm trying to update my copy of the necessary registration Schema (found here: https://github.com/Netflix/eureka/wiki/Eureka-REST-operations) but I don't know how to get those @ signs to work in the schema file, has anyone else got the schema updated that I can see?

I have successfully connected my NodeJs App to Spring Cloud Registry with 'eureka-js-client' npm module with following configurations:

const Eureka = require('eureka-js-client').Eureka;

const eureka = new Eureka({
instance: {
app: 'booking-service',
hostName: 'localhost',
ipAddr: '127.0.0.1',
statusPageUrl: 'http://localhost:8080',
port: {
'$': port,
'@enabled': 'true',
},
vipAddress: 'localhost',
dataCenterInfo: {
'@Class': 'com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo',
name: 'MyOwn',
}
},
eureka: {
host: 'localhost',
port: 8761, /* Spring Cloud Eureka Registry */
servicePath: '/eureka/apps/'
}
});
eureka.logger.level('debug');
eureka.start(function(error){
console.log(error || 'complete');
});

Now, I'm trying to connect to JHipster Registry which is protected by username and password. If I configure Eureka for JHipster Registry as following, it rejects the connection from JHipster Registry as it would be an anauthorized request:

eureka: { host: 'localhost', port: 8765, /* JHipster Registry*/ servicePath: '/eureka/' }

I am unable to find how to configure authentication parameters in Eureka configuration in NodeJs. Kindly share some pointers. Thanks.

@hushensavani You should be able to utilize the requestMiddleware functionality here. You can use it to set any custom auth headers or just basic auth since you get passed the request options if you provide that callback.