From 5acf4e1a2e63a9ada77a2e2df214f438369ca50d Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Mon, 25 Apr 2016 13:47:51 -0600 Subject: [PATCH] Throw IOException in RibbonLoadBalancerClient.execute Fixes proper RestTemplate behavior. fixes gh-986 --- .../ribbon/RibbonLoadBalancerClient.java | 8 +++++- .../ribbon/RibbonLoadBalancerClientTests.java | 27 ++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java index 128a363f..78bc9e8c 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClient.java @@ -16,6 +16,7 @@ package org.springframework.cloud.netflix.ribbon; +import java.io.IOException; import java.net.URI; import java.util.Collections; import java.util.Map; @@ -71,7 +72,7 @@ public class RibbonLoadBalancerClient implements LoadBalancerClient { } @Override - public T execute(String serviceId, LoadBalancerRequest request) { + public T execute(String serviceId, LoadBalancerRequest request) throws IOException { ILoadBalancer loadBalancer = getLoadBalancer(serviceId); Server server = getServer(loadBalancer); if (server == null) { @@ -89,6 +90,11 @@ public class RibbonLoadBalancerClient implements LoadBalancerClient { statsRecorder.recordStats(returnVal); return returnVal; } + // catch IOException and rethrow so RestTemplate behaves correctly + catch (IOException ex) { + statsRecorder.recordStats(ex); + throw ex; + } catch (Exception ex) { statsRecorder.recordStats(ex); ReflectionUtils.rethrowRuntimeException(ex); diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClientTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClientTests.java index 22d22835..38173080 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClientTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancerClientTests.java @@ -16,6 +16,7 @@ package org.springframework.cloud.netflix.ribbon; +import java.io.IOException; import java.net.URI; import java.net.URL; import java.util.Collections; @@ -38,9 +39,12 @@ import com.netflix.loadbalancer.ServerStats; import lombok.SneakyThrows; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import static org.mockito.BDDMockito.given; import static org.mockito.Matchers.anyDouble; @@ -139,7 +143,7 @@ public class RibbonLoadBalancerClientTests { } @Test - public void testExecute() { + public void testExecute() throws IOException { final RibbonServer server = getRibbonServer(); RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); final String returnVal = "myval"; @@ -176,6 +180,27 @@ public class RibbonLoadBalancerClientTests { verifyServerStats(); } + @Test + public void testExecuteIOException() { + final RibbonServer ribbonServer = getRibbonServer(); + RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(ribbonServer); + try { + client.execute(ribbonServer.getServiceId(), + new LoadBalancerRequest() { + @Override + public Object apply(ServiceInstance instance) throws Exception { + assertServiceInstance(ribbonServer, instance); + throw new IOException(); + } + }); + fail("Should have thrown exception"); + } + catch (Exception ex) { + assertThat("wrong exception type", ex, is(instanceOf(IOException.class))); + } + verifyServerStats(); + } + protected RibbonServer getRibbonServer() { return new RibbonServer("testService", new Server("myhost", 9080), false, Collections.singletonMap("mykey", "myvalue"));