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; ...@@ -19,8 +19,10 @@ package org.springframework.cloud.netflix.eureka.http;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.support.BasicAuthorizationInterceptor; import org.springframework.http.client.support.BasicAuthorizationInterceptor;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.BeanDescription; import com.fasterxml.jackson.databind.BeanDescription;
...@@ -74,6 +76,7 @@ public class RestTemplateTransportClientFactory implements TransportClientFactor ...@@ -74,6 +76,7 @@ public class RestTemplateTransportClientFactory implements TransportClientFactor
} }
restTemplate.getMessageConverters().add(0, mappingJacksonHttpMessageConverter()); restTemplate.getMessageConverters().add(0, mappingJacksonHttpMessageConverter());
restTemplate.setErrorHandler(new ErrorHanlder());
return restTemplate; return restTemplate;
} }
...@@ -134,4 +137,20 @@ public class RestTemplateTransportClientFactory implements TransportClientFactor ...@@ -134,4 +137,20 @@ public class RestTemplateTransportClientFactory implements TransportClientFactor
public void shutdown() { 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; ...@@ -20,6 +20,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
...@@ -82,13 +83,16 @@ public class EurekaServerMockApplication { ...@@ -82,13 +83,16 @@ public class EurekaServerMockApplication {
@ResponseStatus(HttpStatus.OK) @ResponseStatus(HttpStatus.OK)
@PutMapping(value = "/apps/{appName}/{id}", params = { "status", @PutMapping(value = "/apps/{appName}/{id}", params = { "status",
"lastDirtyTimestamp" }) "lastDirtyTimestamp" })
public InstanceInfo sendHeartBeat(@PathVariable String appName, public ResponseEntity sendHeartBeat(@PathVariable String appName,
@PathVariable String id, @RequestParam String status, @PathVariable String id, @RequestParam String status,
@RequestParam String lastDirtyTimestamp, @RequestParam String lastDirtyTimestamp,
@RequestParam(required = false) String overriddenstatus) { @RequestParam(required = false) String overriddenstatus) {
return new InstanceInfo(null, null, null, null, null, null, null, null, null, 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, null, null, null, null, 0, null, null, null, null, null, null, null, 0l,
0l, null, null); 0l, null, null), HttpStatus.OK);
} }
@ResponseStatus(HttpStatus.OK) @ResponseStatus(HttpStatus.OK)
......
...@@ -92,6 +92,12 @@ public class RestTemplateEurekaHttpClientTest { ...@@ -92,6 +92,12 @@ public class RestTemplateEurekaHttpClientTest {
} }
@Test @Test
public void testSendHeartBeatFourOFour() {
Assert.assertEquals(HttpStatus.NOT_FOUND.value(), eurekaHttpClient
.sendHeartBeat("fourOFour", "test", info, null).getStatusCode());
}
@Test
public void testStatusUpdate() { public void testStatusUpdate() {
Assert.assertEquals(HttpStatus.OK.value(), eurekaHttpClient Assert.assertEquals(HttpStatus.OK.value(), eurekaHttpClient
.statusUpdate("test", "test", InstanceStatus.UP, info).getStatusCode()); .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