Using Eureka as a registry using REST APIs
Asked Answered
A

1

9

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.

Aude answered 14/11, 2015 at 5:43 Comment(4)
Have you considered using a sidecar instead? It deals with registration and also acts as a revers proxy if you C++ application wants to connect to other deployed services. You application only needs to expose it's health status in the predefined format.Inspectorate
That's an option. But I am trying to achieve this by calling straight REST endpoints. cURL invocations should work in my opinion. But they that's not happening.Aude
spring-cloud didn't include the v2. You are probably using the wrong instanceId. What version of spring cloud are you using? Do you set instanceId somewhere in the apps?Forenoon
The URLs I am trying using Postman or cURL do not have v2 in them. I'm using Eureka with Spring Cloud Starter Angle.SR3. I'm registering using the POST URL and not via the Java (to try the Eureka REST URLs via cURL). All I need is the REST endpoint that works for DELETE or cancel operation.Aude
A
17

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.

Aude answered 16/12, 2015 at 19:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.