From 7d06c140fa319f7bbdbc14ae77c4f7b9647a7bb3 Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Mon, 5 Jun 2017 14:36:49 -0400 Subject: [PATCH 1/9] Close response when retry on certain status codes. Fixes #1970. --- .../apache/RetryableRibbonLoadBalancingHttpClient.java | 4 ++++ .../okhttp/RetryableOkHttpLoadBalancingClient.java | 1 + .../apache/RibbonLoadBalancingHttpClientTests.java | 10 +++++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RetryableRibbonLoadBalancingHttpClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RetryableRibbonLoadBalancingHttpClient.java index ebf35907..a46eb011 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RetryableRibbonLoadBalancingHttpClient.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/apache/RetryableRibbonLoadBalancingHttpClient.java @@ -20,6 +20,7 @@ import java.net.URI; import org.apache.commons.lang.BooleanUtils; import org.apache.http.HttpResponse; import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpUriRequest; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext; @@ -91,6 +92,9 @@ public class RetryableRibbonLoadBalancingHttpClient extends RibbonLoadBalancingH HttpUriRequest httpUriRequest = newRequest.toRequest(requestConfig); final HttpResponse httpResponse = RetryableRibbonLoadBalancingHttpClient.this.delegate.execute(httpUriRequest); if(retryPolicy.retryableStatusCode(httpResponse.getStatusLine().getStatusCode())) { + if(CloseableHttpResponse.class.isInstance(httpResponse)) { + ((CloseableHttpResponse)httpResponse).close(); + } throw new RetryableStatusCodeException(RetryableRibbonLoadBalancingHttpClient.this.clientName, httpResponse.getStatusLine().getStatusCode()); } diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/RetryableOkHttpLoadBalancingClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/RetryableOkHttpLoadBalancingClient.java index a61f2a74..170c275a 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/RetryableOkHttpLoadBalancingClient.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/okhttp/RetryableOkHttpLoadBalancingClient.java @@ -96,6 +96,7 @@ public class RetryableOkHttpLoadBalancingClient extends OkHttpLoadBalancingClien final Request request = newRequest.toRequest(); Response response = httpClient.newCall(request).execute(); if(retryPolicy.retryableStatusCode(response.code())) { + response.close(); throw new RetryableStatusCodeException(RetryableOkHttpLoadBalancingClient.this.clientName, response.code()); } return new OkHttpRibbonResponse(response, newRequest.getUri()); diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClientTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClientTests.java index 266b39be..b77318f0 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClientTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/apache/RibbonLoadBalancingHttpClientTests.java @@ -22,6 +22,7 @@ import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.apache.http.client.HttpClient; import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.junit.After; @@ -285,7 +286,7 @@ public class RibbonLoadBalancingHttpClientTests { HttpMethod method = HttpMethod.POST; URI uri = new URI("http://" + host + ":" + port); HttpClient delegate = mock(HttpClient.class); - final HttpResponse response = mock(HttpResponse.class); + final CloseableHttpResponse response = mock(CloseableHttpResponse.class); StatusLine statusLine = mock(StatusLine.class); doReturn(200).when(statusLine).getStatusCode(); doReturn(statusLine).when(response).getStatusLine(); @@ -301,6 +302,7 @@ public class RibbonLoadBalancingHttpClientTests { HttpUriRequest uriRequest = mock(HttpUriRequest.class); doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); RibbonApacheHttpResponse returnedResponse = client.execute(request, null); + verify(response, times(0)).close(); verify(delegate, times(3)).execute(any(HttpUriRequest.class)); verify(lb, times(1)).chooseServer(eq(serviceName)); } @@ -317,7 +319,7 @@ public class RibbonLoadBalancingHttpClientTests { HttpMethod method = HttpMethod.POST; URI uri = new URI("http://" + host + ":" + port); HttpClient delegate = mock(HttpClient.class); - final HttpResponse response = mock(HttpResponse.class); + final CloseableHttpResponse response = mock(CloseableHttpResponse.class); doThrow(new IOException("boom")).doThrow(new IOException("boom again")).doReturn(response). when(delegate).execute(any(HttpUriRequest.class)); ILoadBalancer lb = mock(ILoadBalancer.class); @@ -334,6 +336,7 @@ public class RibbonLoadBalancingHttpClientTests { client.execute(request, null); fail("Expected IOException"); } catch(IOException e) {} finally { + verify(response, times(0)).close(); verify(delegate, times(1)).execute(any(HttpUriRequest.class)); verify(lb, times(0)).chooseServer(eq(serviceName)); } @@ -355,7 +358,7 @@ public class RibbonLoadBalancingHttpClientTests { StatusLine statusLine = mock(StatusLine.class); doReturn(200).when(statusLine).getStatusCode(); doReturn(statusLine).when(response).getStatusLine(); - final HttpResponse fourOFourResponse = mock(HttpResponse.class); + final CloseableHttpResponse fourOFourResponse = mock(CloseableHttpResponse.class); StatusLine fourOFourStatusLine = mock(StatusLine.class); doReturn(404).when(fourOFourStatusLine).getStatusCode(); doReturn(fourOFourStatusLine).when(fourOFourResponse).getStatusLine(); @@ -371,6 +374,7 @@ public class RibbonLoadBalancingHttpClientTests { doReturn(uri).when(uriRequest).getURI(); doReturn(uriRequest).when(request).toRequest(any(RequestConfig.class)); RibbonApacheHttpResponse returnedResponse = client.execute(request, null); + verify(fourOFourResponse, times(1)).close(); verify(delegate, times(2)).execute(any(HttpUriRequest.class)); verify(lb, times(0)).chooseServer(eq(serviceName)); } From 0b2fc81be437b691136fcd279e0ca5010a5731ee Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Tue, 6 Jun 2017 10:44:07 -0400 Subject: [PATCH 2/9] Closing response in Feign load balancer --- .../cloud/netflix/feign/ribbon/RetryableFeignLoadBalancer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/RetryableFeignLoadBalancer.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/RetryableFeignLoadBalancer.java index 024dd978..d82578ee 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/RetryableFeignLoadBalancer.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/ribbon/RetryableFeignLoadBalancer.java @@ -91,6 +91,7 @@ public class RetryableFeignLoadBalancer extends FeignLoadBalancer implements Ser } Response response = request.client().execute(feignRequest, options); if(retryPolicy.retryableStatusCode(response.status())) { + response.close(); throw new RetryableStatusCodeException(RetryableFeignLoadBalancer.this.getClientName(), response.status()); } return new RibbonResponse(request.getUri(), response); From f5524263046b19b3dd1cab7ca5d0befb66150dac Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Thu, 8 Jun 2017 15:16:03 -0400 Subject: [PATCH 3/9] Trying a plain RestTemplate in an attempt to fix intermittent test failures. --- .../zuul/RetryableZuulProxyApplicationTests.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java index ff1bdc8f..538a402b 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java @@ -10,7 +10,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.context.embedded.LocalServerPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.cloud.netflix.ribbon.StaticServerList; import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; @@ -30,6 +30,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; import com.netflix.loadbalancer.Server; import com.netflix.loadbalancer.ServerList; @@ -47,8 +48,7 @@ import com.netflix.zuul.context.RequestContext; @DirtiesContext public class RetryableZuulProxyApplicationTests { - @Autowired - private TestRestTemplate testRestTemplate; + private RestTemplate testRestTemplate; @Autowired @SuppressWarnings("unused") @@ -58,10 +58,14 @@ public class RetryableZuulProxyApplicationTests { @SuppressWarnings("unused") private RoutesEndpoint endpoint; + @LocalServerPort + private int port; + @Before public void setTestRequestContext() { RequestContext context = new RequestContext(); RequestContext.testSetCurrentContext(context); + testRestTemplate = new RestTemplateBuilder().build(); } @Test @@ -71,7 +75,7 @@ public class RetryableZuulProxyApplicationTests { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); ResponseEntity result = testRestTemplate.exchange( - "/simple", HttpMethod.POST, + "http://localhost:" + port + "/simple", HttpMethod.POST, new HttpEntity<>(form, headers), String.class); assertEquals(HttpStatus.OK, result.getStatusCode()); assertEquals("Posted! {foo=[bar]}", result.getBody()); From 4e25e2eb81919891cd810b9fa1c800f7c4cbe609 Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Thu, 8 Jun 2017 15:34:57 -0400 Subject: [PATCH 4/9] Revert "Trying a plain RestTemplate in an attempt to fix intermittent test failures." This reverts commit f5524263046b19b3dd1cab7ca5d0befb66150dac. --- .../zuul/RetryableZuulProxyApplicationTests.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java index 538a402b..ff1bdc8f 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java @@ -10,7 +10,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.context.embedded.LocalServerPort; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.cloud.netflix.ribbon.StaticServerList; import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; @@ -30,7 +30,6 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.client.RestTemplate; import com.netflix.loadbalancer.Server; import com.netflix.loadbalancer.ServerList; @@ -48,7 +47,8 @@ import com.netflix.zuul.context.RequestContext; @DirtiesContext public class RetryableZuulProxyApplicationTests { - private RestTemplate testRestTemplate; + @Autowired + private TestRestTemplate testRestTemplate; @Autowired @SuppressWarnings("unused") @@ -58,14 +58,10 @@ public class RetryableZuulProxyApplicationTests { @SuppressWarnings("unused") private RoutesEndpoint endpoint; - @LocalServerPort - private int port; - @Before public void setTestRequestContext() { RequestContext context = new RequestContext(); RequestContext.testSetCurrentContext(context); - testRestTemplate = new RestTemplateBuilder().build(); } @Test @@ -75,7 +71,7 @@ public class RetryableZuulProxyApplicationTests { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); ResponseEntity result = testRestTemplate.exchange( - "http://localhost:" + port + "/simple", HttpMethod.POST, + "/simple", HttpMethod.POST, new HttpEntity<>(form, headers), String.class); assertEquals(HttpStatus.OK, result.getStatusCode()); assertEquals("Posted! {foo=[bar]}", result.getBody()); From 8281757da8a9da4f8d572aaef2e5c02868af008e Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Thu, 8 Jun 2017 15:43:15 -0400 Subject: [PATCH 5/9] Add path to try and fix intermittent failures with RetryableZuulApplicationTests pass --- .../netflix/zuul/RetryableZuulProxyApplicationTests.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java index ff1bdc8f..9bda5ba5 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java @@ -71,7 +71,7 @@ public class RetryableZuulProxyApplicationTests { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); ResponseEntity result = testRestTemplate.exchange( - "/simple", HttpMethod.POST, + "/simple/poster", HttpMethod.POST, new HttpEntity<>(form, headers), String.class); assertEquals(HttpStatus.OK, result.getStatusCode()); assertEquals("Posted! {foo=[bar]}", result.getBody()); @@ -87,7 +87,7 @@ public class RetryableZuulProxyApplicationTests { @RibbonClient(name = "simple", configuration = RetryableRibbonClientConfiguration.class) class RetryableZuulProxyApplication { - @RequestMapping(value = "/", method = RequestMethod.POST) + @RequestMapping(value = "/poster", method = RequestMethod.POST) public String delete(@RequestBody MultiValueMap form) { return "Posted! " + form; } From 484bde10b3a67977f970b26a384bab3fb2b27dff Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Thu, 8 Jun 2017 16:18:11 -0400 Subject: [PATCH 6/9] Adding 404 to list of retryable status codes --- .../cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java index 9bda5ba5..9ac0d365 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/RetryableZuulProxyApplicationTests.java @@ -43,7 +43,8 @@ import com.netflix.zuul.context.RequestContext; value = { "zuul.routes.simple.path: /simple/**", "zuul.routes.simple.retryable: true", - "ribbon.OkToRetryOnAllOperations: true"}) + "ribbon.OkToRetryOnAllOperations: true", + "simple.ribbon.retryableStatusCodes: 404"}) @DirtiesContext public class RetryableZuulProxyApplicationTests { From 9f10d5207fd39e130875d788f5ddecf50680e66f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20D=C3=B6rnbrack?= Date: Fri, 9 Jun 2017 10:12:24 +0200 Subject: [PATCH 7/9] fixes a problem with whitespaces in list of retryable status codes --- .../ribbon/RibbonLoadBalancedRetryPolicy.java | 14 +++++++------- .../RibbonLoadBalancedRetryPolicyFactoryTest.java | 5 +++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicy.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicy.java index 4e062ae5..874215f8 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicy.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicy.java @@ -18,17 +18,17 @@ package org.springframework.cloud.netflix.ribbon; -import java.util.ArrayList; -import java.util.List; +import com.netflix.client.config.CommonClientConfigKey; +import com.netflix.client.config.IClientConfig; +import com.netflix.client.config.IClientConfigKey; import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext; import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.core.env.Environment; import org.springframework.http.HttpMethod; import org.springframework.util.StringUtils; -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.IClientConfig; -import com.netflix.client.config.IClientConfigKey; + +import java.util.ArrayList; +import java.util.List; /** * {@link LoadBalancedRetryPolicy} for Ribbon clients. @@ -60,7 +60,7 @@ public class RibbonLoadBalancedRetryPolicy implements LoadBalancedRetryPolicy { for(String code : retryableStatusCodesArray) { if(!StringUtils.isEmpty(code)) { try { - retryableStatusCodes.add(Integer.valueOf(code)); + retryableStatusCodes.add(Integer.valueOf(code.trim())); } catch (NumberFormatException e) { //TODO log } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicyFactoryTest.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicyFactoryTest.java index 3fedccea..595de862 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicyFactoryTest.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicyFactoryTest.java @@ -201,7 +201,7 @@ public class RibbonLoadBalancedRetryPolicyFactoryTest { } @Test - public void testRetryableStatusCodest() throws Exception { + public void testRetryableStatusCodes() throws Exception { int sameServer = 3; int nextServer = 3; RibbonServer server = getRibbonServer(); @@ -210,7 +210,7 @@ public class RibbonLoadBalancedRetryPolicyFactoryTest { doReturn(nextServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); doReturn(false).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false)); doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId())); - doReturn("404,502,foo, ,").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq("")); + doReturn("404,502, 418,foo, ,").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq("")); clientFactory.getLoadBalancerContext(server.getServiceId()).setRetryHandler(new DefaultLoadBalancerRetryHandler(config)); RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); RibbonLoadBalancedRetryPolicyFactory factory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory); @@ -220,6 +220,7 @@ public class RibbonLoadBalancedRetryPolicyFactoryTest { assertThat(policy.retryableStatusCode(400), is(false)); assertThat(policy.retryableStatusCode(404), is(true)); assertThat(policy.retryableStatusCode(502), is(true)); + assertThat(policy.retryableStatusCode(418), is(true)); } protected RibbonLoadBalancerClient getRibbonLoadBalancerClient( From 4f148de74d7b91f2916c0897ab883717939c8565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20D=C3=B6rnbrack?= Date: Fri, 9 Jun 2017 10:12:24 +0200 Subject: [PATCH 8/9] code cleanup --- .../ribbon/RibbonLoadBalancedRetryPolicy.java | 14 +++++++------- .../RibbonLoadBalancedRetryPolicyFactoryTest.java | 5 +++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicy.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicy.java index 4e062ae5..874215f8 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicy.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicy.java @@ -18,17 +18,17 @@ package org.springframework.cloud.netflix.ribbon; -import java.util.ArrayList; -import java.util.List; +import com.netflix.client.config.CommonClientConfigKey; +import com.netflix.client.config.IClientConfig; +import com.netflix.client.config.IClientConfigKey; import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext; import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser; -import org.springframework.core.env.Environment; import org.springframework.http.HttpMethod; import org.springframework.util.StringUtils; -import com.netflix.client.config.CommonClientConfigKey; -import com.netflix.client.config.IClientConfig; -import com.netflix.client.config.IClientConfigKey; + +import java.util.ArrayList; +import java.util.List; /** * {@link LoadBalancedRetryPolicy} for Ribbon clients. @@ -60,7 +60,7 @@ public class RibbonLoadBalancedRetryPolicy implements LoadBalancedRetryPolicy { for(String code : retryableStatusCodesArray) { if(!StringUtils.isEmpty(code)) { try { - retryableStatusCodes.add(Integer.valueOf(code)); + retryableStatusCodes.add(Integer.valueOf(code.trim())); } catch (NumberFormatException e) { //TODO log } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicyFactoryTest.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicyFactoryTest.java index 3fedccea..90c5739c 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicyFactoryTest.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonLoadBalancedRetryPolicyFactoryTest.java @@ -201,7 +201,7 @@ public class RibbonLoadBalancedRetryPolicyFactoryTest { } @Test - public void testRetryableStatusCodest() throws Exception { + public void testRetryableStatusCodes() throws Exception { int sameServer = 3; int nextServer = 3; RibbonServer server = getRibbonServer(); @@ -210,7 +210,7 @@ public class RibbonLoadBalancedRetryPolicyFactoryTest { doReturn(nextServer).when(config).get(eq(CommonClientConfigKey.MaxAutoRetriesNextServer), anyInt()); doReturn(false).when(config).get(eq(CommonClientConfigKey.OkToRetryOnAllOperations), eq(false)); doReturn(config).when(clientFactory).getClientConfig(eq(server.getServiceId())); - doReturn("404,502,foo, ,").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq("")); + doReturn("404, 418,502,foo, ,").when(config).getPropertyAsString(eq(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES),eq("")); clientFactory.getLoadBalancerContext(server.getServiceId()).setRetryHandler(new DefaultLoadBalancerRetryHandler(config)); RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); RibbonLoadBalancedRetryPolicyFactory factory = new RibbonLoadBalancedRetryPolicyFactory(clientFactory); @@ -219,6 +219,7 @@ public class RibbonLoadBalancedRetryPolicyFactoryTest { doReturn(HttpMethod.GET).when(request).getMethod(); assertThat(policy.retryableStatusCode(400), is(false)); assertThat(policy.retryableStatusCode(404), is(true)); + assertThat(policy.retryableStatusCode(418), is(true)); assertThat(policy.retryableStatusCode(502), is(true)); } From a59f5e1c4fc527e8394e9195fd955b57a2ff8a17 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 9 Jun 2017 13:09:02 +0100 Subject: [PATCH 9/9] Clean up some resources to keep tests running --- .../archaius/ArchaiusAutoConfiguration.java | 25 +++--- .../cloud/netflix/AdhocTestSuite.java | 12 ++- .../encoding/FeignAcceptEncodingTests.java | 19 +++-- .../netflix/ribbon/RibbonDisabledTests.java | 7 +- .../zuul/ZuulProxyAutoConfigurationTests.java | 64 +++++++++++++++ .../RibbonRetryIntegrationTestBase.java | 57 ++++++++------ .../route/support/ZuulProxyTestBase.java | 77 +++++++++++-------- 7 files changed, 178 insertions(+), 83 deletions(-) create mode 100644 spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfigurationTests.java diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java index 32e464b7..64ae8614 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/archaius/ArchaiusAutoConfiguration.java @@ -23,12 +23,21 @@ import java.util.concurrent.atomic.AtomicBoolean; import javax.annotation.PreDestroy; +import com.netflix.config.AggregatedConfiguration; +import com.netflix.config.ConcurrentCompositeConfiguration; +import com.netflix.config.ConfigurationManager; +import com.netflix.config.DeploymentContext; +import com.netflix.config.DynamicProperty; +import com.netflix.config.DynamicPropertyFactory; +import com.netflix.config.DynamicURLConfiguration; + import org.apache.commons.configuration.AbstractConfiguration; import org.apache.commons.configuration.ConfigurationBuilder; import org.apache.commons.configuration.EnvironmentConfiguration; import org.apache.commons.configuration.SystemConfiguration; import org.apache.commons.configuration.event.ConfigurationEvent; import org.apache.commons.configuration.event.ConfigurationListener; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint; import org.springframework.boot.actuate.endpoint.Endpoint; @@ -44,14 +53,6 @@ import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; import org.springframework.util.ReflectionUtils; -import com.netflix.config.AggregatedConfiguration; -import com.netflix.config.ConcurrentCompositeConfiguration; -import com.netflix.config.ConfigurationManager; -import com.netflix.config.DeploymentContext; -import com.netflix.config.DynamicProperty; -import com.netflix.config.DynamicPropertyFactory; -import com.netflix.config.DynamicURLConfiguration; - import static com.netflix.config.ConfigurationManager.APPLICATION_PROPERTIES; import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_ENV_CONFIG; import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_SYS_CONFIG; @@ -79,8 +80,13 @@ public class ArchaiusAutoConfiguration { @Autowired(required = false) private List externalConfigurations = new ArrayList<>(); + private DynamicURLConfiguration defaultURLConfig; + @PreDestroy public void close() { + if (defaultURLConfig != null) { + defaultURLConfig.stopLoading(); + } setStatic(ConfigurationManager.class, "instance", null); setStatic(ConfigurationManager.class, "customConfigurationInstalled", false); setStatic(DynamicPropertyFactory.class, "config", null); @@ -154,8 +160,7 @@ public class ArchaiusAutoConfiguration { config.addConfiguration(envConfig, ConfigurableEnvironmentConfiguration.class.getSimpleName()); - // below come from ConfigurationManager.createDefaultConfigInstance() - DynamicURLConfiguration defaultURLConfig = new DynamicURLConfiguration(); + defaultURLConfig = new DynamicURLConfiguration(); try { config.addConfiguration(defaultURLConfig, URL_CONFIG_NAME); } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/AdhocTestSuite.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/AdhocTestSuite.java index 47a365ed..eb36fe30 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/AdhocTestSuite.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/AdhocTestSuite.java @@ -20,11 +20,9 @@ import org.junit.Ignore; import org.junit.runner.RunWith; import org.junit.runners.Suite; import org.junit.runners.Suite.SuiteClasses; -import org.springframework.cloud.netflix.feign.encoding.FeignAcceptEncodingTests; -import org.springframework.cloud.netflix.metrics.servo.ServoMetricReaderTests; -import org.springframework.cloud.netflix.ribbon.RibbonInterceptorTests; -import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClientTests; -import org.springframework.cloud.netflix.zuul.ZuulProxyConfigurationTests; + +import org.springframework.cloud.netflix.zuul.FormZuulServletProxyApplicationTests; +import org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfigurationTests; /** * A test suite for probing weird ordering problems in the tests. @@ -32,8 +30,8 @@ import org.springframework.cloud.netflix.zuul.ZuulProxyConfigurationTests; * @author Dave Syer */ @RunWith(Suite.class) -@SuiteClasses({ RibbonLoadBalancerClientTests.class, RibbonInterceptorTests.class, FeignAcceptEncodingTests.class, - ServoMetricReaderTests.class, ZuulProxyConfigurationTests.class }) +@SuiteClasses({ ZuulProxyAutoConfigurationTests.class, + FormZuulServletProxyApplicationTests.class }) @Ignore public class AdhocTestSuite { diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/FeignAcceptEncodingTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/FeignAcceptEncodingTests.java index a0620fc8..bd7f9956 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/FeignAcceptEncodingTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/encoding/FeignAcceptEncodingTests.java @@ -16,14 +16,16 @@ package org.springframework.cloud.netflix.feign.encoding; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - import java.util.Collections; import java.util.List; +import com.netflix.loadbalancer.BaseLoadBalancer; +import com.netflix.loadbalancer.ILoadBalancer; +import com.netflix.loadbalancer.Server; + import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -37,11 +39,11 @@ 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.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; -import com.netflix.loadbalancer.BaseLoadBalancer; -import com.netflix.loadbalancer.ILoadBalancer; -import com.netflix.loadbalancer.Server; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; /** * Tests the response compression. @@ -50,7 +52,8 @@ import com.netflix.loadbalancer.Server; */ @SpringBootTest(classes = FeignAcceptEncodingTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = { "feign.compression.response.enabled=true" }) -@RunWith(SpringJUnit4ClassRunner.class) +@RunWith(SpringRunner.class) +@DirtiesContext public class FeignAcceptEncodingTests { @Autowired diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonDisabledTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonDisabledTests.java index 5da53b4c..1c3bccd5 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonDisabledTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonDisabledTests.java @@ -20,6 +20,7 @@ package org.springframework.cloud.netflix.ribbon; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.ClassPathExclusions; import org.springframework.cloud.FilteredClassPathRunner; @@ -28,12 +29,12 @@ import org.springframework.cloud.FilteredClassPathRunner; * @author Ryan Baxter */ @RunWith(FilteredClassPathRunner.class) -@ClassPathExclusions({"ribbon-{version:\\d.*}.jar"}) +@ClassPathExclusions({ "ribbon-{version:\\d.*}.jar" }) public class RibbonDisabledTests { @Test(expected = ArrayStoreException.class) public void testRibbonDisabled() { - new SpringApplicationBuilder().web(false) - .sources(RibbonAutoConfiguration.class).run(); + new SpringApplicationBuilder().web(false).sources(RibbonAutoConfiguration.class) + .run().close(); } } \ No newline at end of file diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfigurationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfigurationTests.java new file mode 100644 index 00000000..c374d823 --- /dev/null +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/ZuulProxyAutoConfigurationTests.java @@ -0,0 +1,64 @@ +/* + * Copyright 2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.springframework.cloud.netflix.zuul; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.cloud.netflix.zuul.filters.CompositeRouteLocator; +import org.springframework.cloud.netflix.zuul.filters.RouteLocator; +import org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * To test the auto-configuration of Zuul Proxy + * + * @author Biju Kunjummen + * + */ + +@RunWith(SpringRunner.class) +@SpringBootTest +@DirtiesContext +public class ZuulProxyAutoConfigurationTests { + + @Autowired + private RouteLocator routeLocator; + + @Autowired(required = false) + private RibbonRoutingFilter ribbonRoutingFilter; + + @Test + public void testAutoConfiguredBeans() { + assertThat(routeLocator).isInstanceOf(CompositeRouteLocator.class); + assertThat(this.ribbonRoutingFilter).isNotNull(); + } + + @Configuration + @EnableAutoConfiguration + @EnableZuulProxy + static class TestConfig { + } +} diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonRetryIntegrationTestBase.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonRetryIntegrationTestBase.java index c43b6307..a0d1eea6 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonRetryIntegrationTestBase.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/RibbonRetryIntegrationTestBase.java @@ -18,10 +18,15 @@ package org.springframework.cloud.netflix.zuul.filters.route.support; +import com.netflix.loadbalancer.Server; +import com.netflix.loadbalancer.ServerList; +import com.netflix.zuul.context.RequestContext; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.Before; import org.junit.Test; + import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.web.client.TestRestTemplate; @@ -47,10 +52,6 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.context.RequestContext; - import static org.junit.Assert.assertEquals; /** @@ -67,12 +68,10 @@ public abstract class RibbonRetryIntegrationTestBase { public void setup() { RequestContext.getCurrentContext().clear(); String uri = "/resetError"; - new TestRestTemplate().exchange( - "http://localhost:" + this.port + uri, HttpMethod.GET, - new HttpEntity<>((Void) null), String.class); + new TestRestTemplate().exchange("http://localhost:" + this.port + uri, + HttpMethod.GET, new HttpEntity<>((Void) null), String.class); } - @Test public void retryable() { String uri = "/retryable/everyothererror"; @@ -147,9 +146,11 @@ public abstract class RibbonRetryIntegrationTestBase { @RibbonClient(name = "retryable", configuration = RibbonClientConfiguration.class), @RibbonClient(name = "disableretry", configuration = RibbonClientConfiguration.class), @RibbonClient(name = "globalretrydisabled", configuration = RibbonClientConfiguration.class), - @RibbonClient(name = "getretryable", configuration = RibbonClientConfiguration.class)}) + @RibbonClient(name = "getretryable", configuration = RibbonClientConfiguration.class) }) public static class RetryableTestConfig { + private final Log LOG = LogFactory.getLog(RetryableTestConfig.class); + private boolean error = true; @RequestMapping("/resetError") @@ -162,13 +163,14 @@ public abstract class RibbonRetryIntegrationTestBase { boolean shouldError = error; error = !error; try { - if(shouldError) { + if (shouldError) { Thread.sleep(80000); } - } catch (InterruptedException e) { - e.printStackTrace(); } - + catch (InterruptedException e) { + LOG.info(e); + Thread.currentThread().interrupt(); + } return new ResponseEntity("no error", HttpStatus.OK); } @@ -183,9 +185,9 @@ public abstract class RibbonRetryIntegrationTestBase { public ResponseEntity fourOFourError() { boolean shouldError = error; error = !error; - if(shouldError) { - return new ResponseEntity("not found", HttpStatus.NOT_FOUND); - } + if (shouldError) { + return new ResponseEntity("not found", HttpStatus.NOT_FOUND); + } return new ResponseEntity("no error", HttpStatus.OK); } @@ -204,14 +206,17 @@ public abstract class RibbonRetryIntegrationTestBase { } @Configuration - public static class FourOFourRetryableRibbonConfiguration extends RibbonClientConfiguration { + public static class FourOFourRetryableRibbonConfiguration + extends RibbonClientConfiguration { @Bean - public LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory(SpringClientFactory factory) { + public LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory( + SpringClientFactory factory) { return new MyRibbonRetryPolicyFactory(factory); } - public static class MyRibbonRetryPolicyFactory extends RibbonLoadBalancedRetryPolicyFactory { + public static class MyRibbonRetryPolicyFactory + extends RibbonLoadBalancedRetryPolicyFactory { private SpringClientFactory factory; @@ -221,21 +226,25 @@ public abstract class RibbonRetryIntegrationTestBase { } @Override - public LoadBalancedRetryPolicy create(String serviceId, ServiceInstanceChooser loadBalanceChooser) { + public LoadBalancedRetryPolicy create(String serviceId, + ServiceInstanceChooser loadBalanceChooser) { RibbonLoadBalancerContext lbContext = this.factory .getLoadBalancerContext(serviceId); - return new MyLoadBalancedRetryPolicy(serviceId, lbContext, loadBalanceChooser); + return new MyLoadBalancedRetryPolicy(serviceId, lbContext, + loadBalanceChooser); } class MyLoadBalancedRetryPolicy extends RibbonLoadBalancedRetryPolicy { - public MyLoadBalancedRetryPolicy(String serviceId, RibbonLoadBalancerContext context, ServiceInstanceChooser loadBalanceChooser) { + public MyLoadBalancedRetryPolicy(String serviceId, + RibbonLoadBalancerContext context, + ServiceInstanceChooser loadBalanceChooser) { super(serviceId, context, loadBalanceChooser); } @Override - public boolean retryableStatusCode( int statusCode) { - if(statusCode == HttpStatus.NOT_FOUND.value()) { + public boolean retryableStatusCode(int statusCode) { + if (statusCode == HttpStatus.NOT_FOUND.value()) { return true; } return super.retryableStatusCode(statusCode); diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/ZuulProxyTestBase.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/ZuulProxyTestBase.java index c1912697..41fbabf3 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/ZuulProxyTestBase.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/support/ZuulProxyTestBase.java @@ -27,9 +27,19 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; + import javax.servlet.http.HttpServletRequest; + +import com.netflix.loadbalancer.Server; +import com.netflix.loadbalancer.ServerList; +import com.netflix.zuul.ZuulFilter; +import com.netflix.zuul.context.RequestContext; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.junit.Before; import org.junit.Test; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.web.BasicErrorController; @@ -43,6 +53,7 @@ import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; import org.springframework.cloud.netflix.zuul.filters.discovery.DiscoveryClientRouteLocator; import org.springframework.cloud.netflix.zuul.filters.route.RibbonCommandFactory; import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; +import org.springframework.cloud.netflix.zuul.filters.route.support.RibbonRetryIntegrationTestBase.RetryableTestConfig; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpEntity; @@ -65,10 +76,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; @@ -214,12 +221,13 @@ public abstract class ZuulProxyTestBase { public void ribbonDeleteWithBody() { this.endpoint.reset(); ResponseEntity result = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/simple/deletewithbody", HttpMethod.DELETE, - new HttpEntity<>("deleterequestbody"), String.class); + "http://localhost:" + this.port + "/simple/deletewithbody", + HttpMethod.DELETE, new HttpEntity<>("deleterequestbody"), String.class); assertEquals(HttpStatus.OK, result.getStatusCode()); if (supportsDeleteWithBody()) { assertEquals("Deleted deleterequestbody", result.getBody()); - } else { + } + else { assertEquals("Deleted null", result.getBody()); } } @@ -286,16 +294,16 @@ public abstract class ZuulProxyTestBase { assertEquals(HttpStatus.OK, result.getStatusCode()); assertEquals("Patched 1!", result.getBody()); } - + @SuppressWarnings("deprecation") @Test public void javascriptEncodedFormParams() { TestRestTemplate testRestTemplate = new TestRestTemplate(); ArrayList> converters = new ArrayList<>(); - converters.addAll(Arrays.asList(new StringHttpMessageConverter(), + converters.addAll(Arrays.asList(new StringHttpMessageConverter(), new NoEncodingFormHttpMessageConverter())); testRestTemplate.getRestTemplate().setMessageConverters(converters); - + MultiValueMap map = new LinkedMultiValueMap<>(); map.add("foo", "(bar)"); ResponseEntity result = testRestTemplate.postForEntity( @@ -307,9 +315,11 @@ public abstract class ZuulProxyTestBase { public static abstract class AbstractZuulProxyApplication extends DelegatingWebMvcConfiguration { + private final Log LOG = LogFactory.getLog(RetryableTestConfig.class); + @RequestMapping(value = "/local/{id}", method = RequestMethod.PATCH) public String patch(@PathVariable final String id, - @RequestBody final String body) { + @RequestBody final String body) { return "Patched " + id + "!"; } @@ -322,11 +332,12 @@ public abstract class ZuulProxyTestBase { public String local() { return "Hello local"; } - + @RequestMapping(value = "/local", method = RequestMethod.POST) - public String postWithFormParam(HttpServletRequest request, + public String postWithFormParam(HttpServletRequest request, @RequestBody MultiValueMap body) { - return "Posted " + body.get("foo") + " and Content-Length was: " + request.getContentLength() + "!"; + return "Posted " + body.get("foo") + " and Content-Length was: " + + request.getContentLength() + "!"; } @RequestMapping(value = "/deletewithbody", method = RequestMethod.DELETE) @@ -371,8 +382,10 @@ public abstract class ZuulProxyTestBase { public String slow() { try { Thread.sleep(80000); - } catch (InterruptedException e) { - e.printStackTrace(); + } + catch (InterruptedException e) { + LOG.info(e); + Thread.currentThread().interrupt(); } return "slow"; } @@ -422,7 +435,6 @@ public abstract class ZuulProxyTestBase { return mapping; } - } public static class FallbackProvider implements ZuulFallbackProvider { @@ -469,14 +481,16 @@ public abstract class ZuulProxyTestBase { }; } } - + @Configuration - public class FormEncodedMessageConverterConfiguration extends WebMvcConfigurerAdapter { + public class FormEncodedMessageConverterConfiguration + extends WebMvcConfigurerAdapter { @Override public void configureMessageConverters(List> converters) { FormHttpMessageConverter converter = new FormHttpMessageConverter(); - MediaType mediaType = new MediaType("application", "x-www-form-urlencoded", Charset.forName("UTF-8")); + MediaType mediaType = new MediaType("application", "x-www-form-urlencoded", + Charset.forName("UTF-8")); converter.setSupportedMediaTypes(Arrays.asList(mediaType)); converters.add(converter); super.configureMessageConverters(converters); @@ -492,8 +506,8 @@ public abstract class ZuulProxyTestBase { @Bean public ServerList ribbonServerList() { - return new StaticServerList<>(new Server("localhost", this.port)); - } + return new StaticServerList<>(new Server("localhost", this.port)); + } } @@ -516,12 +530,13 @@ public abstract class ZuulProxyTestBase { AtomicBoolean controllerUsed = new AtomicBoolean(); public MyErrorController(ErrorAttributes errorAttributes) { - super(errorAttributes, new ErrorProperties()); - } + super(errorAttributes, new ErrorProperties()); + } @Override public ResponseEntity> error(HttpServletRequest request) { - String errorUri = (String) request.getAttribute("javax.servlet.error.request_uri"); + String errorUri = (String) request + .getAttribute("javax.servlet.error.request_uri"); if (errorUri != null && errorUri.equals(this.uriToMatch.get())) { controllerUsed.set(true); @@ -531,15 +546,15 @@ public abstract class ZuulProxyTestBase { } public void setUriToMatch(String uri) { - this.uriToMatch.set(uri); - } + this.uriToMatch.set(uri); + } public boolean wasControllerUsed() { - return this.controllerUsed.get(); - } + return this.controllerUsed.get(); + } public void clear() { - this.controllerUsed.set(false); - } + this.controllerUsed.set(false); + } } }