From 0adbd5662f8fb87dd9eaa2dc7af5326eaa8e74f4 Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Tue, 4 Oct 2016 18:39:07 -0600 Subject: [PATCH 01/24] polish --- .../cloud/netflix/zuul/filters/ZuulProperties.java | 2 +- .../cloud/netflix/ribbon/RibbonUtilsTests.java | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java index b621f59d..59c37dab 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ZuulProperties.java @@ -103,7 +103,7 @@ public class ZuulProperties { private Set ignoredHeaders = new LinkedHashSet<>(); /** - * SECURITY_HEADERS are added to ignored headers if spring security is on the classpath and ignoreSecurityHeaders = true + * Flag to say that SECURITY_HEADERS are added to ignored headers if spring security is on the classpath. * By setting ignoreSecurityHeaders to false we can switch off this default behaviour. This should be used together with * disabling the default spring security headers * see https://docs.spring.io/spring-security/site/docs/current/reference/html/headers.html#default-security-headers diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonUtilsTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonUtilsTests.java index 53b1bd8d..92548e7f 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonUtilsTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonUtilsTests.java @@ -17,9 +17,6 @@ package org.springframework.cloud.netflix.ribbon; -import static org.hamcrest.Matchers.is; -import static org.springframework.cloud.netflix.ribbon.RibbonUtils.*; - import java.net.URI; import java.net.URISyntaxException; import java.util.Map; @@ -31,6 +28,10 @@ import com.netflix.client.config.CommonClientConfigKey; import com.netflix.client.config.DefaultClientConfigImpl; import com.netflix.loadbalancer.Server; +import static org.hamcrest.Matchers.is; +import static org.springframework.cloud.netflix.ribbon.RibbonUtils.isSecure; +import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToHttpsIfNeeded; + /** * @author Spencer Gibb * @author Jacques-Etienne Beaudet From 8e18c3d3b64b09b48fb77eda298446ebd5c2a0c1 Mon Sep 17 00:00:00 2001 From: bpicode Date: Wed, 5 Oct 2016 02:46:33 +0200 Subject: [PATCH 02/24] Add support for fallback factories in feign client annotation. (#1373) Adds `@FeignClient.fallbackFactory` to define a `feign.hystrix.FallbackFactory`. fixes gh-1117 --- .../main/asciidoc/spring-cloud-netflix.adoc | 24 ++++ .../cloud/netflix/feign/FeignClient.java | 9 ++ .../netflix/feign/FeignClientFactoryBean.java | 2 + .../netflix/feign/FeignClientsRegistrar.java | 1 + .../cloud/netflix/feign/HystrixTargeter.java | 66 ++++++++-- .../invalid/FeignClientValidationTests.java | 124 +++++++++++++++--- .../netflix/feign/valid/FeignClientTests.java | 47 ++++++- 7 files changed, 242 insertions(+), 31 deletions(-) diff --git a/docs/src/main/asciidoc/spring-cloud-netflix.adoc b/docs/src/main/asciidoc/spring-cloud-netflix.adoc index 53961116..1194d049 100644 --- a/docs/src/main/asciidoc/spring-cloud-netflix.adoc +++ b/docs/src/main/asciidoc/spring-cloud-netflix.adoc @@ -1012,6 +1012,30 @@ static class HystrixClientFallback implements HystrixClient { } ---- +If one needs access to the cause that made the fallback trigger, one can use the `fallbackFactory` attribute inside `@FeignClient`. + +[source,java,indent=0] +---- +@FeignClient(name = "hello", fallbackFactory = HystrixClientFallbackFactory.class) +protected interface HystrixClient { + @RequestMapping(method = RequestMethod.GET, value = "/hello") + Hello iFailSometimes(); +} + +@Component +static class HystrixClientFallbackFactory implements FallbackFactory { + @Override + public HystrixClient create(Throwable cause) { + return new HystrixClientWithFallBackFactory() { + @Override + public Hello iFailSometimes() { + return new Hello("fallback; reason was: " + cause.getMessage()); + } + }; + } +} +---- + WARNING: There is a limitation with the implementation of fallbacks in Feign and how Hystrix fallbacks work. Fallbacks are currently not supported for methods that return `com.netflix.hystrix.HystrixCommand` and `rx.Observable`. [[spring-cloud-feign-inheritance]] diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClient.java index 8c2e361f..86620a92 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClient.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClient.java @@ -90,6 +90,15 @@ public @interface FeignClient { */ Class fallback() default void.class; + /** + * Define a fallback factory for the specified Feign client interface. The fallback + * factory must produce instances of fallback classes that implement the interface + * annotated by {@link FeignClient}. + * + * @see feign.hystrix.FallbackFactory for details. + */ + Class fallbackFactory() default void.class; + /** * Path prefix to be used by all method-level mappings. Can be used with or without * @RibbonClient. diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java index fa345d88..18bd5b70 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java @@ -69,6 +69,8 @@ class FeignClientFactoryBean implements FactoryBean, InitializingBean, private Class fallback = void.class; + private Class fallbackFactory = void.class; + @Override public void afterPropertiesSet() throws Exception { Assert.hasText(this.name, "Name must be set"); diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrar.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrar.java index 9020c6e7..53c34ef5 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrar.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientsRegistrar.java @@ -179,6 +179,7 @@ class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, definition.addPropertyValue("type", className); definition.addPropertyValue("decode404", attributes.get("decode404")); definition.addPropertyValue("fallback", attributes.get("fallback")); + definition.addPropertyValue("fallbackFactory", attributes.get("fallbackFactory")); definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE); String alias = name + "FeignClient"; diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/HystrixTargeter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/HystrixTargeter.java index 5b9ed8d8..66106c70 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/HystrixTargeter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/HystrixTargeter.java @@ -19,6 +19,9 @@ package org.springframework.cloud.netflix.feign; import feign.Feign; import feign.Target; +import feign.hystrix.FallbackFactory; +import feign.hystrix.HystrixFeign; +import org.springframework.util.Assert; /** * @author Spencer Gibb @@ -29,26 +32,67 @@ class HystrixTargeter implements Targeter { @Override public T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context, Target.HardCodedTarget target) { - if (factory.getFallback() == void.class - || !(feign instanceof feign.hystrix.HystrixFeign.Builder)) { + if (!(feign instanceof feign.hystrix.HystrixFeign.Builder)) { return feign.target(target); } + feign.hystrix.HystrixFeign.Builder builder = (feign.hystrix.HystrixFeign.Builder) feign; + Class fallback = factory.getFallback(); + if (fallback != void.class) { + return targetWithFallback(factory.getName(), context, target, builder, fallback); + } + Class fallbackFactory = factory.getFallbackFactory(); + if (fallbackFactory != void.class) { + return targetWithFallbackFactory(factory.getName(), context, target, builder, fallbackFactory); + } - Object fallbackInstance = context.getInstance(factory.getName(), factory.getFallback()); + return feign.target(target); + } + + private T targetWithFallbackFactory(String feignClientName, FeignContext context, + Target.HardCodedTarget target, + HystrixFeign.Builder builder, + Class fallbackFactoryClass) { + FallbackFactory fallbackFactory = (FallbackFactory) + getFromContext("fallbackFactory", feignClientName, context, fallbackFactoryClass, FallbackFactory.class); + /* We take a sample fallback from the fallback factory to check if it returns a fallback + that is compatible with the annotated feign interface. */ + Object exampleFallback = fallbackFactory.create(new RuntimeException()); + Assert.notNull(exampleFallback, + String.format( + "Incompatible fallbackFactory instance for feign client %s. Factory may not produce null!", + feignClientName)); + if (!target.type().isAssignableFrom(exampleFallback.getClass())) { + throw new IllegalStateException( + String.format( + "Incompatible fallbackFactory instance for feign client %s. Factory produces instances of '%s', but should produce instances of '%s'", + feignClientName, exampleFallback.getClass(), target.type())); + } + return builder.target(target, fallbackFactory); + } + + + private T targetWithFallback(String feignClientName, FeignContext context, + Target.HardCodedTarget target, + HystrixFeign.Builder builder, Class fallback) { + T fallbackInstance = getFromContext("fallback", feignClientName, context, fallback, target.type()); + return builder.target(target, fallbackInstance); + } + + private T getFromContext(String fallbackMechanism, String feignClientName, FeignContext context, + Class beanType, Class targetType) { + Object fallbackInstance = context.getInstance(feignClientName, beanType); if (fallbackInstance == null) { throw new IllegalStateException(String.format( - "No fallback instance of type %s found for feign client %s", - factory.getFallback(), factory.getName())); + "No " + fallbackMechanism + " instance of type %s found for feign client %s", + beanType, feignClientName)); } - if (!target.type().isAssignableFrom(factory.getFallback())) { + if (!targetType.isAssignableFrom(beanType)) { throw new IllegalStateException( String.format( - "Incompatible fallback instance. Fallback of type %s is not assignable to %s for feign client %s", - factory.getFallback(), target.type(), factory.getName())); + "Incompatible " + fallbackMechanism + " instance. Fallback/fallbackFactory of type %s is not assignable to %s for feign client %s", + beanType, targetType, feignClientName)); } - - feign.hystrix.HystrixFeign.Builder builder = (feign.hystrix.HystrixFeign.Builder) feign; - return builder.target(target, (T) fallbackInstance); + return (T) fallbackInstance; } } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/invalid/FeignClientValidationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/invalid/FeignClientValidationTests.java index 178fc643..bd7d235f 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/invalid/FeignClientValidationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/invalid/FeignClientValidationTests.java @@ -16,6 +16,7 @@ package org.springframework.cloud.netflix.feign.invalid; +import feign.hystrix.FallbackFactory; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -42,10 +43,7 @@ public class FeignClientValidationTests { @Test public void testNameAndValue() { this.expected.expectMessage("only one is permitted"); - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( - NameAndValueConfiguration.class); - assertNotNull(context.getBean(NameAndValueConfiguration.Client.class)); - context.close(); + new AnnotationConfigApplicationContext(NameAndValueConfiguration.class); } @Configuration @@ -86,10 +84,7 @@ public class FeignClientValidationTests { @Test public void testNotLegalHostname() { this.expected.expectMessage("not legal hostname (foo_bar)"); - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( - BadHostnameConfiguration.class); - assertNotNull(context.getBean(BadHostnameConfiguration.Client.class)); - context.close(); + new AnnotationConfigApplicationContext(BadHostnameConfiguration.class); } @Configuration @@ -107,11 +102,12 @@ public class FeignClientValidationTests { @Test public void testMissingFallback() { - this.expected.expectMessage("No fallback instance of type"); + try ( AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( - MissingFallbackConfiguration.class); - assertNotNull(context.getBean(MissingFallbackConfiguration.Client.class)); - context.close(); + MissingFallbackConfiguration.class)) { + this.expected.expectMessage("No fallback instance of type"); + assertNotNull(context.getBean(MissingFallbackConfiguration.Client.class)); + } } @Configuration @@ -136,11 +132,11 @@ public class FeignClientValidationTests { @Test public void testWrongFallbackType() { - this.expected.expectMessage("Incompatible fallback instance"); - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( - WrongFallbackTypeConfiguration.class); - assertNotNull(context.getBean(WrongFallbackTypeConfiguration.Client.class)); - context.close(); + try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + WrongFallbackTypeConfiguration.class)) { + this.expected.expectMessage("Incompatible fallback instance"); + assertNotNull(context.getBean(WrongFallbackTypeConfiguration.Client.class)); + } } @Configuration @@ -163,4 +159,98 @@ public class FeignClientValidationTests { } } + + @Test + public void testMissingFallbackFactory() { + try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + MissingFallbackFactoryConfiguration.class)) { + this.expected.expectMessage("No fallbackFactory instance of type"); + assertNotNull(context.getBean(MissingFallbackFactoryConfiguration.Client.class)); + } + } + + @Configuration + @Import(FeignAutoConfiguration.class) + @EnableFeignClients(clients = MissingFallbackFactoryConfiguration.Client.class) + protected static class MissingFallbackFactoryConfiguration { + + @FeignClient(name = "foobar", url = "http://localhost", fallbackFactory = ClientFallback.class) + interface Client { + @RequestMapping(method = RequestMethod.GET, value = "/") + String get(); + } + + class ClientFallback implements FallbackFactory { + + @Override + public Client create(Throwable cause) { + return null; + } + } + } + + @Test + public void testWrongFallbackFactoryType() { + try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + WrongFallbackFactoryTypeConfiguration.class)) { + this.expected.expectMessage("Incompatible fallbackFactory instance"); + assertNotNull(context.getBean(WrongFallbackFactoryTypeConfiguration.Client.class)); + } + } + + @Configuration + @Import(FeignAutoConfiguration.class) + @EnableFeignClients(clients = WrongFallbackFactoryTypeConfiguration.Client.class) + protected static class WrongFallbackFactoryTypeConfiguration { + + @FeignClient(name = "foobar", url = "http://localhost", fallbackFactory = Dummy.class) + interface Client { + @RequestMapping(method = RequestMethod.GET, value = "/") + String get(); + } + + @Bean + Dummy dummy() { + return new Dummy(); + } + + class Dummy { + } + + } + + @Test + public void testWrongFallbackFactoryGenericType() { + try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + WrongFallbackFactoryGenericTypeConfiguration.class)) { + this.expected.expectMessage("Incompatible fallbackFactory instance"); + assertNotNull(context.getBean(WrongFallbackFactoryGenericTypeConfiguration.Client.class)); + } + } + + @Configuration + @Import(FeignAutoConfiguration.class) + @EnableFeignClients(clients = WrongFallbackFactoryGenericTypeConfiguration.Client.class) + protected static class WrongFallbackFactoryGenericTypeConfiguration { + + @FeignClient(name = "foobar", url = "http://localhost", fallbackFactory = ClientFallback.class) + interface Client { + @RequestMapping(method = RequestMethod.GET, value = "/") + String get(); + } + + @Bean + ClientFallback dummy() { + return new ClientFallback(); + } + + class ClientFallback implements FallbackFactory { + + @Override + public String create(Throwable cause) { + return "tryinToTrickYa"; + } + } + + } } diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientTests.java index 49f3b831..366e6454 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/valid/FeignClientTests.java @@ -74,6 +74,7 @@ import feign.Client; import feign.Logger; import feign.RequestInterceptor; import feign.RequestTemplate; +import feign.hystrix.FallbackFactory; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -115,6 +116,9 @@ public class FeignClientTests { @Autowired HystrixClient hystrixClient; + @Autowired + private HystrixClientWithFallBackFactory hystrixClientWithFallBackFactory; + @Autowired @Qualifier("localapp3FeignClient") HystrixClient namedHystrixClient; @@ -237,6 +241,27 @@ public class FeignClientTests { Future failFuture(); } + @FeignClient(name = "localapp4", fallbackFactory = HystrixClientFallbackFactory.class) + protected interface HystrixClientWithFallBackFactory { + + @RequestMapping(method = RequestMethod.GET, path = "/fail") + Hello fail(); + } + + static class HystrixClientFallbackFactory implements FallbackFactory { + + @Override + public HystrixClientWithFallBackFactory create(final Throwable cause) { + return new HystrixClientWithFallBackFactory() { + @Override + public Hello fail() { + assertNotNull("Cause was null", cause); + return new Hello("Hello from the fallback side: " + cause.getMessage()); + } + }; + } + } + static class HystrixClientFallback implements HystrixClient { @Override public Hello fail() { @@ -268,13 +293,15 @@ public class FeignClientTests { @EnableAutoConfiguration @RestController @EnableFeignClients(clients = { TestClientServiceId.class, TestClient.class, - DecodingTestClient.class, - HystrixClient.class }, defaultConfiguration = TestDefaultFeignConfig.class) + DecodingTestClient.class, HystrixClient.class, HystrixClientWithFallBackFactory.class }, + defaultConfiguration = TestDefaultFeignConfig.class) @RibbonClients({ @RibbonClient(name = "localapp", configuration = LocalRibbonClientConfiguration.class), @RibbonClient(name = "localapp1", configuration = LocalRibbonClientConfiguration.class), @RibbonClient(name = "localapp2", configuration = LocalRibbonClientConfiguration.class), - @RibbonClient(name = "localapp3", configuration = LocalRibbonClientConfiguration.class), }) + @RibbonClient(name = "localapp3", configuration = LocalRibbonClientConfiguration.class), + @RibbonClient(name = "localapp4", configuration = LocalRibbonClientConfiguration.class) + }) protected static class Application { // needs to be in parent context to test multiple HystrixClient beans @@ -283,6 +310,11 @@ public class FeignClientTests { return new HystrixClientFallback(); } + @Bean + public HystrixClientFallbackFactory hystrixClientFallbackFactory() { + return new HystrixClientFallbackFactory(); + } + @Bean FeignFormatterRegistrar feignFormatterRegistrar() { return new FeignFormatterRegistrar() { @@ -584,6 +616,15 @@ public class FeignClientTests { assertEquals("message was wrong", "fallbackfuture", hello.getMessage()); } + @Test + public void testHystrixClientWithFallBackFactory() throws Exception { + Hello hello = hystrixClientWithFallBackFactory.fail(); + assertNotNull("hello was null", hello); + assertNotNull("hello#message was null", hello.getMessage()); + assertTrue("hello#message did not contain the cause (status code) of the fallback invocation", + hello.getMessage().contains("500")); + } + @Test public void namedFeignClientWorks() { assertNotNull("namedHystrixClient was null", this.namedHystrixClient); From 622cc832044c7dc6165ece59502099936f3fa61f Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Tue, 4 Oct 2016 18:48:28 -0600 Subject: [PATCH 03/24] polish --- .../org/springframework/cloud/netflix/feign/FeignClient.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClient.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClient.java index 86620a92..1dc139a1 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClient.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClient.java @@ -93,7 +93,8 @@ public @interface FeignClient { /** * Define a fallback factory for the specified Feign client interface. The fallback * factory must produce instances of fallback classes that implement the interface - * annotated by {@link FeignClient}. + * annotated by {@link FeignClient}. The fallback factory must be a valid spring + * bean. * * @see feign.hystrix.FallbackFactory for details. */ From ba3923d70608e695aa7a928eb711e4e5da82897e Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Wed, 5 Oct 2016 12:51:28 -0600 Subject: [PATCH 04/24] Fix zuul error when there are colons in request param name. Previously, parameter names with colons (ie foo:bar), caused an IllegalArgumentException because 41c364002fe2e0d9e9c1f59ccf4a9c530dcde04a introduced UriTemplate to properly encode. fixes gh-1193 --- .../zuul/filters/ProxyRequestHelper.java | 23 ++++++++++++++++--- .../zuul/filters/ProxyRequestHelperTests.java | 22 ++++++++++++++++++ ...stClientRibbonCommandIntegrationTests.java | 18 ++++++++++++++- 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelper.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelper.java index 0f99a99e..85bdb599 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelper.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelper.java @@ -249,6 +249,12 @@ public class ProxyRequestHelper { MultiValueMap headers) { } + /** + * Get url encoded query string. Pay special attention to single parameters with no values + * and parameter names with colon (:) from use of UriTemplate. + * @param params Un-encoded request parameters + * @return + */ public String getQueryString(MultiValueMap params) { if (params.isEmpty()) { return ""; @@ -260,10 +266,21 @@ public class ProxyRequestHelper { for (String value : params.get(param)) { query.append("&"); query.append(param); - if (!"".equals(value)) { - singles.put(param + i, value); + if (!"".equals(value)) { // don't add =, if original is ?wsdl, output is not ?wsdl= + String key = param; + // if form feed is already part of param name double + // since form feed is used as the colon replacement below + if (key.contains("\f")) { + key = (key.replaceAll("\f", "\f\f")); + } + // colon is special to UriTemplate + if (key.contains(":")) { + key = key.replaceAll(":", "\f"); + } + key = key + i; + singles.put(key, value); query.append("={"); - query.append(param + i); + query.append(key); query.append("}"); } i++; diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelperTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelperTests.java index a3f6f6ab..4d211dc0 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelperTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/ProxyRequestHelperTests.java @@ -259,6 +259,28 @@ public class ProxyRequestHelperTests { assertThat(queryString, is("?wsdl")); } + @Test + public void getQueryStringEncoded() { + MultiValueMap params = new LinkedMultiValueMap<>(); + params.add("foo", "weird#chars"); + + String queryString = new ProxyRequestHelper().getQueryString(params); + + assertThat(queryString, is("?foo=weird%23chars")); + } + + @Test + public void getQueryParamNameWithColon() { + MultiValueMap params = new LinkedMultiValueMap<>(); + params.add("foo:bar", "baz"); + params.add("foobar", "bam"); + params.add("foo\fbar", "bat"); // form feed is the colon replacement char + + String queryString = new ProxyRequestHelper().getQueryString(params); + + assertThat(queryString, is("?foo:bar=baz&foobar=bam&foo%0Cbar=bat")); + } + @Test public void buildZuulRequestURIWithUTF8() throws Exception { String encodedURI = "/resource/esp%C3%A9cial-char"; diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandIntegrationTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandIntegrationTests.java index 826a574b..7b1a4d8b 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandIntegrationTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/restclient/RestClientRibbonCommandIntegrationTests.java @@ -186,6 +186,17 @@ public class RestClientRibbonCommandIntegrationTests extends ZuulProxyTestBase { assertEquals("/query?foo=weird#chars", result.getBody()); } + @Test + public void simpleHostRouteWithColonParamNames() { + this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); + this.endpoint.reset(); + ResponseEntity result = new TestRestTemplate().exchange( + "http://localhost:" + this.port + "/self/colonquery?foo:bar={foobar0}&foobar={foobar1}", HttpMethod.GET, + new HttpEntity<>((Void) null), String.class, "baz", "bam"); + assertEquals(HttpStatus.OK, result.getStatusCode()); + assertEquals("/colonquery?foo:bar=baz&foobar=bam", result.getBody()); + } + @Test public void simpleHostRouteWithContentType() { this.routes.addRoute("/self/**", "http://localhost:" + this.port + "/"); @@ -295,10 +306,15 @@ public class RestClientRibbonCommandIntegrationTests extends ZuulProxyTestBase { } @RequestMapping("/query") - public String addQuery(HttpServletRequest request, @RequestParam String foo) { + public String query(HttpServletRequest request, @RequestParam String foo) { return request.getRequestURI() + "?foo=" + foo; } + @RequestMapping("/colonquery") + public String colonQuery(HttpServletRequest request, @RequestParam(name = "foo:bar") String foobar0, @RequestParam(name = "foobar") String foobar1) { + return request.getRequestURI() + "?foo:bar=" + foobar0 + "&foobar=" + foobar1; + } + @RequestMapping("/matrix/{name}/{another}") public String matrix(@PathVariable("name") String name, @MatrixVariable(value = "p", pathVar = "name") int p, From f30e8b7b4630db74b1cccf436fb3f50f94618427 Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Thu, 6 Oct 2016 10:19:46 -0600 Subject: [PATCH 05/24] Remove @Autowired from FeignClientFactoryBean @Autowired causes NullPointerExceptions because of some unknown lifecycle issues. fixes gh-1366 --- .../cloud/netflix/feign/FeignClientFactoryBean.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java index 18bd5b70..e5fcffc7 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/FeignClientFactoryBean.java @@ -51,9 +51,9 @@ import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = false) class FeignClientFactoryBean implements FactoryBean, InitializingBean, ApplicationContextAware { - - @Autowired - private Targeter targeter; + /*********************************** + * WARNING! Nothing in this class should be @Autowired. It causes NPEs because of some lifecycle race condition. + ***********************************/ private Class type; @@ -146,6 +146,7 @@ class FeignClientFactoryBean implements FactoryBean, InitializingBean, Client client = getOptional(context, Client.class); if (client != null) { builder.client(client); + Targeter targeter = get(context, Targeter.class); return targeter.target(this, builder, context, target); } @@ -183,6 +184,7 @@ class FeignClientFactoryBean implements FactoryBean, InitializingBean, } builder.client(client); } + Targeter targeter = get(context, Targeter.class); return targeter.target(this, builder, context, new HardCodedTarget<>( this.type, this.name, url)); } From dd97b6a4b71fc2612feeb07fabd7872b6d91d50b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20S=C5=82ota?= Date: Fri, 7 Oct 2016 00:11:24 +0200 Subject: [PATCH 06/24] #1376 Register and cancel event sending fix --- .../eureka/server/InstanceRegistry.java | 66 ++++++++++++++----- 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java index 05c5676f..fe2090f6 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java @@ -18,6 +18,7 @@ package org.springframework.cloud.netflix.eureka.server; import java.util.List; +import com.netflix.eureka.lease.Lease; import org.springframework.beans.BeansException; import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceCanceledEvent; import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRegisteredEvent; @@ -78,27 +79,23 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl @Override public void register(InstanceInfo info, int leaseDuration, boolean isReplication) { - if (log.isDebugEnabled()) { - log.debug("register " + info.getAppName() + ", vip " + info.getVIPAddress() - + ", leaseDuration " + leaseDuration + ", isReplication " - + isReplication); - } - // TODO: what to publish from info (whole object?) - this.ctxt.publishEvent(new EurekaInstanceRegisteredEvent(this, info, - leaseDuration, isReplication)); - + logRegistration(info, isReplication, leaseDuration); + publishEurekaInstanceRegisteredEvent(info, leaseDuration, isReplication); super.register(info, leaseDuration, isReplication); } @Override - public boolean cancel(String appName, String serverId, boolean isReplication) { - if (log.isDebugEnabled()) { - log.debug("cancel " + appName + " serverId " + serverId + ", isReplication {}" - + isReplication); - } - this.ctxt.publishEvent( - new EurekaInstanceCanceledEvent(this, appName, serverId, isReplication)); + public void register(final InstanceInfo info, final boolean isReplication) { + final int instanceLeaseDuration = resolveInstanceLeaseDuration(info); + logRegistration(info, isReplication, instanceLeaseDuration); + publishEurekaInstanceRegisteredEvent(info, instanceLeaseDuration, isReplication); + super.register(info, isReplication); + } + @Override + public boolean cancel(String appName, String serverId, boolean isReplication) { + logCancelation(appName, serverId, isReplication); + publishEurekaInstanceCanceledEvent(appName, serverId, isReplication); return super.cancel(appName, serverId, isReplication); } @@ -126,4 +123,41 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl } return super.renew(appName, serverId, isReplication); } + + @Override + protected boolean internalCancel(String appName, String id, boolean isReplication) { + logCancelation(appName, id, isReplication); + publishEurekaInstanceCanceledEvent(appName, id, isReplication); + return super.internalCancel(appName, id, isReplication); + } + + private void logRegistration(InstanceInfo info, boolean isReplication, int instanceLeaseDuration) { + if (log.isDebugEnabled()) { + log.debug("register " + info.getAppName() + ", vip " + info.getVIPAddress() + + ", leaseDuration " + instanceLeaseDuration + ", isReplication " + isReplication); + } + } + + private void logCancelation(String appName, String serverId, boolean isReplication) { + if (log.isDebugEnabled()) { + log.debug("cancel " + appName + " serverId " + serverId + ", isReplication " + isReplication); + } + } + + private void publishEurekaInstanceRegisteredEvent(InstanceInfo info, int leaseDuration, boolean isReplication) { + // TODO: what to publish from info (whole object?) + this.ctxt.publishEvent(new EurekaInstanceRegisteredEvent(this, info, leaseDuration, isReplication)); + } + + private void publishEurekaInstanceCanceledEvent(String appName, String serverId, boolean isReplication) { + this.ctxt.publishEvent(new EurekaInstanceCanceledEvent(this, appName, serverId, isReplication)); + } + + private int resolveInstanceLeaseDuration(final InstanceInfo info) { + int leaseDuration = Lease.DEFAULT_DURATION_IN_SECS; + if (info.getLeaseInfo() != null && info.getLeaseInfo().getDurationInSecs() > 0) { + leaseDuration = info.getLeaseInfo().getDurationInSecs(); + } + return leaseDuration; + } } From 151e021ef970c5c01c0efe056736a9e5e593558d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20S=C5=82ota?= Date: Sat, 8 Oct 2016 00:15:47 +0200 Subject: [PATCH 07/24] formatting fixed + tests, fixes #1376 --- .../eureka/server/InstanceRegistry.java | 34 +++- .../eureka/server/InstanceRegistryTest.java | 179 ++++++++++++++++++ 2 files changed, 204 insertions(+), 9 deletions(-) create mode 100644 spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java index fe2090f6..7ff9de68 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java @@ -89,7 +89,7 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl final int instanceLeaseDuration = resolveInstanceLeaseDuration(info); logRegistration(info, isReplication, instanceLeaseDuration); publishEurekaInstanceRegisteredEvent(info, instanceLeaseDuration, isReplication); - super.register(info, isReplication); + superRegister(info, isReplication); } @Override @@ -128,29 +128,45 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl protected boolean internalCancel(String appName, String id, boolean isReplication) { logCancelation(appName, id, isReplication); publishEurekaInstanceCanceledEvent(appName, id, isReplication); + return superInternalCancel(appName, id, isReplication); + } + + protected boolean superInternalCancel(String appName, String id, + boolean isReplication) { return super.internalCancel(appName, id, isReplication); } - private void logRegistration(InstanceInfo info, boolean isReplication, int instanceLeaseDuration) { + protected void superRegister(InstanceInfo info, boolean isReplication) { + super.register(info, isReplication); + } + + private void logRegistration(InstanceInfo info, boolean isReplication, + int instanceLeaseDuration) { if (log.isDebugEnabled()) { - log.debug("register " + info.getAppName() + ", vip " + info.getVIPAddress() - + ", leaseDuration " + instanceLeaseDuration + ", isReplication " + isReplication); + log.debug("register " + info.getAppName() + ", vip " + info.getVIPAddress() + + ", leaseDuration " + instanceLeaseDuration + ", isReplication " + + isReplication); } } private void logCancelation(String appName, String serverId, boolean isReplication) { if (log.isDebugEnabled()) { - log.debug("cancel " + appName + " serverId " + serverId + ", isReplication " + isReplication); + log.debug("cancel " + appName + " serverId " + serverId + ", isReplication " + + isReplication); } } - private void publishEurekaInstanceRegisteredEvent(InstanceInfo info, int leaseDuration, boolean isReplication) { + private void publishEurekaInstanceRegisteredEvent(InstanceInfo info, + int leaseDuration, boolean isReplication) { // TODO: what to publish from info (whole object?) - this.ctxt.publishEvent(new EurekaInstanceRegisteredEvent(this, info, leaseDuration, isReplication)); + this.ctxt.publishEvent(new EurekaInstanceRegisteredEvent(this, info, + leaseDuration, isReplication)); } - private void publishEurekaInstanceCanceledEvent(String appName, String serverId, boolean isReplication) { - this.ctxt.publishEvent(new EurekaInstanceCanceledEvent(this, appName, serverId, isReplication)); + private void publishEurekaInstanceCanceledEvent(String appName, String serverId, + boolean isReplication) { + this.ctxt.publishEvent( + new EurekaInstanceCanceledEvent(this, appName, serverId, isReplication)); } private int resolveInstanceLeaseDuration(final InstanceInfo info) { diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java new file mode 100644 index 00000000..4c32ce34 --- /dev/null +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java @@ -0,0 +1,179 @@ +package org.springframework.cloud.netflix.eureka.server; + +import static org.junit.Assert.*; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.*; + +import java.util.LinkedList; +import java.util.List; + +import org.junit.Before; +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.builder.SpringApplicationBuilder; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.cloud.netflix.eureka.server.InstanceRegistryTest.Application; +import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceCanceledEvent; +import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRegisteredEvent; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.netflix.appinfo.InstanceInfo; +import com.netflix.appinfo.LeaseInfo; +import com.netflix.eureka.registry.PeerAwareInstanceRegistry; + +/** + * @author Bartlomiej Slota + */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringBootTest(classes = Application.class, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + value = {"spring.application.name=eureka", "logging.level.org.springframework." + + "cloud.netflix.eureka.server.InstanceRegistry=DEBUG"}) +public class InstanceRegistryTest { + + @SpyBean(PeerAwareInstanceRegistry.class) + private InstanceRegistry instanceRegistry; + + @Autowired + private Listener eurekaEventListener; + + @Before + public void setup() { + eurekaEventListener.getApplicationEvents().clear(); + } + + @Test + public void testRegister() throws Exception { + // stubbing superclass method invocation + doNothing().when(instanceRegistry) + .superRegister(any(InstanceInfo.class), anyBoolean()); + + // creating instance info + LeaseInfo leaseInfo = getLeaseInfo(); + InstanceInfo instanceInfo = getInstanceInfo(leaseInfo); + + // calling tested method + instanceRegistry.register(instanceInfo, false); + + // event of proper type is registered + assertEquals(1, eurekaEventListener.getApplicationEvents().size()); + assertTrue(eurekaEventListener.getApplicationEvents().get(0) + instanceof EurekaInstanceRegisteredEvent); + + // event details are correct + EurekaInstanceRegisteredEvent registeredEvent = (EurekaInstanceRegisteredEvent) + (eurekaEventListener.getApplicationEvents().get(0)); + assertEquals(instanceInfo, registeredEvent.getInstanceInfo()); + assertEquals(leaseInfo.getDurationInSecs(), registeredEvent.getLeaseDuration()); + assertEquals(instanceRegistry, registeredEvent.getSource()); + assertFalse(registeredEvent.isReplication()); + + // superclass method wrapper was successfully invoked + verify(instanceRegistry).superRegister(instanceInfo, false); + } + + @Test + public void testDefaultLeaseDurationRegisterEvent() throws Exception { + // stubbing superclass method invocation + doNothing().when(instanceRegistry) + .superRegister(any(InstanceInfo.class), anyBoolean()); + + // creating instance info + InstanceInfo instanceInfo = getInstanceInfo(null); + + // calling tested method + instanceRegistry.register(instanceInfo, false); + + // instance info duration is set to default + EurekaInstanceRegisteredEvent registeredEvent = (EurekaInstanceRegisteredEvent) + (eurekaEventListener.getApplicationEvents().get(0)); + assertEquals(LeaseInfo.DEFAULT_LEASE_DURATION, registeredEvent.getLeaseDuration()); + } + + @Test + public void testInternalCancel() throws Exception { + // stubbing superclass method invocation + doReturn(Boolean.TRUE).when(instanceRegistry) + .superInternalCancel(anyString(), anyString(), anyBoolean()); + + // calling tested method + boolean cancellationResult = instanceRegistry + .internalCancel("my-app", "appId", false); + + // event of proper type is registered + assertEquals(1, eurekaEventListener.getApplicationEvents().size()); + assertTrue(eurekaEventListener.getApplicationEvents().get(0) + instanceof EurekaInstanceCanceledEvent); + + // event details are correct + EurekaInstanceCanceledEvent registeredEvent = (EurekaInstanceCanceledEvent) + (eurekaEventListener.getApplicationEvents().get(0)); + assertEquals("my-app", registeredEvent.getAppName()); + assertEquals("appId", registeredEvent.getServerId()); + assertEquals(instanceRegistry, registeredEvent.getSource()); + assertFalse(registeredEvent.isReplication()); + + // superclass method wrapper was successfully invoked + verify(instanceRegistry).superInternalCancel("my-app", "appId", false); + assertTrue(cancellationResult); + } + + @Configuration + @EnableAutoConfiguration + @EnableEurekaServer + protected static class Application { + + public static void main(String[] args) { + new SpringApplicationBuilder(Application.class) + .properties("spring.application.name=eureka").run(args); + } + + @Bean + public Listener eurekaEventsListener() { + return new Listener(); + } + } + + private LeaseInfo getLeaseInfo() { + LeaseInfo.Builder leaseBuilder = LeaseInfo.Builder.newBuilder(); + leaseBuilder.setRenewalIntervalInSecs(10); + leaseBuilder.setDurationInSecs(15); + return leaseBuilder.build(); + } + + + private InstanceInfo getInstanceInfo(LeaseInfo leaseInfo) { + InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder(); + builder.setAppName("my-app-name"); + builder.setHostName("my-host-name"); + builder.setPort(8008); + builder.setLeaseInfo(leaseInfo); + return builder.build(); + } + + private static class Listener implements ApplicationListener { + + private final List applicationEvents = new LinkedList<>(); + + @Override + public void onApplicationEvent(ApplicationEvent event) { + if (event instanceof EurekaInstanceCanceledEvent || + event instanceof EurekaInstanceRegisteredEvent) { + applicationEvents.add(event); + } + } + + public List getApplicationEvents() { + return applicationEvents; + } + } +} \ No newline at end of file From 99b86e7a29e3864a351291e7141750b4b96ec1ba Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Mon, 10 Oct 2016 15:31:42 -0400 Subject: [PATCH 08/24] Fixes #1374 --- .../filters/pre/FormBodyWrapperFilter.java | 45 ++++++++++--------- spring-cloud-netflix-dependencies/pom.xml | 2 +- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java index 22681762..dfe88c7d 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java @@ -16,22 +16,10 @@ package org.springframework.cloud.netflix.zuul.filters.pre; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.lang.reflect.Field; -import java.util.HashSet; -import java.util.List; -import java.util.Map.Entry; -import java.util.Set; - -import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletRequestWrapper; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.Part; - -import org.apache.commons.lang3.StringUtils; +import com.netflix.zuul.ZuulFilter; +import com.netflix.zuul.context.RequestContext; +import com.netflix.zuul.http.HttpServletRequestWrapper; +import com.netflix.zuul.http.ServletInputStreamWrapper; import org.springframework.core.io.InputStreamResource; import org.springframework.core.io.Resource; import org.springframework.http.HttpEntity; @@ -44,14 +32,23 @@ import org.springframework.util.Assert; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.ReflectionUtils; +import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartRequest; import org.springframework.web.servlet.DispatcherServlet; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.http.HttpServletRequestWrapper; -import com.netflix.zuul.http.ServletInputStreamWrapper; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletRequest; +import javax.servlet.ServletRequestWrapper; +import javax.servlet.http.HttpServletRequest; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.lang.reflect.Field; +import java.util.HashSet; +import java.util.List; +import java.util.Map.Entry; +import java.util.Set; /** * @author Spencer Gibb @@ -232,8 +229,12 @@ public class FormBodyWrapperFilter extends ZuulFilter { private Set findQueryParams() { Set result = new HashSet<>(); String query = this.request.getQueryString(); - if (query != null) { - for (String value : StringUtils.split(query, "&")) { + String[] splitQuery = StringUtils.split(query, "&"); + if(splitQuery == null && query != null) { + splitQuery = new String[]{query}; + } + if (splitQuery != null) { + for (String value : splitQuery) { if (value.contains("=")) { value = value.substring(0, value.indexOf("=")); } diff --git a/spring-cloud-netflix-dependencies/pom.xml b/spring-cloud-netflix-dependencies/pom.xml index 99e3cb2d..094bee0e 100644 --- a/spring-cloud-netflix-dependencies/pom.xml +++ b/spring-cloud-netflix-dependencies/pom.xml @@ -17,7 +17,7 @@ 0.7.4 1.4.11 9.3.1 - 1.5.5 + 1.5.6 2.2.0 0.10.1 1.2.2 From 50fac81a30a82648dab82e7e7a5e5a1ae43ad719 Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Mon, 10 Oct 2016 15:32:20 -0400 Subject: [PATCH 09/24] Revert "Fixes #1374" This reverts commit 99b86e7a29e3864a351291e7141750b4b96ec1ba. --- .../filters/pre/FormBodyWrapperFilter.java | 45 +++++++++---------- spring-cloud-netflix-dependencies/pom.xml | 2 +- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java index dfe88c7d..22681762 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java @@ -16,10 +16,22 @@ package org.springframework.cloud.netflix.zuul.filters.pre; -import com.netflix.zuul.ZuulFilter; -import com.netflix.zuul.context.RequestContext; -import com.netflix.zuul.http.HttpServletRequestWrapper; -import com.netflix.zuul.http.ServletInputStreamWrapper; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.lang.reflect.Field; +import java.util.HashSet; +import java.util.List; +import java.util.Map.Entry; +import java.util.Set; + +import javax.servlet.ServletInputStream; +import javax.servlet.ServletRequest; +import javax.servlet.ServletRequestWrapper; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.Part; + +import org.apache.commons.lang3.StringUtils; import org.springframework.core.io.InputStreamResource; import org.springframework.core.io.Resource; import org.springframework.http.HttpEntity; @@ -32,23 +44,14 @@ import org.springframework.util.Assert; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartRequest; import org.springframework.web.servlet.DispatcherServlet; -import javax.servlet.ServletInputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletRequestWrapper; -import javax.servlet.http.HttpServletRequest; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.lang.reflect.Field; -import java.util.HashSet; -import java.util.List; -import java.util.Map.Entry; -import java.util.Set; +import com.netflix.zuul.ZuulFilter; +import com.netflix.zuul.context.RequestContext; +import com.netflix.zuul.http.HttpServletRequestWrapper; +import com.netflix.zuul.http.ServletInputStreamWrapper; /** * @author Spencer Gibb @@ -229,12 +232,8 @@ public class FormBodyWrapperFilter extends ZuulFilter { private Set findQueryParams() { Set result = new HashSet<>(); String query = this.request.getQueryString(); - String[] splitQuery = StringUtils.split(query, "&"); - if(splitQuery == null && query != null) { - splitQuery = new String[]{query}; - } - if (splitQuery != null) { - for (String value : splitQuery) { + if (query != null) { + for (String value : StringUtils.split(query, "&")) { if (value.contains("=")) { value = value.substring(0, value.indexOf("=")); } diff --git a/spring-cloud-netflix-dependencies/pom.xml b/spring-cloud-netflix-dependencies/pom.xml index 094bee0e..99e3cb2d 100644 --- a/spring-cloud-netflix-dependencies/pom.xml +++ b/spring-cloud-netflix-dependencies/pom.xml @@ -17,7 +17,7 @@ 0.7.4 1.4.11 9.3.1 - 1.5.6 + 1.5.5 2.2.0 0.10.1 1.2.2 From 279edf0665e4646e8ea633b5468f27f5fb7d097d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20S=C5=82ota?= Date: Mon, 10 Oct 2016 22:54:39 +0200 Subject: [PATCH 10/24] super class method wrappers removal and test update #1376 --- .../eureka/server/InstanceRegistry.java | 11 +- .../eureka/server/InstanceRegistryTest.java | 231 ++++++++---------- 2 files changed, 101 insertions(+), 141 deletions(-) diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java index 7ff9de68..69fe52ba 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java @@ -89,7 +89,7 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl final int instanceLeaseDuration = resolveInstanceLeaseDuration(info); logRegistration(info, isReplication, instanceLeaseDuration); publishEurekaInstanceRegisteredEvent(info, instanceLeaseDuration, isReplication); - superRegister(info, isReplication); + super.register(info, isReplication); } @Override @@ -128,18 +128,9 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl protected boolean internalCancel(String appName, String id, boolean isReplication) { logCancelation(appName, id, isReplication); publishEurekaInstanceCanceledEvent(appName, id, isReplication); - return superInternalCancel(appName, id, isReplication); - } - - protected boolean superInternalCancel(String appName, String id, - boolean isReplication) { return super.internalCancel(appName, id, isReplication); } - protected void superRegister(InstanceInfo info, boolean isReplication) { - super.register(info, isReplication); - } - private void logRegistration(InstanceInfo info, boolean isReplication, int instanceLeaseDuration) { if (log.isDebugEnabled()) { diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java index 4c32ce34..fa740240 100644 --- a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java @@ -1,10 +1,8 @@ package org.springframework.cloud.netflix.eureka.server; import static org.junit.Assert.*; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.*; +import static org.mockito.Matchers.isA; +import static org.mockito.Mockito.doAnswer; import java.util.LinkedList; import java.util.List; @@ -12,17 +10,18 @@ import java.util.List; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.SpyBean; import org.springframework.cloud.netflix.eureka.server.InstanceRegistryTest.Application; import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceCanceledEvent; import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRegisteredEvent; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -40,140 +39,110 @@ import com.netflix.eureka.registry.PeerAwareInstanceRegistry; + "cloud.netflix.eureka.server.InstanceRegistry=DEBUG"}) public class InstanceRegistryTest { - @SpyBean(PeerAwareInstanceRegistry.class) - private InstanceRegistry instanceRegistry; + private final List applicationEvents = new LinkedList<>(); - @Autowired - private Listener eurekaEventListener; + @SpyBean(PeerAwareInstanceRegistry.class) + private InstanceRegistry instanceRegistry; - @Before - public void setup() { - eurekaEventListener.getApplicationEvents().clear(); - } + @MockBean + private ApplicationListener + instanceRegisteredEventListenerMock; - @Test - public void testRegister() throws Exception { - // stubbing superclass method invocation - doNothing().when(instanceRegistry) - .superRegister(any(InstanceInfo.class), anyBoolean()); + @MockBean + private ApplicationListener + instanceCanceledEventListenerMock; - // creating instance info - LeaseInfo leaseInfo = getLeaseInfo(); - InstanceInfo instanceInfo = getInstanceInfo(leaseInfo); + @Before + public void setup() { + applicationEvents.clear(); + Answer applicationListenerAnswer = prepareListenerMockAnswer(); + doAnswer(applicationListenerAnswer).when(instanceRegisteredEventListenerMock) + .onApplicationEvent(isA(EurekaInstanceRegisteredEvent.class)); + doAnswer(applicationListenerAnswer).when(instanceCanceledEventListenerMock) + .onApplicationEvent(isA(EurekaInstanceCanceledEvent.class)); + } + - // calling tested method - instanceRegistry.register(instanceInfo, false); + @Test + public void testRegister() throws Exception { + // creating instance info + LeaseInfo leaseInfo = getLeaseInfo(); + InstanceInfo instanceInfo = getInstanceInfo(leaseInfo); + // calling tested method + instanceRegistry.register(instanceInfo, false); + // event of proper type is registered + assertEquals(1, applicationEvents.size()); + assertTrue(applicationEvents.get(0) instanceof EurekaInstanceRegisteredEvent); + // event details are correct + EurekaInstanceRegisteredEvent registeredEvent = + (EurekaInstanceRegisteredEvent) (applicationEvents.get(0)); + assertEquals(instanceInfo, registeredEvent.getInstanceInfo()); + assertEquals(leaseInfo.getDurationInSecs(), registeredEvent.getLeaseDuration()); + assertEquals(instanceRegistry, registeredEvent.getSource()); + assertFalse(registeredEvent.isReplication()); + } - // event of proper type is registered - assertEquals(1, eurekaEventListener.getApplicationEvents().size()); - assertTrue(eurekaEventListener.getApplicationEvents().get(0) - instanceof EurekaInstanceRegisteredEvent); + @Test + public void testDefaultLeaseDurationRegisterEvent() throws Exception { + // creating instance info + InstanceInfo instanceInfo = getInstanceInfo(null); + // calling tested method + instanceRegistry.register(instanceInfo, false); + // instance info duration is set to default + EurekaInstanceRegisteredEvent registeredEvent = + (EurekaInstanceRegisteredEvent) (applicationEvents.get(0)); + assertEquals(LeaseInfo.DEFAULT_LEASE_DURATION, + registeredEvent.getLeaseDuration()); + } - // event details are correct - EurekaInstanceRegisteredEvent registeredEvent = (EurekaInstanceRegisteredEvent) - (eurekaEventListener.getApplicationEvents().get(0)); - assertEquals(instanceInfo, registeredEvent.getInstanceInfo()); - assertEquals(leaseInfo.getDurationInSecs(), registeredEvent.getLeaseDuration()); - assertEquals(instanceRegistry, registeredEvent.getSource()); - assertFalse(registeredEvent.isReplication()); + @Test + public void testInternalCancel() throws Exception { + // calling tested method + instanceRegistry.internalCancel("my-app", "appId", false); + // event of proper type is registered + assertEquals(1, applicationEvents.size()); + assertTrue(applicationEvents.get(0) instanceof EurekaInstanceCanceledEvent); + // event details are correct + EurekaInstanceCanceledEvent registeredEvent = + (EurekaInstanceCanceledEvent) (applicationEvents.get(0)); + assertEquals("my-app", registeredEvent.getAppName()); + assertEquals("appId", registeredEvent.getServerId()); + assertEquals(instanceRegistry, registeredEvent.getSource()); + assertFalse(registeredEvent.isReplication()); + } - // superclass method wrapper was successfully invoked - verify(instanceRegistry).superRegister(instanceInfo, false); - } + @Configuration + @EnableAutoConfiguration + @EnableEurekaServer + protected static class Application { + public static void main(String[] args) { + new SpringApplicationBuilder(Application.class).run(args); + } + } - @Test - public void testDefaultLeaseDurationRegisterEvent() throws Exception { - // stubbing superclass method invocation - doNothing().when(instanceRegistry) - .superRegister(any(InstanceInfo.class), anyBoolean()); + private LeaseInfo getLeaseInfo() { + LeaseInfo.Builder leaseBuilder = LeaseInfo.Builder.newBuilder(); + leaseBuilder.setRenewalIntervalInSecs(10); + leaseBuilder.setDurationInSecs(15); + return leaseBuilder.build(); + } - // creating instance info - InstanceInfo instanceInfo = getInstanceInfo(null); + private InstanceInfo getInstanceInfo(LeaseInfo leaseInfo) { + InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder(); + builder.setAppName("my-app-name"); + builder.setHostName("my-host-name"); + builder.setPort(8008); + builder.setLeaseInfo(leaseInfo); + return builder.build(); + } - // calling tested method - instanceRegistry.register(instanceInfo, false); - - // instance info duration is set to default - EurekaInstanceRegisteredEvent registeredEvent = (EurekaInstanceRegisteredEvent) - (eurekaEventListener.getApplicationEvents().get(0)); - assertEquals(LeaseInfo.DEFAULT_LEASE_DURATION, registeredEvent.getLeaseDuration()); - } - - @Test - public void testInternalCancel() throws Exception { - // stubbing superclass method invocation - doReturn(Boolean.TRUE).when(instanceRegistry) - .superInternalCancel(anyString(), anyString(), anyBoolean()); - - // calling tested method - boolean cancellationResult = instanceRegistry - .internalCancel("my-app", "appId", false); - - // event of proper type is registered - assertEquals(1, eurekaEventListener.getApplicationEvents().size()); - assertTrue(eurekaEventListener.getApplicationEvents().get(0) - instanceof EurekaInstanceCanceledEvent); - - // event details are correct - EurekaInstanceCanceledEvent registeredEvent = (EurekaInstanceCanceledEvent) - (eurekaEventListener.getApplicationEvents().get(0)); - assertEquals("my-app", registeredEvent.getAppName()); - assertEquals("appId", registeredEvent.getServerId()); - assertEquals(instanceRegistry, registeredEvent.getSource()); - assertFalse(registeredEvent.isReplication()); - - // superclass method wrapper was successfully invoked - verify(instanceRegistry).superInternalCancel("my-app", "appId", false); - assertTrue(cancellationResult); - } - - @Configuration - @EnableAutoConfiguration - @EnableEurekaServer - protected static class Application { - - public static void main(String[] args) { - new SpringApplicationBuilder(Application.class) - .properties("spring.application.name=eureka").run(args); - } - - @Bean - public Listener eurekaEventsListener() { - return new Listener(); - } - } - - private LeaseInfo getLeaseInfo() { - LeaseInfo.Builder leaseBuilder = LeaseInfo.Builder.newBuilder(); - leaseBuilder.setRenewalIntervalInSecs(10); - leaseBuilder.setDurationInSecs(15); - return leaseBuilder.build(); - } - - - private InstanceInfo getInstanceInfo(LeaseInfo leaseInfo) { - InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder(); - builder.setAppName("my-app-name"); - builder.setHostName("my-host-name"); - builder.setPort(8008); - builder.setLeaseInfo(leaseInfo); - return builder.build(); - } - - private static class Listener implements ApplicationListener { - - private final List applicationEvents = new LinkedList<>(); - - @Override - public void onApplicationEvent(ApplicationEvent event) { - if (event instanceof EurekaInstanceCanceledEvent || - event instanceof EurekaInstanceRegisteredEvent) { - applicationEvents.add(event); - } - } - - public List getApplicationEvents() { - return applicationEvents; - } - } + private Answer prepareListenerMockAnswer() { + return new Answer() { + @Override + public Object answer(InvocationOnMock invocation) throws Throwable { + return applicationEvents + .add((ApplicationEvent) invocation.getArguments()[0]); + } + }; + } } \ No newline at end of file From c8829f2aa4ffac27772c4e960ced51a582f38d00 Mon Sep 17 00:00:00 2001 From: Max Ishchenko Date: Tue, 11 Oct 2016 17:19:33 +0300 Subject: [PATCH 11/24] Prevent double url encoding for secure ribbon urls (#1389) Secure ribbon urls were forced to use https scheme via UriComponentsBuilder, that was created from original uri. This transformation url encoded previously encoded url parts that were used to create builder. This was introduced in c883495. This change fixes double url encoding using RibbonUtils.updateToHttpsIfNeeded that fixes double escaping case and corner case with '+' in url as well. Fixes gh-1382 --- .../ribbon/RibbonLoadBalancerClient.java | 9 +++---- .../ribbon/RibbonLoadBalancerClientTests.java | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+), 5 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 4d00a9fb..c9261db5 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 @@ -52,11 +52,10 @@ public class RibbonLoadBalancerClient implements LoadBalancerClient { RibbonLoadBalancerContext context = this.clientFactory .getLoadBalancerContext(serviceId); Server server = new Server(instance.getHost(), instance.getPort()); - boolean secure = isSecure(server, serviceId); - URI uri = original; - if (secure) { - uri = UriComponentsBuilder.fromUri(uri).scheme("https").build().toUri(); - } + IClientConfig clientConfig = clientFactory.getClientConfig(serviceId); + ServerIntrospector serverIntrospector = serverIntrospector(serviceId); + URI uri = RibbonUtils.updateToHttpsIfNeeded(original, clientConfig, + serverIntrospector, server); return context.reconstructURIWithServer(server, uri); } 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 e224a134..f2e540cd 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 @@ -38,6 +38,7 @@ import com.netflix.loadbalancer.Server; import com.netflix.loadbalancer.ServerStats; import lombok.SneakyThrows; +import org.springframework.web.util.DefaultUriTemplateHandler; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; @@ -107,6 +108,31 @@ public class RibbonLoadBalancerClientTests { assertEquals(server.getPort(), uri.getPort()); } + @Test + public void testReconstructSecureUriWithSpecialCharsPath() { + testReconstructUriWithPath("https", "/foo=|"); + } + + @Test + public void testReconstructUnsecureUriWithSpecialCharsPath() { + testReconstructUriWithPath("http", "/foo=|"); + } + + private void testReconstructUriWithPath(String scheme, String path) { + RibbonServer server = getRibbonServer(); + IClientConfig config = mock(IClientConfig.class); + when(config.get(CommonClientConfigKey.IsSecure)).thenReturn(true); + when(clientFactory.getClientConfig(server.getServiceId())).thenReturn(config); + + RibbonLoadBalancerClient client = getRibbonLoadBalancerClient(server); + ServiceInstance serviceInstance = client.choose(server.getServiceId()); + + URI expanded = new DefaultUriTemplateHandler() + .expand(scheme + "://" + server.getServiceId() + path); + URI reconstructed = client.reconstructURI(serviceInstance, expanded); + assertEquals(expanded.getPath(), reconstructed.getPath()); + } + @Test @SneakyThrows public void testReconstructUriWithSecureClientConfig() { From aa160940df8901bde2d30ad4ac48e868e765e939 Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Tue, 11 Oct 2016 10:25:02 -0600 Subject: [PATCH 12/24] import order --- .../cloud/netflix/ribbon/RibbonLoadBalancerClientTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 f2e540cd..905cc6ac 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 @@ -29,6 +29,7 @@ import org.mockito.MockitoAnnotations; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest; import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.RibbonServer; +import org.springframework.web.util.DefaultUriTemplateHandler; import com.netflix.client.config.CommonClientConfigKey; import com.netflix.client.config.IClientConfig; @@ -38,7 +39,6 @@ import com.netflix.loadbalancer.Server; import com.netflix.loadbalancer.ServerStats; import lombok.SneakyThrows; -import org.springframework.web.util.DefaultUriTemplateHandler; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; From 5a127d07002daa6e7cb8ef8d4e9ce302aa49e84c Mon Sep 17 00:00:00 2001 From: mg Date: Sun, 2 Oct 2016 13:44:51 -0500 Subject: [PATCH 13/24] Warning for GC Overhead Limit Reached with servo. Fixes gh-947 --- docs/src/main/asciidoc/spring-cloud-netflix.adoc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/src/main/asciidoc/spring-cloud-netflix.adoc b/docs/src/main/asciidoc/spring-cloud-netflix.adoc index 1194d049..13d3d4b0 100644 --- a/docs/src/main/asciidoc/spring-cloud-netflix.adoc +++ b/docs/src/main/asciidoc/spring-cloud-netflix.adoc @@ -1758,6 +1758,18 @@ If Spring AOP is enabled and `org.aspectj:aspectjweaver` is present on your runt 3. URI, sanitized for Atlas 4. Client name +WARNING: Avoid using hardcoded url parameters within `RestTemplate`. When targeting dynamic endpoints use URL variables. This will avoid potential "GC Overhead Limit Reached" issues where `ServoMonitorCache` treats each url as a unique key. + +[source,java,indent=0] +---- +// recommended +String orderid = "1"; +restTemplate.getForObject("http://testeurekabrixtonclient/orders/{orderid}", String.class, orderid) + +// avoid +restTemplate.getForObject("http://testeurekabrixtonclient/orders/1", String.class) +---- + [[netflix-metrics-spectator]] === Metrics Collection: Spectator From 18c4bc060b2b3c19f1ce9b0b1d6f3f1b6cbf85dd Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Tue, 11 Oct 2016 13:41:31 -0400 Subject: [PATCH 14/24] Upgrade hystrix 1.5.6 (#1388) Fixes gh-1374 --- .../zuul/filters/pre/FormBodyWrapperFilter.java | 13 ++++++------- spring-cloud-netflix-dependencies/pom.xml | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java index 22681762..500ee5a2 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre/FormBodyWrapperFilter.java @@ -22,16 +22,14 @@ import java.io.OutputStream; import java.lang.reflect.Field; import java.util.HashSet; import java.util.List; -import java.util.Map.Entry; import java.util.Set; +import java.util.Map.Entry; import javax.servlet.ServletInputStream; import javax.servlet.ServletRequest; import javax.servlet.ServletRequestWrapper; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.Part; -import org.apache.commons.lang3.StringUtils; import org.springframework.core.io.InputStreamResource; import org.springframework.core.io.Resource; import org.springframework.http.HttpEntity; @@ -44,6 +42,7 @@ import org.springframework.util.Assert; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.ReflectionUtils; +import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartRequest; import org.springframework.web.servlet.DispatcherServlet; @@ -65,7 +64,7 @@ public class FormBodyWrapperFilter extends ZuulFilter { this.requestField = ReflectionUtils.findField(HttpServletRequestWrapper.class, "req", HttpServletRequest.class); this.servletRequestField = ReflectionUtils.findField(ServletRequestWrapper.class, - "request", ServletRequest.class); + "request", ServletRequest.class); Assert.notNull(this.requestField, "HttpServletRequestWrapper.req field not found"); Assert.notNull(this.servletRequestField, @@ -121,7 +120,7 @@ public class FormBodyWrapperFilter extends ZuulFilter { .getField(this.requestField, request); wrapper = new FormBodyRequestWrapper(wrapped); ReflectionUtils.setField(this.requestField, request, wrapper); - if(request instanceof ServletRequestWrapper) { + if (request instanceof ServletRequestWrapper) { ReflectionUtils.setField(this.servletRequestField, request, wrapper); } } @@ -170,7 +169,7 @@ public class FormBodyWrapperFilter extends ZuulFilter { } return this.contentLength; } - + @Override public long getContentLengthLong() { return getContentLength(); @@ -233,7 +232,7 @@ public class FormBodyWrapperFilter extends ZuulFilter { Set result = new HashSet<>(); String query = this.request.getQueryString(); if (query != null) { - for (String value : StringUtils.split(query, "&")) { + for (String value : StringUtils.tokenizeToStringArray(query, "&")) { if (value.contains("=")) { value = value.substring(0, value.indexOf("=")); } diff --git a/spring-cloud-netflix-dependencies/pom.xml b/spring-cloud-netflix-dependencies/pom.xml index 99e3cb2d..094bee0e 100644 --- a/spring-cloud-netflix-dependencies/pom.xml +++ b/spring-cloud-netflix-dependencies/pom.xml @@ -17,7 +17,7 @@ 0.7.4 1.4.11 9.3.1 - 1.5.5 + 1.5.6 2.2.0 0.10.1 1.2.2 From bdf2f25259b9207a4053235f3c95132fc547afe8 Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Tue, 11 Oct 2016 14:27:47 -0400 Subject: [PATCH 15/24] Fixes #1306 --- spring-cloud-netflix-dependencies/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-cloud-netflix-dependencies/pom.xml b/spring-cloud-netflix-dependencies/pom.xml index 094bee0e..8d0a85da 100644 --- a/spring-cloud-netflix-dependencies/pom.xml +++ b/spring-cloud-netflix-dependencies/pom.xml @@ -20,7 +20,7 @@ 1.5.6 2.2.0 0.10.1 - 1.2.2 + 1.3.0 1.1.10 1.7 1.0.0 From 4aaa7d0555baa0e8ebc5f19238eb0cfd735b4f65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20S=C5=82ota?= Date: Tue, 11 Oct 2016 21:46:25 +0200 Subject: [PATCH 16/24] InstanceRegistry class refactor + renew method test #1376 --- .../eureka/server/InstanceRegistry.java | 67 ++++++++---------- .../eureka/server/InstanceRegistryTest.java | 68 +++++++++++++++---- 2 files changed, 81 insertions(+), 54 deletions(-) diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java index 69fe52ba..c1ba8b25 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java @@ -36,6 +36,7 @@ import com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl; import com.netflix.eureka.resources.ServerCodecs; import lombok.extern.apachecommons.CommonsLog; +import org.springframework.context.ApplicationEvent; /** * @author Spencer Gibb @@ -79,33 +80,27 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl @Override public void register(InstanceInfo info, int leaseDuration, boolean isReplication) { - logRegistration(info, isReplication, leaseDuration); - publishEurekaInstanceRegisteredEvent(info, leaseDuration, isReplication); + handleRegistration(info, leaseDuration, isReplication); super.register(info, leaseDuration, isReplication); } @Override public void register(final InstanceInfo info, final boolean isReplication) { - final int instanceLeaseDuration = resolveInstanceLeaseDuration(info); - logRegistration(info, isReplication, instanceLeaseDuration); - publishEurekaInstanceRegisteredEvent(info, instanceLeaseDuration, isReplication); + handleRegistration(info, resolveInstanceLeaseDuration(info), isReplication); super.register(info, isReplication); } @Override public boolean cancel(String appName, String serverId, boolean isReplication) { - logCancelation(appName, serverId, isReplication); - publishEurekaInstanceCanceledEvent(appName, serverId, isReplication); + handleCancelation(appName, serverId, isReplication); return super.cancel(appName, serverId, isReplication); } @Override public boolean renew(final String appName, final String serverId, boolean isReplication) { - if (log.isDebugEnabled()) { - log.debug("renew " + appName + " serverId " + serverId + ", isReplication {}" - + isReplication); - } + log("renew " + appName + " serverId " + serverId + ", isReplication {}" + + isReplication); List applications = getSortedApplications(); for (Application input : applications) { if (input.getName().equals(appName)) { @@ -116,8 +111,8 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl break; } } - this.ctxt.publishEvent(new EurekaInstanceRenewedEvent(this, appName, - serverId, instance, isReplication)); + publishEvent(new EurekaInstanceRenewedEvent(this, appName, serverId, + instance, isReplication)); break; } } @@ -126,38 +121,32 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl @Override protected boolean internalCancel(String appName, String id, boolean isReplication) { - logCancelation(appName, id, isReplication); - publishEurekaInstanceCanceledEvent(appName, id, isReplication); + handleCancelation(appName, id, isReplication); return super.internalCancel(appName, id, isReplication); } - private void logRegistration(InstanceInfo info, boolean isReplication, - int instanceLeaseDuration) { - if (log.isDebugEnabled()) { - log.debug("register " + info.getAppName() + ", vip " + info.getVIPAddress() - + ", leaseDuration " + instanceLeaseDuration + ", isReplication " - + isReplication); - } + private void handleCancelation(String appName, String id, boolean isReplication) { + log("cancel " + appName + ", serverId " + id + ", isReplication " + isReplication); + publishEvent(new EurekaInstanceCanceledEvent(this, appName, id, isReplication)); } - private void logCancelation(String appName, String serverId, boolean isReplication) { - if (log.isDebugEnabled()) { - log.debug("cancel " + appName + " serverId " + serverId + ", isReplication " - + isReplication); - } - } - - private void publishEurekaInstanceRegisteredEvent(InstanceInfo info, - int leaseDuration, boolean isReplication) { - // TODO: what to publish from info (whole object?) - this.ctxt.publishEvent(new EurekaInstanceRegisteredEvent(this, info, - leaseDuration, isReplication)); - } - - private void publishEurekaInstanceCanceledEvent(String appName, String serverId, + private void handleRegistration(InstanceInfo info, int leaseDuration, boolean isReplication) { - this.ctxt.publishEvent( - new EurekaInstanceCanceledEvent(this, appName, serverId, isReplication)); + log("register " + info.getAppName() + ", vip " + info.getVIPAddress() + + ", leaseDuration " + leaseDuration + ", isReplication " + + isReplication); + publishEvent(new EurekaInstanceRegisteredEvent(this, info, leaseDuration, + isReplication)); + } + + private void log(String message) { + if (log.isDebugEnabled()) { + log.debug(message); + } + } + + private void publishEvent(ApplicationEvent applicationEvent) { + this.ctxt.publishEvent(applicationEvent); } private int resolveInstanceLeaseDuration(final InstanceInfo info) { diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java index fa740240..9689e779 100644 --- a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryTest.java @@ -3,10 +3,13 @@ package org.springframework.cloud.netflix.eureka.server; import static org.junit.Assert.*; import static org.mockito.Matchers.isA; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; +import java.util.ArrayList; import java.util.LinkedList; import java.util.List; +import com.netflix.discovery.shared.Application; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -17,9 +20,10 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.SpyBean; -import org.springframework.cloud.netflix.eureka.server.InstanceRegistryTest.Application; +import org.springframework.cloud.netflix.eureka.server.InstanceRegistryTest.TestApplication; import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceCanceledEvent; import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRegisteredEvent; +import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRenewedEvent; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Configuration; @@ -33,13 +37,15 @@ import com.netflix.eureka.registry.PeerAwareInstanceRegistry; * @author Bartlomiej Slota */ @RunWith(SpringJUnit4ClassRunner.class) -@SpringBootTest(classes = Application.class, +@SpringBootTest(classes = TestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, value = {"spring.application.name=eureka", "logging.level.org.springframework." + "cloud.netflix.eureka.server.InstanceRegistry=DEBUG"}) public class InstanceRegistryTest { private final List applicationEvents = new LinkedList<>(); + private static final String APP_NAME = "MY-APP-NAME"; + private static final String HOST_NAME = "my-host-name"; @SpyBean(PeerAwareInstanceRegistry.class) private InstanceRegistry instanceRegistry; @@ -52,6 +58,9 @@ public class InstanceRegistryTest { private ApplicationListener instanceCanceledEventListenerMock; + @MockBean + private ApplicationListener instanceRenewedEventListener; + @Before public void setup() { applicationEvents.clear(); @@ -60,21 +69,23 @@ public class InstanceRegistryTest { .onApplicationEvent(isA(EurekaInstanceRegisteredEvent.class)); doAnswer(applicationListenerAnswer).when(instanceCanceledEventListenerMock) .onApplicationEvent(isA(EurekaInstanceCanceledEvent.class)); + doAnswer(applicationListenerAnswer).when(instanceRenewedEventListener) + .onApplicationEvent(isA(EurekaInstanceRenewedEvent.class)); } @Test public void testRegister() throws Exception { // creating instance info - LeaseInfo leaseInfo = getLeaseInfo(); - InstanceInfo instanceInfo = getInstanceInfo(leaseInfo); + final LeaseInfo leaseInfo = getLeaseInfo(); + final InstanceInfo instanceInfo = getInstanceInfo(leaseInfo); // calling tested method instanceRegistry.register(instanceInfo, false); // event of proper type is registered assertEquals(1, applicationEvents.size()); assertTrue(applicationEvents.get(0) instanceof EurekaInstanceRegisteredEvent); // event details are correct - EurekaInstanceRegisteredEvent registeredEvent = + final EurekaInstanceRegisteredEvent registeredEvent = (EurekaInstanceRegisteredEvent) (applicationEvents.get(0)); assertEquals(instanceInfo, registeredEvent.getInstanceInfo()); assertEquals(leaseInfo.getDurationInSecs(), registeredEvent.getLeaseDuration()); @@ -85,11 +96,11 @@ public class InstanceRegistryTest { @Test public void testDefaultLeaseDurationRegisterEvent() throws Exception { // creating instance info - InstanceInfo instanceInfo = getInstanceInfo(null); + final InstanceInfo instanceInfo = getInstanceInfo(null); // calling tested method instanceRegistry.register(instanceInfo, false); // instance info duration is set to default - EurekaInstanceRegisteredEvent registeredEvent = + final EurekaInstanceRegisteredEvent registeredEvent = (EurekaInstanceRegisteredEvent) (applicationEvents.get(0)); assertEquals(LeaseInfo.DEFAULT_LEASE_DURATION, registeredEvent.getLeaseDuration()); @@ -98,25 +109,52 @@ public class InstanceRegistryTest { @Test public void testInternalCancel() throws Exception { // calling tested method - instanceRegistry.internalCancel("my-app", "appId", false); + instanceRegistry.internalCancel(APP_NAME, HOST_NAME, false); // event of proper type is registered assertEquals(1, applicationEvents.size()); assertTrue(applicationEvents.get(0) instanceof EurekaInstanceCanceledEvent); // event details are correct - EurekaInstanceCanceledEvent registeredEvent = + final EurekaInstanceCanceledEvent registeredEvent = (EurekaInstanceCanceledEvent) (applicationEvents.get(0)); - assertEquals("my-app", registeredEvent.getAppName()); - assertEquals("appId", registeredEvent.getServerId()); + assertEquals(APP_NAME, registeredEvent.getAppName()); + assertEquals(HOST_NAME, registeredEvent.getServerId()); assertEquals(instanceRegistry, registeredEvent.getSource()); assertFalse(registeredEvent.isReplication()); } + @Test + public void testRenew() throws Exception { + // creating application list + final LeaseInfo leaseInfo = getLeaseInfo(); + final InstanceInfo instanceInfo = getInstanceInfo(leaseInfo); + final List instances = new ArrayList<>(); + instances.add(instanceInfo); + final Application application = new Application(APP_NAME, instances); + final List applications = new ArrayList<>(); + applications.add(application); + // stubbing applications list + doReturn(applications).when(instanceRegistry).getSortedApplications(); + // calling tested method + instanceRegistry.renew(APP_NAME, HOST_NAME, false); + // event of proper type is registered + assertEquals(1, applicationEvents.size()); + assertTrue(applicationEvents.get(0) instanceof EurekaInstanceRenewedEvent); + // event details are correct + final EurekaInstanceRenewedEvent registeredEvent = (EurekaInstanceRenewedEvent) + (applicationEvents.get(0)); + assertEquals(APP_NAME, registeredEvent.getAppName()); + assertEquals(HOST_NAME, registeredEvent.getServerId()); + assertEquals(instanceRegistry, registeredEvent.getSource()); + assertEquals(instanceInfo, registeredEvent.getInstanceInfo()); + assertFalse(registeredEvent.isReplication()); + } + @Configuration @EnableAutoConfiguration @EnableEurekaServer - protected static class Application { + protected static class TestApplication { public static void main(String[] args) { - new SpringApplicationBuilder(Application.class).run(args); + new SpringApplicationBuilder(TestApplication.class).run(args); } } @@ -129,8 +167,8 @@ public class InstanceRegistryTest { private InstanceInfo getInstanceInfo(LeaseInfo leaseInfo) { InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder(); - builder.setAppName("my-app-name"); - builder.setHostName("my-host-name"); + builder.setAppName(APP_NAME); + builder.setHostName(HOST_NAME); builder.setPort(8008); builder.setLeaseInfo(leaseInfo); return builder.build(); From e94c35d331cdbf6f71b4eae2fde9b62779d0553b Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 13 Oct 2016 10:02:15 +0100 Subject: [PATCH 17/24] Exclude aws jars from eureka client by default Saves about 5MB in the final executable jar, and it should be optional for Spring Cloud users. --- spring-cloud-netflix-dependencies/pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spring-cloud-netflix-dependencies/pom.xml b/spring-cloud-netflix-dependencies/pom.xml index 8d0a85da..c991136a 100644 --- a/spring-cloud-netflix-dependencies/pom.xml +++ b/spring-cloud-netflix-dependencies/pom.xml @@ -270,6 +270,10 @@ jackson-dataformat-xml com.fasterxml.jackson.dataformat + + * + com.amazonaws + From acb12ea7d44ac0a2ebc8ac7c662d287b8b3038f5 Mon Sep 17 00:00:00 2001 From: Alena Date: Tue, 13 Sep 2016 18:40:08 +0300 Subject: [PATCH 18/24] Support DELETE method body for SimpleHostRoutingFilter fixes gh-1329 --- .../route/SimpleHostRoutingFilter.java | 63 ++++++++++++------- .../route/SimpleHostRoutingFilterTests.java | 18 ++++++ 2 files changed, 58 insertions(+), 23 deletions(-) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java index cdefd022..a76a5dd5 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilter.java @@ -63,6 +63,7 @@ import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.message.BasicHeader; +import org.apache.http.message.BasicHttpEntityEnclosingRequest; import org.apache.http.message.BasicHttpRequest; import org.apache.http.protocol.HttpContext; import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper; @@ -271,34 +272,13 @@ public class SimpleHostRoutingFilter extends ZuulFilter { URL host = RequestContext.getCurrentContext().getRouteHost(); HttpHost httpHost = getHttpHost(host); uri = StringUtils.cleanPath((host.getPath() + uri).replaceAll("/{2,}", "/")); - HttpRequest httpRequest; int contentLength = request.getContentLength(); InputStreamEntity entity = new InputStreamEntity(requestEntity, contentLength, request.getContentType() != null ? ContentType.create(request.getContentType()) : null); - switch (verb.toUpperCase()) { - case "POST": - HttpPost httpPost = new HttpPost(uri + this.helper.getQueryString(params)); - httpRequest = httpPost; - httpPost.setEntity(entity); - break; - case "PUT": - HttpPut httpPut = new HttpPut(uri + this.helper.getQueryString(params)); - httpRequest = httpPut; - httpPut.setEntity(entity); - break; - case "PATCH": - HttpPatch httpPatch = new HttpPatch(uri + this.helper.getQueryString(params)); - httpRequest = httpPatch; - httpPatch.setEntity(entity); - break; - default: - httpRequest = new BasicHttpRequest(verb, - uri + this.helper.getQueryString(params)); - log.debug(uri + this.helper.getQueryString(params)); - } + + HttpRequest httpRequest = buildHttpRequest(verb, uri, entity, headers, params); try { - httpRequest.setHeaders(convertHeaders(headers)); log.debug(httpHost.getHostName() + " " + httpHost.getPort() + " " + httpHost.getSchemeName()); HttpResponse zuulResponse = forwardRequest(httpclient, httpHost, httpRequest); @@ -314,6 +294,43 @@ public class SimpleHostRoutingFilter extends ZuulFilter { } } + protected HttpRequest buildHttpRequest (String verb, String uri, InputStreamEntity entity, + MultiValueMap headers, MultiValueMap params) + { + HttpRequest httpRequest; + + switch (verb.toUpperCase()) { + case "POST": + HttpPost httpPost = new HttpPost(uri + this.helper.getQueryString(params)); + httpRequest = httpPost; + httpPost.setEntity(entity); + break; + case "PUT": + HttpPut httpPut = new HttpPut(uri + this.helper.getQueryString(params)); + httpRequest = httpPut; + httpPut.setEntity(entity); + break; + case "PATCH": + HttpPatch httpPatch = new HttpPatch(uri + this.helper.getQueryString(params)); + httpRequest = httpPatch; + httpPatch.setEntity(entity); + break; + case "DELETE": + BasicHttpEntityEnclosingRequest entityRequest = new BasicHttpEntityEnclosingRequest(verb, + uri + this.helper.getQueryString(params)); + httpRequest = entityRequest; + entityRequest.setEntity(entity); + break; + default: + httpRequest = new BasicHttpRequest(verb, + uri + this.helper.getQueryString(params)); + log.debug(uri + this.helper.getQueryString(params)); + } + + httpRequest.setHeaders(convertHeaders(headers)); + return httpRequest; + } + private MultiValueMap revertHeaders(Header[] headers) { MultiValueMap map = new LinkedMultiValueMap(); for (Header header : headers) { diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterTests.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterTests.java index 7275e36d..faf5871e 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterTests.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/SimpleHostRoutingFilterTests.java @@ -16,6 +16,11 @@ package org.springframework.cloud.netflix.zuul.filters.route; +import java.io.ByteArrayInputStream; + +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpRequest; +import org.apache.http.entity.InputStreamEntity; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.junit.After; import org.junit.Test; @@ -26,6 +31,7 @@ import org.springframework.cloud.netflix.zuul.filters.ZuulProperties; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.util.LinkedMultiValueMap; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -80,6 +86,18 @@ public class SimpleHostRoutingFilterTests { assertEquals(20, connMgr.getDefaultMaxPerRoute()); } + @Test + public void deleteRequestBuiltWithBody() { + setupContext(); + InputStreamEntity inputStreamEntity = new InputStreamEntity(new ByteArrayInputStream(new byte[]{1})); + HttpRequest httpRequest = getFilter().buildHttpRequest("DELETE", "uri", inputStreamEntity, + new LinkedMultiValueMap(), new LinkedMultiValueMap()); + + assertTrue(httpRequest instanceof HttpEntityEnclosingRequest); + HttpEntityEnclosingRequest httpEntityEnclosingRequest = (HttpEntityEnclosingRequest) httpRequest; + assertTrue(httpEntityEnclosingRequest.getEntity() != null); + } + private void setupContext() { this.context.register(PropertyPlaceholderAutoConfiguration.class, TestConfiguration.class); From acb9e5ebdf1daec606c30504442eb18adafdece3 Mon Sep 17 00:00:00 2001 From: Gregor Zurowski Date: Thu, 13 Oct 2016 22:08:28 +0200 Subject: [PATCH 19/24] Fix formatting (#1397) Signed-off-by: Gregor Zurowski --- docs/src/main/asciidoc/spring-cloud-netflix.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/main/asciidoc/spring-cloud-netflix.adoc b/docs/src/main/asciidoc/spring-cloud-netflix.adoc index 13d3d4b0..bd65af99 100644 --- a/docs/src/main/asciidoc/spring-cloud-netflix.adoc +++ b/docs/src/main/asciidoc/spring-cloud-netflix.adoc @@ -1387,7 +1387,7 @@ path rendering the `users` path unreachable. === Zuul Http Client The default HTTP client used by zuul is now backed by the Apache HTTP Client instead of the -deprecated Ribbon `RestClient. To use `RestClient` or to use the `okhttp3.OkHttpClient` set +deprecated Ribbon `RestClient`. To use `RestClient` or to use the `okhttp3.OkHttpClient` set `ribbon.restclient.enabled=true` or `ribbon.okhttp.enabled=true` respectively. === Cookies and Sensitive Headers From 90d6490feae93e54cf332400a0275f0d0b4bc76e Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Tue, 18 Oct 2016 09:44:57 -0400 Subject: [PATCH 20/24] Version changes for the release --- docs/pom.xml | 2 +- pom.xml | 10 +++++----- spring-cloud-netflix-core/pom.xml | 2 +- spring-cloud-netflix-dependencies/pom.xml | 4 ++-- spring-cloud-netflix-eureka-client/pom.xml | 2 +- spring-cloud-netflix-eureka-server/pom.xml | 2 +- spring-cloud-netflix-hystrix-amqp/pom.xml | 2 +- spring-cloud-netflix-hystrix-dashboard/pom.xml | 2 +- spring-cloud-netflix-hystrix-stream/pom.xml | 2 +- spring-cloud-netflix-sidecar/pom.xml | 2 +- spring-cloud-netflix-spectator/pom.xml | 2 +- spring-cloud-netflix-turbine-stream/pom.xml | 2 +- spring-cloud-netflix-turbine/pom.xml | 2 +- spring-cloud-starter-archaius/pom.xml | 2 +- spring-cloud-starter-atlas/pom.xml | 2 +- spring-cloud-starter-eureka-server/pom.xml | 2 +- spring-cloud-starter-eureka/pom.xml | 2 +- spring-cloud-starter-feign/pom.xml | 2 +- spring-cloud-starter-hystrix-dashboard/pom.xml | 2 +- spring-cloud-starter-hystrix/pom.xml | 2 +- spring-cloud-starter-ribbon/pom.xml | 2 +- spring-cloud-starter-spectator/pom.xml | 2 +- spring-cloud-starter-turbine-amqp/pom.xml | 2 +- spring-cloud-starter-turbine-stream/pom.xml | 2 +- spring-cloud-starter-turbine/pom.xml | 2 +- spring-cloud-starter-zuul/pom.xml | 2 +- 26 files changed, 31 insertions(+), 31 deletions(-) diff --git a/docs/pom.xml b/docs/pom.xml index 750a0699..56528e76 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE spring-cloud-netflix-docs pom diff --git a/pom.xml b/pom.xml index b0994d49..04d13a77 100644 --- a/pom.xml +++ b/pom.xml @@ -3,14 +3,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE pom Spring Cloud Netflix Spring Cloud Netflix org.springframework.cloud spring-cloud-build - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE @@ -24,9 +24,9 @@ ${basedir} 4.0.27.Final 2.7.3 - 1.1.4.BUILD-SNAPSHOT - 1.2.1.BUILD-SNAPSHOT - Brooklyn.BUILD-SNAPSHOT + 1.1.4.RELEASE + 1.2.1.RELEASE + Brooklyn.RELEASE 2.19.1 diff --git a/spring-cloud-netflix-core/pom.xml b/spring-cloud-netflix-core/pom.xml index 8f6985cc..614373d6 100644 --- a/spring-cloud-netflix-core/pom.xml +++ b/spring-cloud-netflix-core/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-netflix-core diff --git a/spring-cloud-netflix-dependencies/pom.xml b/spring-cloud-netflix-dependencies/pom.xml index c991136a..d32b336c 100644 --- a/spring-cloud-netflix-dependencies/pom.xml +++ b/spring-cloud-netflix-dependencies/pom.xml @@ -5,11 +5,11 @@ spring-cloud-dependencies-parent org.springframework.cloud - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE spring-cloud-netflix-dependencies - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE pom spring-cloud-netflix-dependencies Spring Cloud Netflix Dependencies diff --git a/spring-cloud-netflix-eureka-client/pom.xml b/spring-cloud-netflix-eureka-client/pom.xml index 6d6bdcd9..4dbde6ca 100644 --- a/spring-cloud-netflix-eureka-client/pom.xml +++ b/spring-cloud-netflix-eureka-client/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-netflix-eureka-client diff --git a/spring-cloud-netflix-eureka-server/pom.xml b/spring-cloud-netflix-eureka-server/pom.xml index 74b41f12..2d21c477 100644 --- a/spring-cloud-netflix-eureka-server/pom.xml +++ b/spring-cloud-netflix-eureka-server/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-netflix-eureka-server diff --git a/spring-cloud-netflix-hystrix-amqp/pom.xml b/spring-cloud-netflix-hystrix-amqp/pom.xml index b3dcd037..3801dd49 100644 --- a/spring-cloud-netflix-hystrix-amqp/pom.xml +++ b/spring-cloud-netflix-hystrix-amqp/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-netflix-hystrix-amqp diff --git a/spring-cloud-netflix-hystrix-dashboard/pom.xml b/spring-cloud-netflix-hystrix-dashboard/pom.xml index 64d5f719..9e89c9c2 100644 --- a/spring-cloud-netflix-hystrix-dashboard/pom.xml +++ b/spring-cloud-netflix-hystrix-dashboard/pom.xml @@ -8,7 +8,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. diff --git a/spring-cloud-netflix-hystrix-stream/pom.xml b/spring-cloud-netflix-hystrix-stream/pom.xml index dd4c8f51..8cd94ea6 100644 --- a/spring-cloud-netflix-hystrix-stream/pom.xml +++ b/spring-cloud-netflix-hystrix-stream/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-netflix-hystrix-stream diff --git a/spring-cloud-netflix-sidecar/pom.xml b/spring-cloud-netflix-sidecar/pom.xml index c39d4005..4394947f 100644 --- a/spring-cloud-netflix-sidecar/pom.xml +++ b/spring-cloud-netflix-sidecar/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-netflix-sidecar diff --git a/spring-cloud-netflix-spectator/pom.xml b/spring-cloud-netflix-spectator/pom.xml index 55715ac6..c6d409e5 100644 --- a/spring-cloud-netflix-spectator/pom.xml +++ b/spring-cloud-netflix-spectator/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-netflix-spectator diff --git a/spring-cloud-netflix-turbine-stream/pom.xml b/spring-cloud-netflix-turbine-stream/pom.xml index 7fdeef11..1af2a2e8 100644 --- a/spring-cloud-netflix-turbine-stream/pom.xml +++ b/spring-cloud-netflix-turbine-stream/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-netflix-turbine-stream diff --git a/spring-cloud-netflix-turbine/pom.xml b/spring-cloud-netflix-turbine/pom.xml index f4ba02b1..fd49df2b 100644 --- a/spring-cloud-netflix-turbine/pom.xml +++ b/spring-cloud-netflix-turbine/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-netflix-turbine diff --git a/spring-cloud-starter-archaius/pom.xml b/spring-cloud-starter-archaius/pom.xml index 29c05ed3..f6c37d86 100644 --- a/spring-cloud-starter-archaius/pom.xml +++ b/spring-cloud-starter-archaius/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-starter-archaius diff --git a/spring-cloud-starter-atlas/pom.xml b/spring-cloud-starter-atlas/pom.xml index ef07240e..6231e78f 100644 --- a/spring-cloud-starter-atlas/pom.xml +++ b/spring-cloud-starter-atlas/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-starter-atlas diff --git a/spring-cloud-starter-eureka-server/pom.xml b/spring-cloud-starter-eureka-server/pom.xml index 281d6840..1588ca49 100644 --- a/spring-cloud-starter-eureka-server/pom.xml +++ b/spring-cloud-starter-eureka-server/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-starter-eureka-server diff --git a/spring-cloud-starter-eureka/pom.xml b/spring-cloud-starter-eureka/pom.xml index 5db347ea..2afb3f61 100644 --- a/spring-cloud-starter-eureka/pom.xml +++ b/spring-cloud-starter-eureka/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-starter-eureka diff --git a/spring-cloud-starter-feign/pom.xml b/spring-cloud-starter-feign/pom.xml index cfced5bb..b94d7929 100644 --- a/spring-cloud-starter-feign/pom.xml +++ b/spring-cloud-starter-feign/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-starter-feign diff --git a/spring-cloud-starter-hystrix-dashboard/pom.xml b/spring-cloud-starter-hystrix-dashboard/pom.xml index ef126ed6..7a4c92d8 100644 --- a/spring-cloud-starter-hystrix-dashboard/pom.xml +++ b/spring-cloud-starter-hystrix-dashboard/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-starter-hystrix-dashboard diff --git a/spring-cloud-starter-hystrix/pom.xml b/spring-cloud-starter-hystrix/pom.xml index 220ad2e3..42383f04 100644 --- a/spring-cloud-starter-hystrix/pom.xml +++ b/spring-cloud-starter-hystrix/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-starter-hystrix diff --git a/spring-cloud-starter-ribbon/pom.xml b/spring-cloud-starter-ribbon/pom.xml index 533583c0..8b1d971d 100644 --- a/spring-cloud-starter-ribbon/pom.xml +++ b/spring-cloud-starter-ribbon/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-starter-ribbon diff --git a/spring-cloud-starter-spectator/pom.xml b/spring-cloud-starter-spectator/pom.xml index ee66b0eb..1db00804 100644 --- a/spring-cloud-starter-spectator/pom.xml +++ b/spring-cloud-starter-spectator/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-starter-spectator diff --git a/spring-cloud-starter-turbine-amqp/pom.xml b/spring-cloud-starter-turbine-amqp/pom.xml index 15e5a043..6f9633aa 100644 --- a/spring-cloud-starter-turbine-amqp/pom.xml +++ b/spring-cloud-starter-turbine-amqp/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-starter-turbine-amqp diff --git a/spring-cloud-starter-turbine-stream/pom.xml b/spring-cloud-starter-turbine-stream/pom.xml index ef45f833..290adf42 100644 --- a/spring-cloud-starter-turbine-stream/pom.xml +++ b/spring-cloud-starter-turbine-stream/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-starter-turbine-stream diff --git a/spring-cloud-starter-turbine/pom.xml b/spring-cloud-starter-turbine/pom.xml index 3639be91..7867a073 100644 --- a/spring-cloud-starter-turbine/pom.xml +++ b/spring-cloud-starter-turbine/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-starter-turbine diff --git a/spring-cloud-starter-zuul/pom.xml b/spring-cloud-starter-zuul/pom.xml index 8b664ac8..1490174e 100644 --- a/spring-cloud-starter-zuul/pom.xml +++ b/spring-cloud-starter-zuul/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.1.RELEASE .. spring-cloud-starter-zuul From 34775eb8dbf3500f33f9e12083f831435d7cf87a Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Tue, 18 Oct 2016 10:11:03 -0400 Subject: [PATCH 21/24] Revert "Version changes for the release" This reverts commit 90d6490feae93e54cf332400a0275f0d0b4bc76e. --- docs/pom.xml | 2 +- pom.xml | 10 +++++----- spring-cloud-netflix-core/pom.xml | 2 +- spring-cloud-netflix-dependencies/pom.xml | 4 ++-- spring-cloud-netflix-eureka-client/pom.xml | 2 +- spring-cloud-netflix-eureka-server/pom.xml | 2 +- spring-cloud-netflix-hystrix-amqp/pom.xml | 2 +- spring-cloud-netflix-hystrix-dashboard/pom.xml | 2 +- spring-cloud-netflix-hystrix-stream/pom.xml | 2 +- spring-cloud-netflix-sidecar/pom.xml | 2 +- spring-cloud-netflix-spectator/pom.xml | 2 +- spring-cloud-netflix-turbine-stream/pom.xml | 2 +- spring-cloud-netflix-turbine/pom.xml | 2 +- spring-cloud-starter-archaius/pom.xml | 2 +- spring-cloud-starter-atlas/pom.xml | 2 +- spring-cloud-starter-eureka-server/pom.xml | 2 +- spring-cloud-starter-eureka/pom.xml | 2 +- spring-cloud-starter-feign/pom.xml | 2 +- spring-cloud-starter-hystrix-dashboard/pom.xml | 2 +- spring-cloud-starter-hystrix/pom.xml | 2 +- spring-cloud-starter-ribbon/pom.xml | 2 +- spring-cloud-starter-spectator/pom.xml | 2 +- spring-cloud-starter-turbine-amqp/pom.xml | 2 +- spring-cloud-starter-turbine-stream/pom.xml | 2 +- spring-cloud-starter-turbine/pom.xml | 2 +- spring-cloud-starter-zuul/pom.xml | 2 +- 26 files changed, 31 insertions(+), 31 deletions(-) diff --git a/docs/pom.xml b/docs/pom.xml index 56528e76..750a0699 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT spring-cloud-netflix-docs pom diff --git a/pom.xml b/pom.xml index 04d13a77..b0994d49 100644 --- a/pom.xml +++ b/pom.xml @@ -3,14 +3,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT pom Spring Cloud Netflix Spring Cloud Netflix org.springframework.cloud spring-cloud-build - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT @@ -24,9 +24,9 @@ ${basedir} 4.0.27.Final 2.7.3 - 1.1.4.RELEASE - 1.2.1.RELEASE - Brooklyn.RELEASE + 1.1.4.BUILD-SNAPSHOT + 1.2.1.BUILD-SNAPSHOT + Brooklyn.BUILD-SNAPSHOT 2.19.1 diff --git a/spring-cloud-netflix-core/pom.xml b/spring-cloud-netflix-core/pom.xml index 614373d6..8f6985cc 100644 --- a/spring-cloud-netflix-core/pom.xml +++ b/spring-cloud-netflix-core/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-netflix-core diff --git a/spring-cloud-netflix-dependencies/pom.xml b/spring-cloud-netflix-dependencies/pom.xml index d32b336c..c991136a 100644 --- a/spring-cloud-netflix-dependencies/pom.xml +++ b/spring-cloud-netflix-dependencies/pom.xml @@ -5,11 +5,11 @@ spring-cloud-dependencies-parent org.springframework.cloud - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT spring-cloud-netflix-dependencies - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT pom spring-cloud-netflix-dependencies Spring Cloud Netflix Dependencies diff --git a/spring-cloud-netflix-eureka-client/pom.xml b/spring-cloud-netflix-eureka-client/pom.xml index 4dbde6ca..6d6bdcd9 100644 --- a/spring-cloud-netflix-eureka-client/pom.xml +++ b/spring-cloud-netflix-eureka-client/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-netflix-eureka-client diff --git a/spring-cloud-netflix-eureka-server/pom.xml b/spring-cloud-netflix-eureka-server/pom.xml index 2d21c477..74b41f12 100644 --- a/spring-cloud-netflix-eureka-server/pom.xml +++ b/spring-cloud-netflix-eureka-server/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-netflix-eureka-server diff --git a/spring-cloud-netflix-hystrix-amqp/pom.xml b/spring-cloud-netflix-hystrix-amqp/pom.xml index 3801dd49..b3dcd037 100644 --- a/spring-cloud-netflix-hystrix-amqp/pom.xml +++ b/spring-cloud-netflix-hystrix-amqp/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-netflix-hystrix-amqp diff --git a/spring-cloud-netflix-hystrix-dashboard/pom.xml b/spring-cloud-netflix-hystrix-dashboard/pom.xml index 9e89c9c2..64d5f719 100644 --- a/spring-cloud-netflix-hystrix-dashboard/pom.xml +++ b/spring-cloud-netflix-hystrix-dashboard/pom.xml @@ -8,7 +8,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. diff --git a/spring-cloud-netflix-hystrix-stream/pom.xml b/spring-cloud-netflix-hystrix-stream/pom.xml index 8cd94ea6..dd4c8f51 100644 --- a/spring-cloud-netflix-hystrix-stream/pom.xml +++ b/spring-cloud-netflix-hystrix-stream/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-netflix-hystrix-stream diff --git a/spring-cloud-netflix-sidecar/pom.xml b/spring-cloud-netflix-sidecar/pom.xml index 4394947f..c39d4005 100644 --- a/spring-cloud-netflix-sidecar/pom.xml +++ b/spring-cloud-netflix-sidecar/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-netflix-sidecar diff --git a/spring-cloud-netflix-spectator/pom.xml b/spring-cloud-netflix-spectator/pom.xml index c6d409e5..55715ac6 100644 --- a/spring-cloud-netflix-spectator/pom.xml +++ b/spring-cloud-netflix-spectator/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-netflix-spectator diff --git a/spring-cloud-netflix-turbine-stream/pom.xml b/spring-cloud-netflix-turbine-stream/pom.xml index 1af2a2e8..7fdeef11 100644 --- a/spring-cloud-netflix-turbine-stream/pom.xml +++ b/spring-cloud-netflix-turbine-stream/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-netflix-turbine-stream diff --git a/spring-cloud-netflix-turbine/pom.xml b/spring-cloud-netflix-turbine/pom.xml index fd49df2b..f4ba02b1 100644 --- a/spring-cloud-netflix-turbine/pom.xml +++ b/spring-cloud-netflix-turbine/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-netflix-turbine diff --git a/spring-cloud-starter-archaius/pom.xml b/spring-cloud-starter-archaius/pom.xml index f6c37d86..29c05ed3 100644 --- a/spring-cloud-starter-archaius/pom.xml +++ b/spring-cloud-starter-archaius/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-starter-archaius diff --git a/spring-cloud-starter-atlas/pom.xml b/spring-cloud-starter-atlas/pom.xml index 6231e78f..ef07240e 100644 --- a/spring-cloud-starter-atlas/pom.xml +++ b/spring-cloud-starter-atlas/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-starter-atlas diff --git a/spring-cloud-starter-eureka-server/pom.xml b/spring-cloud-starter-eureka-server/pom.xml index 1588ca49..281d6840 100644 --- a/spring-cloud-starter-eureka-server/pom.xml +++ b/spring-cloud-starter-eureka-server/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-starter-eureka-server diff --git a/spring-cloud-starter-eureka/pom.xml b/spring-cloud-starter-eureka/pom.xml index 2afb3f61..5db347ea 100644 --- a/spring-cloud-starter-eureka/pom.xml +++ b/spring-cloud-starter-eureka/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-starter-eureka diff --git a/spring-cloud-starter-feign/pom.xml b/spring-cloud-starter-feign/pom.xml index b94d7929..cfced5bb 100644 --- a/spring-cloud-starter-feign/pom.xml +++ b/spring-cloud-starter-feign/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-starter-feign diff --git a/spring-cloud-starter-hystrix-dashboard/pom.xml b/spring-cloud-starter-hystrix-dashboard/pom.xml index 7a4c92d8..ef126ed6 100644 --- a/spring-cloud-starter-hystrix-dashboard/pom.xml +++ b/spring-cloud-starter-hystrix-dashboard/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-starter-hystrix-dashboard diff --git a/spring-cloud-starter-hystrix/pom.xml b/spring-cloud-starter-hystrix/pom.xml index 42383f04..220ad2e3 100644 --- a/spring-cloud-starter-hystrix/pom.xml +++ b/spring-cloud-starter-hystrix/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-starter-hystrix diff --git a/spring-cloud-starter-ribbon/pom.xml b/spring-cloud-starter-ribbon/pom.xml index 8b1d971d..533583c0 100644 --- a/spring-cloud-starter-ribbon/pom.xml +++ b/spring-cloud-starter-ribbon/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-starter-ribbon diff --git a/spring-cloud-starter-spectator/pom.xml b/spring-cloud-starter-spectator/pom.xml index 1db00804..ee66b0eb 100644 --- a/spring-cloud-starter-spectator/pom.xml +++ b/spring-cloud-starter-spectator/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-starter-spectator diff --git a/spring-cloud-starter-turbine-amqp/pom.xml b/spring-cloud-starter-turbine-amqp/pom.xml index 6f9633aa..15e5a043 100644 --- a/spring-cloud-starter-turbine-amqp/pom.xml +++ b/spring-cloud-starter-turbine-amqp/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-starter-turbine-amqp diff --git a/spring-cloud-starter-turbine-stream/pom.xml b/spring-cloud-starter-turbine-stream/pom.xml index 290adf42..ef45f833 100644 --- a/spring-cloud-starter-turbine-stream/pom.xml +++ b/spring-cloud-starter-turbine-stream/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-starter-turbine-stream diff --git a/spring-cloud-starter-turbine/pom.xml b/spring-cloud-starter-turbine/pom.xml index 7867a073..3639be91 100644 --- a/spring-cloud-starter-turbine/pom.xml +++ b/spring-cloud-starter-turbine/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-starter-turbine diff --git a/spring-cloud-starter-zuul/pom.xml b/spring-cloud-starter-zuul/pom.xml index 1490174e..8b664ac8 100644 --- a/spring-cloud-starter-zuul/pom.xml +++ b/spring-cloud-starter-zuul/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.RELEASE + 1.2.1.BUILD-SNAPSHOT .. spring-cloud-starter-zuul From c9704d3c97ddb35e52dc987b35343511523eed69 Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Tue, 18 Oct 2016 10:16:01 -0400 Subject: [PATCH 22/24] Updating versions for next release --- docs/pom.xml | 2 +- pom.xml | 8 ++++---- spring-cloud-netflix-core/pom.xml | 2 +- spring-cloud-netflix-dependencies/pom.xml | 4 ++-- spring-cloud-netflix-eureka-client/pom.xml | 2 +- spring-cloud-netflix-eureka-server/pom.xml | 2 +- spring-cloud-netflix-hystrix-amqp/pom.xml | 2 +- spring-cloud-netflix-hystrix-dashboard/pom.xml | 2 +- spring-cloud-netflix-hystrix-stream/pom.xml | 2 +- spring-cloud-netflix-sidecar/pom.xml | 2 +- spring-cloud-netflix-spectator/pom.xml | 2 +- spring-cloud-netflix-turbine-stream/pom.xml | 2 +- spring-cloud-netflix-turbine/pom.xml | 2 +- spring-cloud-starter-archaius/pom.xml | 2 +- spring-cloud-starter-atlas/pom.xml | 2 +- spring-cloud-starter-eureka-server/pom.xml | 2 +- spring-cloud-starter-eureka/pom.xml | 2 +- spring-cloud-starter-feign/pom.xml | 2 +- spring-cloud-starter-hystrix-dashboard/pom.xml | 2 +- spring-cloud-starter-hystrix/pom.xml | 2 +- spring-cloud-starter-ribbon/pom.xml | 2 +- spring-cloud-starter-spectator/pom.xml | 2 +- spring-cloud-starter-turbine-amqp/pom.xml | 2 +- spring-cloud-starter-turbine-stream/pom.xml | 2 +- spring-cloud-starter-turbine/pom.xml | 2 +- spring-cloud-starter-zuul/pom.xml | 2 +- 26 files changed, 30 insertions(+), 30 deletions(-) diff --git a/docs/pom.xml b/docs/pom.xml index 750a0699..7225f151 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT spring-cloud-netflix-docs pom diff --git a/pom.xml b/pom.xml index b0994d49..ef239e18 100644 --- a/pom.xml +++ b/pom.xml @@ -3,14 +3,14 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT pom Spring Cloud Netflix Spring Cloud Netflix org.springframework.cloud spring-cloud-build - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT @@ -24,8 +24,8 @@ ${basedir} 4.0.27.Final 2.7.3 - 1.1.4.BUILD-SNAPSHOT - 1.2.1.BUILD-SNAPSHOT + 1.1.5.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT Brooklyn.BUILD-SNAPSHOT diff --git a/spring-cloud-netflix-core/pom.xml b/spring-cloud-netflix-core/pom.xml index 8f6985cc..3343772a 100644 --- a/spring-cloud-netflix-core/pom.xml +++ b/spring-cloud-netflix-core/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-netflix-core diff --git a/spring-cloud-netflix-dependencies/pom.xml b/spring-cloud-netflix-dependencies/pom.xml index c991136a..c40c98c6 100644 --- a/spring-cloud-netflix-dependencies/pom.xml +++ b/spring-cloud-netflix-dependencies/pom.xml @@ -5,11 +5,11 @@ spring-cloud-dependencies-parent org.springframework.cloud - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT spring-cloud-netflix-dependencies - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT pom spring-cloud-netflix-dependencies Spring Cloud Netflix Dependencies diff --git a/spring-cloud-netflix-eureka-client/pom.xml b/spring-cloud-netflix-eureka-client/pom.xml index 6d6bdcd9..a30f0e75 100644 --- a/spring-cloud-netflix-eureka-client/pom.xml +++ b/spring-cloud-netflix-eureka-client/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-netflix-eureka-client diff --git a/spring-cloud-netflix-eureka-server/pom.xml b/spring-cloud-netflix-eureka-server/pom.xml index 74b41f12..4c1d4190 100644 --- a/spring-cloud-netflix-eureka-server/pom.xml +++ b/spring-cloud-netflix-eureka-server/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-netflix-eureka-server diff --git a/spring-cloud-netflix-hystrix-amqp/pom.xml b/spring-cloud-netflix-hystrix-amqp/pom.xml index b3dcd037..34442fc8 100644 --- a/spring-cloud-netflix-hystrix-amqp/pom.xml +++ b/spring-cloud-netflix-hystrix-amqp/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-netflix-hystrix-amqp diff --git a/spring-cloud-netflix-hystrix-dashboard/pom.xml b/spring-cloud-netflix-hystrix-dashboard/pom.xml index 64d5f719..e0a0528b 100644 --- a/spring-cloud-netflix-hystrix-dashboard/pom.xml +++ b/spring-cloud-netflix-hystrix-dashboard/pom.xml @@ -8,7 +8,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. diff --git a/spring-cloud-netflix-hystrix-stream/pom.xml b/spring-cloud-netflix-hystrix-stream/pom.xml index dd4c8f51..1e5715a2 100644 --- a/spring-cloud-netflix-hystrix-stream/pom.xml +++ b/spring-cloud-netflix-hystrix-stream/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-netflix-hystrix-stream diff --git a/spring-cloud-netflix-sidecar/pom.xml b/spring-cloud-netflix-sidecar/pom.xml index c39d4005..e919210c 100644 --- a/spring-cloud-netflix-sidecar/pom.xml +++ b/spring-cloud-netflix-sidecar/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-netflix-sidecar diff --git a/spring-cloud-netflix-spectator/pom.xml b/spring-cloud-netflix-spectator/pom.xml index 55715ac6..2d193b84 100644 --- a/spring-cloud-netflix-spectator/pom.xml +++ b/spring-cloud-netflix-spectator/pom.xml @@ -6,7 +6,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-netflix-spectator diff --git a/spring-cloud-netflix-turbine-stream/pom.xml b/spring-cloud-netflix-turbine-stream/pom.xml index 7fdeef11..9328f905 100644 --- a/spring-cloud-netflix-turbine-stream/pom.xml +++ b/spring-cloud-netflix-turbine-stream/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-netflix-turbine-stream diff --git a/spring-cloud-netflix-turbine/pom.xml b/spring-cloud-netflix-turbine/pom.xml index f4ba02b1..4af74b88 100644 --- a/spring-cloud-netflix-turbine/pom.xml +++ b/spring-cloud-netflix-turbine/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-netflix-turbine diff --git a/spring-cloud-starter-archaius/pom.xml b/spring-cloud-starter-archaius/pom.xml index 29c05ed3..fa0b7fa9 100644 --- a/spring-cloud-starter-archaius/pom.xml +++ b/spring-cloud-starter-archaius/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-starter-archaius diff --git a/spring-cloud-starter-atlas/pom.xml b/spring-cloud-starter-atlas/pom.xml index ef07240e..1add805c 100644 --- a/spring-cloud-starter-atlas/pom.xml +++ b/spring-cloud-starter-atlas/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-starter-atlas diff --git a/spring-cloud-starter-eureka-server/pom.xml b/spring-cloud-starter-eureka-server/pom.xml index 281d6840..a7b34608 100644 --- a/spring-cloud-starter-eureka-server/pom.xml +++ b/spring-cloud-starter-eureka-server/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-starter-eureka-server diff --git a/spring-cloud-starter-eureka/pom.xml b/spring-cloud-starter-eureka/pom.xml index 5db347ea..feb3560a 100644 --- a/spring-cloud-starter-eureka/pom.xml +++ b/spring-cloud-starter-eureka/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-starter-eureka diff --git a/spring-cloud-starter-feign/pom.xml b/spring-cloud-starter-feign/pom.xml index cfced5bb..ba5bb310 100644 --- a/spring-cloud-starter-feign/pom.xml +++ b/spring-cloud-starter-feign/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-starter-feign diff --git a/spring-cloud-starter-hystrix-dashboard/pom.xml b/spring-cloud-starter-hystrix-dashboard/pom.xml index ef126ed6..87069df1 100644 --- a/spring-cloud-starter-hystrix-dashboard/pom.xml +++ b/spring-cloud-starter-hystrix-dashboard/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-starter-hystrix-dashboard diff --git a/spring-cloud-starter-hystrix/pom.xml b/spring-cloud-starter-hystrix/pom.xml index 220ad2e3..7c90a6f1 100644 --- a/spring-cloud-starter-hystrix/pom.xml +++ b/spring-cloud-starter-hystrix/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-starter-hystrix diff --git a/spring-cloud-starter-ribbon/pom.xml b/spring-cloud-starter-ribbon/pom.xml index 533583c0..4a31be7c 100644 --- a/spring-cloud-starter-ribbon/pom.xml +++ b/spring-cloud-starter-ribbon/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-starter-ribbon diff --git a/spring-cloud-starter-spectator/pom.xml b/spring-cloud-starter-spectator/pom.xml index ee66b0eb..5ed2f4ec 100644 --- a/spring-cloud-starter-spectator/pom.xml +++ b/spring-cloud-starter-spectator/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-starter-spectator diff --git a/spring-cloud-starter-turbine-amqp/pom.xml b/spring-cloud-starter-turbine-amqp/pom.xml index 15e5a043..0820167f 100644 --- a/spring-cloud-starter-turbine-amqp/pom.xml +++ b/spring-cloud-starter-turbine-amqp/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-starter-turbine-amqp diff --git a/spring-cloud-starter-turbine-stream/pom.xml b/spring-cloud-starter-turbine-stream/pom.xml index ef45f833..1a7edbcb 100644 --- a/spring-cloud-starter-turbine-stream/pom.xml +++ b/spring-cloud-starter-turbine-stream/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-starter-turbine-stream diff --git a/spring-cloud-starter-turbine/pom.xml b/spring-cloud-starter-turbine/pom.xml index 3639be91..5f6ed33a 100644 --- a/spring-cloud-starter-turbine/pom.xml +++ b/spring-cloud-starter-turbine/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-starter-turbine diff --git a/spring-cloud-starter-zuul/pom.xml b/spring-cloud-starter-zuul/pom.xml index 8b664ac8..fb397c1d 100644 --- a/spring-cloud-starter-zuul/pom.xml +++ b/spring-cloud-starter-zuul/pom.xml @@ -5,7 +5,7 @@ org.springframework.cloud spring-cloud-netflix - 1.2.1.BUILD-SNAPSHOT + 1.2.2.BUILD-SNAPSHOT .. spring-cloud-starter-zuul From ddc1069e86e57b3ff3e631780d59803e059bd3c1 Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Wed, 19 Oct 2016 12:36:15 -0600 Subject: [PATCH 23/24] Move properties to new namespace. Moving eureka.server.{expectedNumberOfRenewsPerMin,defaultOpenForTrafficCount} to eureka.instance.registry so relaxed binding can be used. Default to old values for backwards compatibility. --- .../server/EurekaServerConfiguration.java | 19 ++---- .../eureka/server/InstanceRegistry.java | 4 +- .../server/InstanceRegistryProperties.java | 63 +++++++++++++++++++ 3 files changed, 71 insertions(+), 15 deletions(-) create mode 100644 spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryProperties.java diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerConfiguration.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerConfiguration.java index 0e2f81ed..e5fae161 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerConfiguration.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaServerConfiguration.java @@ -71,7 +71,7 @@ import com.sun.jersey.spi.container.servlet.ServletContainer; @Configuration @Import(EurekaServerInitializerConfiguration.class) @EnableDiscoveryClient -@EnableConfigurationProperties(EurekaDashboardProperties.class) +@EnableConfigurationProperties({ EurekaDashboardProperties.class, InstanceRegistryProperties.class }) @PropertySource("classpath:/eureka/server.properties") public class EurekaServerConfiguration extends WebMvcConfigurerAdapter { /** @@ -92,17 +92,9 @@ public class EurekaServerConfiguration extends WebMvcConfigurerAdapter { @Autowired private EurekaClient eurekaClient; - /* - * Setting expectedNumberOfRenewsPerMin to non-zero to ensure that even an isolated - * server can adjust its eviction policy to the number of registrations (when it's - * zero, even a successful registration won't reset the rate threshold in - * InstanceRegistry.register()). - */ - @Value("${eureka.server.expectedNumberOfRenewsPerMin:1}") - private int expectedNumberOfRenewsPerMin; + @Autowired + private InstanceRegistryProperties instanceRegistryProperties; - @Value("${eureka.server.defaultOpenForTrafficCount:1}") - private int defaultOpenForTrafficCount; public static final CloudJacksonJson JACKSON_JSON = new CloudJacksonJson(); @Bean @@ -166,8 +158,9 @@ public class EurekaServerConfiguration extends WebMvcConfigurerAdapter { ServerCodecs serverCodecs) { this.eurekaClient.getApplications(); // force initialization return new InstanceRegistry(this.eurekaServerConfig, this.eurekaClientConfig, - serverCodecs, this.eurekaClient, this.expectedNumberOfRenewsPerMin, - this.defaultOpenForTrafficCount); + serverCodecs, this.eurekaClient, + this.instanceRegistryProperties.getExpectedNumberOfRenewsPerMin(), + this.instanceRegistryProperties.getDefaultOpenForTrafficCount()); } @Bean diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java index c1ba8b25..3faaef7e 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistry.java @@ -66,8 +66,8 @@ public class InstanceRegistry extends PeerAwareInstanceRegistryImpl /** * If * {@link PeerAwareInstanceRegistryImpl#openForTraffic(ApplicationInfoManager, int)} - * is called with a zero * argument, it means that leases are not automatically * - * cancelled if the instance * hasn't sent any renewals recently. This happens for a + * is called with a zero argument, it means that leases are not automatically + * cancelled if the instance hasn't sent any renewals recently. This happens for a * standalone server. It seems like a bad default, so we set it to the smallest * non-zero value we can, so that any instances that subsequently register can bump up * the threshold. diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryProperties.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryProperties.java new file mode 100644 index 00000000..87a0ebac --- /dev/null +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/InstanceRegistryProperties.java @@ -0,0 +1,63 @@ +/* + * Copyright 2013-2016 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.eureka.server; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import static org.springframework.cloud.netflix.eureka.server.InstanceRegistryProperties.PREFIX; + +/** + * @author Spencer Gibb + */ +@ConfigurationProperties(PREFIX) +public class InstanceRegistryProperties { + + public static final String PREFIX = "eureka.instance.registry"; + + + /* Default number of expected renews per minute, defaults to 1. + * Setting expectedNumberOfRenewsPerMin to non-zero to ensure that even an isolated + * server can adjust its eviction policy to the number of registrations (when it's + * zero, even a successful registration won't reset the rate threshold in + * InstanceRegistry.register()). + */ + @Value("${eureka.server.expectedNumberOfRenewsPerMin:1}") // for backwards compatibility + private int expectedNumberOfRenewsPerMin = 1; + + /** Value used in determining when leases are cancelled, default to 1 for standalone. + * Should be set to 0 for peer replicated eurekas */ + @Value("${eureka.server.defaultOpenForTrafficCount:1}") // for backwards compatibility + private int defaultOpenForTrafficCount = 1; + + public int getExpectedNumberOfRenewsPerMin() { + return expectedNumberOfRenewsPerMin; + } + + public void setExpectedNumberOfRenewsPerMin(int expectedNumberOfRenewsPerMin) { + this.expectedNumberOfRenewsPerMin = expectedNumberOfRenewsPerMin; + } + + public int getDefaultOpenForTrafficCount() { + return defaultOpenForTrafficCount; + } + + public void setDefaultOpenForTrafficCount(int defaultOpenForTrafficCount) { + this.defaultOpenForTrafficCount = defaultOpenForTrafficCount; + } +} From 8e6b64382995eab85d2275bc57eb279e23b746aa Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Thu, 20 Oct 2016 11:19:54 -0600 Subject: [PATCH 24/24] Use new ServletRegistrationBean package. Breaks Spring Boot 1.3 compatibility, enables 1.5 --- .../springframework/cloud/netflix/zuul/ZuulConfiguration.java | 2 +- .../hystrix/dashboard/HystrixDashboardConfiguration.java | 4 ++-- .../cloud/netflix/turbine/TurbineHttpConfiguration.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulConfiguration.java index cc5a5d0b..81f46576 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulConfiguration.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/ZuulConfiguration.java @@ -24,8 +24,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.autoconfigure.web.ErrorController; import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration; -import org.springframework.boot.context.embedded.ServletRegistrationBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.cloud.client.actuator.HasFeatures; import org.springframework.cloud.client.discovery.event.HeartbeatEvent; import org.springframework.cloud.client.discovery.event.HeartbeatMonitor; diff --git a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfiguration.java b/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfiguration.java index 38569b63..4d05b504 100644 --- a/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfiguration.java +++ b/spring-cloud-netflix-hystrix-dashboard/src/main/java/org/springframework/cloud/netflix/hystrix/dashboard/HystrixDashboardConfiguration.java @@ -40,8 +40,8 @@ import org.apache.http.params.HttpParams; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration; -import org.springframework.boot.context.embedded.ServletRegistrationBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.cloud.client.actuator.HasFeatures; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -53,7 +53,6 @@ import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; * @author Dave Syer * @author Roy Clarkson */ -@SuppressWarnings("deprecation") @Configuration @EnableConfigurationProperties(HystrixDashboardProperties.class) public class HystrixDashboardConfiguration { @@ -263,6 +262,7 @@ public class HystrixDashboardConfiguration { } } + @SuppressWarnings("deprecation") private static class ProxyConnectionManager { private final static PoolingClientConnectionManager threadSafeConnectionManager = new PoolingClientConnectionManager(); diff --git a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineHttpConfiguration.java b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineHttpConfiguration.java index 0c58625c..8c23c86f 100644 --- a/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineHttpConfiguration.java +++ b/spring-cloud-netflix-turbine/src/main/java/org/springframework/cloud/netflix/turbine/TurbineHttpConfiguration.java @@ -19,8 +19,8 @@ package org.springframework.cloud.netflix.turbine; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.context.embedded.ServletRegistrationBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.cloud.client.actuator.HasFeatures; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;