We have been using Eureka with our Spring Boot applications for few months now. We have enabled service lookup between applications using @DiscoveryClient
annotations. The registrations, lease renewals and deregistration works as expected.
Recently, we have encountered a scenario where we have non-Java application component (written in C++), which is exposes 3 REST service endpoints that many of our Spring Boot Java applications would use. We are trying to see if the C++ component can make use of the Eureka server's REST APIs to register itself when it came up, so that the Spring Boot Java applications can perform the usual lookup via Eureka to get in touch with the C++ component.
Since I cannot use the Eureka Client in the C++ components (obviously), I started testing direct REST APIs (as described here) using Postman. The registration worked without any problems by sending a JSON payload using POST method to http://eurekaserver:8761/eureka/apps/FOO-APP (with instanceId = 1111 and hostName = foo-app). I can query http://eurekaserver:8761/eureka/apps and can see FOO-APP listed there as expected.
However, when I try the cancel operation using DELETE method to http://eurekaserver:8761/eureka/apps/FOO-APP/1111 or http://eurekaserver:8761/eureka/apps/FOO-APP/foo-app, I get a 404 error.
With instanceId:
{
"timestamp": 1447479397996,
"status": 404,
"error": "Not Found",
"message": "Not Found",
"path": "/eureka/apps/FOO-APP/1111"
}
OR (same outcome for hostName):
{
"timestamp": 1447479397996,
"status": 404,
"error": "Not Found",
"message": "Not Found",
"path": "/eureka/apps/FOO-APP/foo-app"
}
I tried different combinations, but I am not able to make this work. I have a feeling I am missing something obvious - may be something small. Any help on this would be appreciated.
PS: Eureka REST endpoint documentation mentions "v2" in the URL. However, that does not work in my case. Registration (which works for me) does not use "v2" as described above. If someone could validate this, that would be helpful as well. There just doesn't seem to be enough material on this.
Finally, I have figured out how the cancel
operation can be invoked using REST URLs of a Eureka server. This works for Spring Cloud Eureka server, but should also work for the Netflix Eureka server.
The URL pattern for the cancel
operation is as the following:
DELETE http://eureka_host:eureka_port/eureka/apps/<appName>/<instanceId>
This is how it is documented at the Eureka REST operations page, but there's very little clarity as to what <instanceId>
was supposed to be. As per the documentation, <instanceId>
is the hostname of the host that runs the Eureka client. That did not work (IP address or host name). I tried passing in the same value that the GET
URL gave me (for example, 192.168.55.55) or localhost
. That did not work either. I also tried passing in the instanceId
value from the GET
output (which would be the same as the value of eureka.instance.metadataMap.instanceId property). That too, didn't work. I literally had to try different combinations to find this out. The <instanceId>
is the concatenation of the hostname and instance ID, separated by :
. For example, 192.168.55.55:foo-app-some-random-str
.
Here's an example output of the GET
operation listing the active instance registered with Eureka:
<instance>
<hostName>192.168.55.55</hostName>
<app>FOO-APP</app>
...
<metadata>
<instanceId>foo-app-f4ea7b06fc03a05a06900713f7526a5d</instanceId>
</metadata>
...
</instance>
In this case, the cancel
cURL command would look like this:
$ curl -X "DELETE" http://eureka_host:eureka_port/eureka/apps/FOO-APP/192.168.55.55:foo-app-f4ea7b06fc03a05a06900713f7526a5d
That would de-register the instance as expected.
That said, I must confess that I wasn't paying much attention to the Eureka server logs. When you register the Eureka client, the log printed out the fully qualified name of the instance (FOO-APP/192.168.55.55:foo-app-f4ea7b06fc03a05a06900713f7526a5d
), which I could have used as my guess.
I hope someone fixes this in the Eureka documentation.