Unverified Commit 7b75fe93 by Ryan Baxter Committed by GitHub

Return 404 upstream when using Eureka and RestTemplate. Fixes #2861 (#3023)

parent 8c7116b2
......@@ -19,8 +19,10 @@ package org.springframework.cloud.netflix.eureka.http;
import java.net.URI;
import java.net.URISyntaxException;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.support.BasicAuthorizationInterceptor;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.BeanDescription;
......@@ -74,6 +76,7 @@ public class RestTemplateTransportClientFactory implements TransportClientFactor
}
restTemplate.getMessageConverters().add(0, mappingJacksonHttpMessageConverter());
restTemplate.setErrorHandler(new ErrorHanlder());
return restTemplate;
}
......@@ -134,4 +137,20 @@ public class RestTemplateTransportClientFactory implements TransportClientFactor
public void shutdown() {
}
class ErrorHanlder extends DefaultResponseErrorHandler {
@Override
protected boolean hasError(HttpStatus statusCode) {
/**
* When the Eureka server restarts and a client tries to sent a heartbeat the server
* will respond with a 404. By default RestTemplate will throw an exception in this case.
* What we want is to return the 404 to the upstream code so it will send another registration
* request to the server.
*/
if(statusCode.is4xxClientError()) {
return false;
}
return super.hasError(statusCode);
}
}
}
......@@ -20,6 +20,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
......@@ -82,13 +83,16 @@ public class EurekaServerMockApplication {
@ResponseStatus(HttpStatus.OK)
@PutMapping(value = "/apps/{appName}/{id}", params = { "status",
"lastDirtyTimestamp" })
public InstanceInfo sendHeartBeat(@PathVariable String appName,
@PathVariable String id, @RequestParam String status,
@RequestParam String lastDirtyTimestamp,
@RequestParam(required = false) String overriddenstatus) {
return new InstanceInfo(null, null, null, null, null, null, null, null, null,
public ResponseEntity sendHeartBeat(@PathVariable String appName,
@PathVariable String id, @RequestParam String status,
@RequestParam String lastDirtyTimestamp,
@RequestParam(required = false) String overriddenstatus) {
if("fourOFour".equals(appName)) {
return new ResponseEntity(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<InstanceInfo>(new InstanceInfo(null, null, null, null, null, null, null, null, null,
null, null, null, null, 0, null, null, null, null, null, null, null, 0l,
0l, null, null);
0l, null, null), HttpStatus.OK);
}
@ResponseStatus(HttpStatus.OK)
......
......@@ -92,6 +92,12 @@ public class RestTemplateEurekaHttpClientTest {
}
@Test
public void testSendHeartBeatFourOFour() {
Assert.assertEquals(HttpStatus.NOT_FOUND.value(), eurekaHttpClient
.sendHeartBeat("fourOFour", "test", info, null).getStatusCode());
}
@Test
public void testStatusUpdate() {
Assert.assertEquals(HttpStatus.OK.value(), eurekaHttpClient
.statusUpdate("test", "test", InstanceStatus.UP, info).getStatusCode());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment