Adds connectionRequestTimeoutMillis to zuul.host

fixes gh-2851
parent 0a8f594b
......@@ -18,6 +18,7 @@ package org.springframework.cloud.netflix.zuul.filters;
import com.netflix.hystrix.HystrixCommandProperties.ExecutionIsolationStrategy;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
......@@ -439,6 +440,11 @@ public class ZuulProperties {
*/
private int connectTimeoutMillis = 2000;
/**
* The timeout in milliseconds used when requesting a connection
* from the connection manager. Defaults to -1, undefined use the system default.
*/
private int connectionRequestTimeoutMillis = -1;
/**
* The lifetime for the connection pool.
*/
private long timeToLive = -1;
......@@ -493,6 +499,14 @@ public class ZuulProperties {
this.connectTimeoutMillis = connectTimeoutMillis;
}
public int getConnectionRequestTimeoutMillis() {
return connectionRequestTimeoutMillis;
}
public void setConnectionRequestTimeoutMillis(int connectionRequestTimeoutMillis) {
this.connectionRequestTimeoutMillis = connectionRequestTimeoutMillis;
}
public long getTimeToLive() {
return timeToLive;
}
......@@ -518,26 +532,28 @@ public class ZuulProperties {
maxPerRouteConnections == host.maxPerRouteConnections &&
socketTimeoutMillis == host.socketTimeoutMillis &&
connectTimeoutMillis == host.connectTimeoutMillis &&
connectionRequestTimeoutMillis == host.connectionRequestTimeoutMillis &&
timeToLive == host.timeToLive &&
timeUnit == host.timeUnit;
}
@Override
public int hashCode() {
return Objects.hash(maxTotalConnections, maxPerRouteConnections, socketTimeoutMillis, connectTimeoutMillis, timeToLive, timeUnit);
return Objects.hash(maxTotalConnections, maxPerRouteConnections, socketTimeoutMillis, connectTimeoutMillis,
connectionRequestTimeoutMillis, timeToLive, timeUnit);
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Host{");
sb.append("maxTotalConnections=").append(maxTotalConnections);
sb.append(", maxPerRouteConnections=").append(maxPerRouteConnections);
sb.append(", socketTimeoutMillis=").append(socketTimeoutMillis);
sb.append(", connectTimeoutMillis=").append(connectTimeoutMillis);
sb.append(", timeToLive=").append(timeToLive);
sb.append(", timeUnit=").append(timeUnit);
sb.append('}');
return sb.toString();
return new ToStringCreator(this)
.append("maxTotalConnections", maxTotalConnections)
.append("maxPerRouteConnections", maxPerRouteConnections)
.append("socketTimeoutMillis", socketTimeoutMillis)
.append("connectTimeoutMillis", connectTimeoutMillis)
.append("connectionRequestTimeoutMillis", connectionRequestTimeoutMillis)
.append("timeToLive", timeToLive)
.append("timeUnit", timeUnit)
.toString();
}
}
......
......@@ -217,6 +217,7 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
protected CloseableHttpClient newClient() {
final RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(this.hostProperties.getConnectionRequestTimeoutMillis())
.setSocketTimeout(this.hostProperties.getSocketTimeoutMillis())
.setConnectTimeout(this.hostProperties.getConnectTimeoutMillis())
.setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();
......
......@@ -92,7 +92,7 @@ import static org.springframework.util.StreamUtils.copyToString;
* @author Gang Li
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SampleApplication.class,
@SpringBootTest(classes = SimpleHostRoutingFilterTests.SampleApplication.class,
webEnvironment = RANDOM_PORT,
properties = {"server.servlet.contextPath: /app"})
@DirtiesContext
......@@ -119,13 +119,14 @@ public class SimpleHostRoutingFilterTests {
@Test
public void timeoutPropertiesAreApplied() {
addEnvironment(this.context, "zuul.host.socket-timeout-millis=11000",
"zuul.host.connect-timeout-millis=2100");
"zuul.host.connect-timeout-millis=2100", "zuul.host.connection-request-timeout-millis=2500");
setupContext();
CloseableHttpClient httpClient = getFilter().newClient();
Assertions.assertThat(httpClient).isInstanceOf(Configurable.class);
RequestConfig config = ((Configurable) httpClient).getConfig();
assertEquals(11000, config.getSocketTimeout());
assertEquals(2100, config.getConnectTimeout());
assertEquals(2500, config.getConnectionRequestTimeout());
}
@Test
......@@ -180,7 +181,7 @@ public class SimpleHostRoutingFilterTests {
setupContext();
InputStreamEntity inputStreamEntity = new InputStreamEntity(new ByteArrayInputStream(new byte[]{1}));
HttpRequest httpRequest = getFilter().buildHttpRequest("DELETE", "uri", inputStreamEntity,
new LinkedMultiValueMap<String, String>(), new LinkedMultiValueMap<String, String>(), new MockHttpServletRequest());
new LinkedMultiValueMap<>(), new LinkedMultiValueMap<>(), new MockHttpServletRequest());
assertTrue(httpRequest instanceof HttpEntityEnclosingRequest);
HttpEntityEnclosingRequest httpEntityEnclosingRequest = (HttpEntityEnclosingRequest) httpRequest;
......@@ -192,7 +193,7 @@ public class SimpleHostRoutingFilterTests {
setupContext();
InputStreamEntity inputStreamEntity = new InputStreamEntity(new ByteArrayInputStream(new byte[]{1}));
HttpRequest httpRequest = getFilter().buildHttpRequest("GET", "/app/compressed/get/1", inputStreamEntity,
new LinkedMultiValueMap<String, String>(), new LinkedMultiValueMap<String, String>(), new MockHttpServletRequest());
new LinkedMultiValueMap<>(), new LinkedMultiValueMap<>(), new MockHttpServletRequest());
CloseableHttpResponse response = getFilter().newClient().execute(new HttpHost("localhost", this.port), httpRequest);
assertEquals(200, response.getStatusLine().getStatusCode());
......@@ -205,7 +206,7 @@ public class SimpleHostRoutingFilterTests {
setupContext();
InputStreamEntity inputStreamEntity = new InputStreamEntity(new ByteArrayInputStream(new byte[]{1}));
HttpRequest httpRequest = getFilter().buildHttpRequest("GET", "/app/get/1", inputStreamEntity,
new LinkedMultiValueMap<String, String>(), new LinkedMultiValueMap<String, String>(), new MockHttpServletRequest());
new LinkedMultiValueMap<>(), new LinkedMultiValueMap<>(), new MockHttpServletRequest());
CloseableHttpResponse response = getFilter().newClient().execute(new HttpHost("localhost", this.port), httpRequest);
assertEquals(200, response.getStatusLine().getStatusCode());
......@@ -215,11 +216,11 @@ public class SimpleHostRoutingFilterTests {
@Test
public void redirectTest() throws Exception {
public void redirectTest() throws IOException {
setupContext();
InputStreamEntity inputStreamEntity = new InputStreamEntity(new ByteArrayInputStream(new byte[]{}));
HttpRequest httpRequest = getFilter().buildHttpRequest("GET", "/app/redirect", inputStreamEntity,
new LinkedMultiValueMap<String, String>(), new LinkedMultiValueMap<String, String>(), new MockHttpServletRequest());
new LinkedMultiValueMap<>(), new LinkedMultiValueMap<>(), new MockHttpServletRequest());
CloseableHttpResponse response = getFilter().newClient().execute(new HttpHost("localhost", this.port), httpRequest);
assertEquals(302, response.getStatusLine().getStatusCode());
......@@ -252,11 +253,11 @@ public class SimpleHostRoutingFilterTests {
}
@Test
public void putRequestBuiltWithBody() throws Exception {
public void putRequestBuiltWithBody() {
setupContext();
InputStreamEntity inputStreamEntity = new InputStreamEntity(new ByteArrayInputStream(new byte[]{1}));
HttpRequest httpRequest = getFilter().buildHttpRequest("PUT", "uri", inputStreamEntity,
new LinkedMultiValueMap<String, String>(), new LinkedMultiValueMap<String, String>(), new MockHttpServletRequest());
new LinkedMultiValueMap<>(), new LinkedMultiValueMap<>(), new MockHttpServletRequest());
assertTrue(httpRequest instanceof HttpEntityEnclosingRequest);
HttpEntityEnclosingRequest httpEntityEnclosingRequest = (HttpEntityEnclosingRequest) httpRequest;
......@@ -264,11 +265,11 @@ public class SimpleHostRoutingFilterTests {
}
@Test
public void postRequestBuiltWithBody() throws Exception {
public void postRequestBuiltWithBody() {
setupContext();
InputStreamEntity inputStreamEntity = new InputStreamEntity(new ByteArrayInputStream(new byte[]{1}));
HttpRequest httpRequest = getFilter().buildHttpRequest("POST", "uri", inputStreamEntity,
new LinkedMultiValueMap<String, String>(), new LinkedMultiValueMap<String, String>(), new MockHttpServletRequest());
new LinkedMultiValueMap<>(), new LinkedMultiValueMap<>(), new MockHttpServletRequest());
assertTrue(httpRequest instanceof HttpEntityEnclosingRequest);
HttpEntityEnclosingRequest httpEntityEnclosingRequest = (HttpEntityEnclosingRequest) httpRequest;
......@@ -276,18 +277,18 @@ public class SimpleHostRoutingFilterTests {
}
@Test
public void pathRequestBuiltWithBody() throws Exception {
public void pathRequestBuiltWithBody() {
setupContext();
InputStreamEntity inputStreamEntity = new InputStreamEntity(new ByteArrayInputStream(new byte[]{1}));
HttpRequest httpRequest = getFilter().buildHttpRequest("PATCH", "uri", inputStreamEntity,
new LinkedMultiValueMap<String, String>(), new LinkedMultiValueMap<String, String>(), new MockHttpServletRequest());
new LinkedMultiValueMap<>(), new LinkedMultiValueMap<>(), new MockHttpServletRequest());
HttpPatch basicHttpRequest = (HttpPatch) httpRequest;
assertTrue(basicHttpRequest.getEntity() != null);
}
@Test
public void shouldFilterFalse() throws Exception {
public void shouldFilterFalse() {
setupContext();
assertEquals(false, getFilter().shouldFilter());
}
......@@ -301,7 +302,7 @@ public class SimpleHostRoutingFilterTests {
}
@Test
public void filterOrder() throws Exception {
public void filterOrder() {
setupContext();
assertEquals(100, getFilter().filterOrder());
}
......@@ -351,45 +352,41 @@ public class SimpleHostRoutingFilterTests {
return new SimpleHostRoutingFilter(new ProxyRequestHelper(), zuulProperties, connectionManagerFactory, clientFactory);
}
}
}
@Configuration
@EnableAutoConfiguration
@RestController
class SampleApplication {
public static void main(String[] args) {
SpringApplication.run(SampleApplication.class, args);
}
@RequestMapping(value = "/compressed/get/{id}", method = RequestMethod.GET)
public byte[] getCompressed(@PathVariable String id, HttpServletResponse response) throws IOException {
response.setHeader("content-encoding", "gzip");
return GZIPCompression.compress("Get " + id);
}
@RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
public String getString(@PathVariable String id, HttpServletResponse response) throws IOException {
return "Get " + id;
}
@RequestMapping(value = "/redirect", method = RequestMethod.GET)
public String redirect(HttpServletResponse response) throws IOException {
response.sendRedirect("/app/get/5");
return null;
}
}
class GZIPCompression {
public static byte[] compress(final String str) throws IOException {
if ((str == null) || (str.length() == 0)) {
return null;
}
ByteArrayOutputStream obj = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(obj);
gzip.write(str.getBytes("UTF-8"));
gzip.close();
return obj.toByteArray();
}
@Configuration
@EnableAutoConfiguration
@RestController
static class SampleApplication {
@RequestMapping(value = "/compressed/get/{id}", method = RequestMethod.GET)
public byte[] getCompressed(@PathVariable String id, HttpServletResponse response) throws IOException {
response.setHeader("content-encoding", "gzip");
return GZIPCompression.compress("Get " + id);
}
@RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
public String getString(@PathVariable String id, HttpServletResponse response) throws IOException {
return "Get " + id;
}
@RequestMapping(value = "/redirect", method = RequestMethod.GET)
public String redirect(HttpServletResponse response) throws IOException {
response.sendRedirect("/app/get/5");
return null;
}
}
static class GZIPCompression {
public static byte[] compress(final String str) throws IOException {
if ((str == null) || (str.length() == 0)) {
return null;
}
ByteArrayOutputStream obj = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(obj);
gzip.write(str.getBytes("UTF-8"));
gzip.close();
return obj.toByteArray();
}
}
}
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