Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible discrepancy between documented REST operations and actual serialization/deserialization? #1563

Open
ljnelson opened this issue Nov 26, 2024 · 1 comment

Comments

@ljnelson
Copy link

The Wiki describes REST operations here: https://github.com/Netflix/eureka/wiki/Eureka-REST-operations

Considering the logical "register" operation, accomplished via HTTP POST, the logical schema of its payload, represented in XSD but also applicable to JSON, is also in the Wiki citation above.

However, it seems to diverge widely from the way in which, for example, an InstanceInfo, representing a desired registration, is actually serialized over the wire during a register operation: https://github.com/Netflix/eureka/blob/v2.0.3/eureka-client/src/main/java/com/netflix/discovery/converters/EurekaJacksonCodec.java#L343-L422

A minimal example would be LeaseInfo. The schema says that leaseInfo is an optional element consisting of exactly one field, evictionDurationInSecs, which must be a positive integer. Taking Jackson annotations and conventions into account, I see no such analogous property in LeaseInfo. Because in fact LeaseInfo is serialized entirely by Jackson, what would be serialized is its (potentially many) properties instead, such as durationInSecs, renewalIntervalInSecs, and so on.

Does this mean the XML schema is out of date? Is there another API resource instead I should be looking at if I were trying to do things via, say, curl?

@ljnelson
Copy link
Author

In case it is helpful I've reverse engineered a JSON schema that accurately describes the JSON representing an InstanceInfo as would be submitted by a user performing registration and/or renewal. Note the discrepancy between what this describes and what is documented in the wiki:

{
    "$id" : "https://github.com/Netflix/eureka/instance-info.schema.json",
    "$schema" : "https://json-schema.org/draft/2020-12/schema",
    "title" : "InstanceInfo",
    "description" : "A caller-supplied InstanceInfo object's JSON representation",
    "type" : "object",
    "required" : [ "app", "countryId", "dataCenterInfo", "hostName", "instanceId", "ipAddr", "metadata", "overriddenStatus", "port", "securePort", "status"],    
    "properties" : {
        "app" : {
            "type" : "string",
            "pattern" : "^\\S+$"
        },
        "appGroupName" : {
            "type" : "string"
        },
        "asgName" : {
            "type" : "string"
        },
        "countryId" : {
            "const" : 1
        },
        "dataCenterInfo" : {
            "$ref" : "#/$defs/dataCenterInfo"
        },
        "healthCheckUrl" : {
            "type" : "string",
            "format" : "uri"
        },
        "homePageUrl" : {
            "type" : "string",
            "format" : "uri"
        },
        "hostName" : {
            "type" : "string",
            "format" : "hostname",
            "pattern" : "^\\S+$"
        },
        "instanceId" : {
            "type" : "string",
            "pattern" : "^\\S+$"
        },
        "ipAddr" : {
            "type" : "string",
            "format" : "ipv4",
            "pattern" : "^\\S+$",
            "$comment" : "There is no way in JSON Schema to have multiple formats; ipv6 should also be OK"
        },
        "lastDirtyTimestamp" : {
            "type" : "number",
            "$comment" : "e.g. System.currentTimeMillis() in Java"
        },
        "lastUpdatedTimestamp" : {
            "type" : "number",
            "$comment" : "e.g. System.currentTimeMillis() in Java"
        },
        "leaseInfo" : {
            "$ref" : "#/$defs/leaseInfo"
        },
        "metadata" : {
            "type" : "object",
            "$comment" : "Keys and values are strings only"
        },
        "overriddenstatus" : {
            "$ref" : "#/$defs/status",
            "default" : "UNKNOWN"
        },
        "overriddenStatus" : {
            "$ref" : "#/$defs/status",
            "default" : "UNKNOWN"
        },
        "port" : {
            "$ref" : "#/$defs/port"
        },
        "secureHealthCheckUrl" : {
            "type" : "string",
            "format" : "uri"
        },
        "securePort" : {
            "$ref" : "#/$defs/port"
        },
        "secureVipAddress" : {
            "type" : "string"
        },
        "sid" : {
            "const" : "na"
        },
        "status" : {
            "$ref" : "#/$defs/status",
            "default" : "STARTING",
            "$comment" : "Can be set to UP as a default"
        },
        "statusPageUrl" : {
            "type" : "string",
            "format" : "uri"
        },
        "vipAddress" : {
            "type" : "string"
        },
    },

    "$defs" : {
        "dataCenterInfo" : {
            "type" : "object",
            "required" : [ "name", "@class" ],
            "if" : {
                "properties" : {
                    "name" : { "const" : "Amazon" }
                }
            },
            "then" : {
                "required" : [ "metadata" ],
                "properties" : {
                    "@class" : { "const" : "com.netflix.appinfo.AmazonInfo" }
                }
            },
            "else" : {
                "properties" : {
                    "@class" : { "const" : "com.netflix.appinfo.MyDataCenterInfo" }
                }
            },
            "properties" : {
                "name" : {
                    "enum" : [ "Amazon", "MyOwn" ],
                    "default" : "MyOwn",
                },
                "@class" : {
                    "enum" : [ "com.netflix.appinfo.AmazonInfo", "com.netflix.appinfo.MyDataCenterInfo" ],
                    "default" : "com.netflix.appinfo.MyDataCenterInfo",
                },
                "metadata" : {
                    "type" : "object"
                }
            }
        },
        "leaseInfo" : {
            "type" : "object",
            "properties" : {
                "renewalIntervalInSecs" : {
                    "type" : "number",
                    "minimum" : 0
                },
                "durationInSecs" : {
                    "type" : "number",
                    "minimum" : 0
                }
            }
        },
        "port" : {
            "type" : "object",
            "required" : [ "$", "@enabled" ],
            "properties" : {
                "$" : {
                    "type" : "number",
                    "minimum" : 0
                },
                "@enabled" : {
                    "type" : "boolean"
                }
            }
        },
        "status" : {
            "enum" : [ "UP", "DOWN", "STARTING", "OUT_OF_SERVICE", "UNKNOWN" ]
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant