Merge master

This commit is contained in:
Dave Syer
2017-05-10 11:40:28 +01:00
49 changed files with 526 additions and 139 deletions

View File

@@ -1 +1 @@
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip

View File

@@ -1,34 +0,0 @@
sudo: false
cache:
directories:
- $HOME/.m2
language: java
jdk:
- oraclejdk8
services:
- rabbitmq
before_install:
- git config user.name "$GIT_NAME"
- git config user.email "$GIT_EMAIL"
- git config credential.helper "store --file=.git/credentials"
- echo "https://$GH_TOKEN:@github.com" > .git/credentials
- gem install asciidoctor
install:
- ./mvnw install -P docs -q -U -DskipTests=true $MVN_LOCAL_OPTS
- '[ "${MVN_GOAL}" == "deploy" ] && ./docs/src/main/asciidoc/ghpages.sh || echo "Not updating docs"'
script:
- './mvnw -s .settings.xml $MVN_GOAL $MVN_PROFILE -nsu $MVN_LOCAL_OPTS'
env:
global:
- MVN_LOCAL_OPTS="-Dmaven.source.skip=true -Dmaven.javadoc.skip=true -Dmaven.test.redirectTestOutputToFile=true"
- GIT_NAME="Dave Syer"
- GIT_EMAIL=dsyer@pivotal.io
- CI_DEPLOY_USERNAME=buildmaster
- FEATURE_BRANCH=$(echo ${TRAVIS_BRANCH} | grep -q "^.*/.*$" && echo true || echo false)
- SPRING_CLOUD_BUILD=$(echo ${TRAVIS_REPO_SLUG} | grep -q "^spring-cloud/.*$" && echo true || echo false)
- MVN_GOAL=install
- VERSION=$(mvn validate | grep Building | head -1 | sed -e 's/.* //')
- MILESTONE=$(echo ${VERSION} | egrep 'M|RC' && echo true || echo false)
- MVN_PROFILE=$([ "${MILESTONE}" == "true" ] && echo -P milestone)
- JAVA_OPTS="-Xmx1024m -XX:CICompilerCount=1 -XX:TieredStopAtLevel=1 -Djava.security.egd=file:/dev/./urandom"
- secure: aeLXRC5oFSddwnZt1/7G2/OHr7jDbxz0ET7sej3I+eSbe3N5vbzQ6FC08es4l89l54ciXd90I1g2BMw7DTYKOO373FP78XPdAEbifJTU4DGd6fCELmoTtUPhjunBIk7E49hisPbv82892IYYA7qi/hzG548cPyZ1IgiJjq0NCsc=

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-cloud-netflix-docs</artifactId>
<packaging>pom</packaging>
@@ -14,7 +14,7 @@
<properties>
<docs.main>spring-cloud-netflix</docs.main>
<main.basedir>${basedir}/..</main.basedir>
<docs.whitelisted.branches>1.0.x,1.1.x,1.2.x</docs.whitelisted.branches>
<docs.whitelisted.branches>1.0.x,1.1.x</docs.whitelisted.branches>
</properties>
<build>
<plugins>

10
mvnw vendored
View File

@@ -238,8 +238,16 @@ else
echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//')
fi
if echo $VERSION | egrep -q 'RELEASE'; then
echo Activating \"central\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pcentral"
else
echo Deactivating \"central\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q central && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pcentral//')
fi
exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} ${MAVEN_ARGS} "$@"
${WRAPPER_LAUNCHER} ${MAVEN_ARGS} "$@"

12
pom.xml
View File

@@ -3,14 +3,14 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Spring Cloud Netflix</name>
<description>Spring Cloud Netflix</description>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-build</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.2.RELEASE</version>
<relativePath />
</parent>
<scm>
@@ -24,8 +24,8 @@
<main.basedir>${basedir}</main.basedir>
<netty.version>4.0.27.Final</netty.version>
<jackson.version>2.7.3</jackson.version>
<spring-cloud-commons.version>2.0.0.BUILD-SNAPSHOT</spring-cloud-commons.version>
<spring-cloud-config.version>2.0.0.BUILD-SNAPSHOT</spring-cloud-config.version>
<spring-cloud-commons.version>1.2.1.BUILD-SNAPSHOT</spring-cloud-commons.version>
<spring-cloud-config.version>1.3.1.BUILD-SNAPSHOT</spring-cloud-config.version>
<spring-cloud-stream.version>Chelsea.BUILD-SNAPSHOT</spring-cloud-stream.version>
<!-- Sonar -->
@@ -57,8 +57,8 @@
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-netflix-core</artifactId>

View File

@@ -18,7 +18,8 @@ package org.springframework.cloud.netflix.feign.encoding;
import feign.Feign;
import feign.httpclient.ApacheHttpClient;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -38,7 +39,7 @@ import org.springframework.context.annotation.Configuration;
@ConditionalOnClass(Feign.class)
@ConditionalOnBean(ApacheHttpClient.class)
@ConditionalOnProperty(value = "feign.compression.response.enabled", matchIfMissing = false)
@AutoConfigureBefore(FeignAutoConfiguration.class)
@AutoConfigureAfter(FeignAutoConfiguration.class)
public class FeignAcceptGzipEncodingAutoConfiguration {
@Bean

View File

@@ -18,7 +18,8 @@ package org.springframework.cloud.netflix.feign.encoding;
import feign.Feign;
import feign.httpclient.ApacheHttpClient;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -38,7 +39,7 @@ import org.springframework.context.annotation.Configuration;
@ConditionalOnClass(Feign.class)
@ConditionalOnBean(ApacheHttpClient.class)
@ConditionalOnProperty(value = "feign.compression.request.enabled", matchIfMissing = false)
@AutoConfigureBefore(FeignAutoConfiguration.class)
@AutoConfigureAfter(FeignAutoConfiguration.class)
public class FeignContentGzipEncodingAutoConfiguration {
@Bean

View File

@@ -19,7 +19,6 @@ package org.springframework.cloud.netflix.feign.ribbon;
import feign.Client;
import feign.Request;
import feign.Response;
import feign.Util;
import java.io.IOException;
import java.net.URI;

View File

@@ -103,6 +103,7 @@ public class RibbonLoadBalancingHttpClient extends
@Override
public RequestSpecificRetryHandler getRequestSpecificRetryHandler(RibbonApacheHttpRequest request, IClientConfig requestConfig) {
return new RequestSpecificRetryHandler(false, false, RetryHandler.DEFAULT, null);
return new RequestSpecificRetryHandler(false, false,
RetryHandler.DEFAULT, requestConfig);
}
}

View File

@@ -33,9 +33,10 @@ import com.netflix.zuul.monitoring.TracerFactory;
import lombok.extern.apachecommons.CommonsLog;
/**
* Initializes various Zuul components including {@link ZuulFilter}.
*
* @author Spencer Gibb
*
* TODO: .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
*/
@CommonsLog
public class ZuulFilterInitializer implements ServletContextListener {
@@ -91,17 +92,4 @@ public class ZuulFilterInitializer implements ServletContextListener {
cache.clear();
}
/*
* private void initGroovyFilterManager() {
*
* //TODO: support groovy filters loaded from filesystem in proxy
* FilterLoader.getInstance().setCompiler(new GroovyCompiler());
*
* final String scriptRoot = props.getFilterRoot();
* log.info("Using file system script: " + scriptRoot);
*
* try { FilterFileManager.setFilenameFilter(new GroovyFileFilter());
* FilterFileManager.init(5, scriptRoot + "/pre", scriptRoot + "/route", scriptRoot +
* "/post" ); } catch (Exception e) { throw new RuntimeException(e); } }
*/
}

View File

@@ -198,21 +198,21 @@ public class PreDecorationFilter extends ZuulFilter {
String proto = request.getScheme();
if (hasHeader(request, X_FORWARDED_HOST_HEADER)) {
host = request.getHeader(X_FORWARDED_HOST_HEADER) + "," + host;
if (!hasHeader(request, X_FORWARDED_PORT_HEADER)) {
if (hasHeader(request, X_FORWARDED_PROTO_HEADER)) {
StringBuilder builder = new StringBuilder();
for (String previous : StringUtils.commaDelimitedListToStringArray(request.getHeader(X_FORWARDED_PROTO_HEADER))) {
if (builder.length()>0) {
builder.append(",");
}
builder.append(HTTPS_SCHEME.equals(previous) ? HTTPS_PORT : HTTP_PORT);
}
if (!hasHeader(request, X_FORWARDED_PORT_HEADER)) {
if (hasHeader(request, X_FORWARDED_PROTO_HEADER)) {
StringBuilder builder = new StringBuilder();
for (String previous : StringUtils.commaDelimitedListToStringArray(request.getHeader(X_FORWARDED_PROTO_HEADER))) {
if (builder.length()>0) {
builder.append(",");
}
builder.append(",").append(port);
port = builder.toString();
builder.append(HTTPS_SCHEME.equals(previous) ? HTTPS_PORT : HTTP_PORT);
}
} else {
port = request.getHeader(X_FORWARDED_PORT_HEADER) + "," + port;
builder.append(",").append(port);
port = builder.toString();
}
} else {
port = request.getHeader(X_FORWARDED_PORT_HEADER) + "," + port;
}
if (hasHeader(request, X_FORWARDED_PROTO_HEADER)) {
proto = request.getHeader(X_FORWARDED_PROTO_HEADER) + "," + proto;

View File

@@ -70,7 +70,7 @@ public class RibbonRoutingFilter extends ZuulFilter {
this.requestCustomizers = requestCustomizers;
// To support Servlet API 3.0.1 we need to check if getcontentLengthLong exists
try {
HttpServletResponse.class.getMethod("getContentLengthLong");
HttpServletRequest.class.getMethod("getContentLengthLong");
} catch(NoSuchMethodException e) {
useServlet31 = false;
}

View File

@@ -0,0 +1,97 @@
/*
*
* * Copyright 2013-2017 the original author or authors.
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package org.springframework.cloud.netflix.feign;
import feign.Client;
import feign.RequestInterceptor;
import feign.httpclient.ApacheHttpClient;
import java.util.Map;
import org.junit.After;
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.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.ClassPathExclusions;
import org.springframework.cloud.FilteredClassPathRunner;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.cloud.netflix.feign.encoding.FeignAcceptGzipEncodingAutoConfiguration;
import org.springframework.cloud.netflix.feign.encoding.FeignAcceptGzipEncodingInterceptor;
import org.springframework.cloud.netflix.feign.encoding.FeignContentGzipEncodingAutoConfiguration;
import org.springframework.cloud.netflix.feign.encoding.FeignContentGzipEncodingInterceptor;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* @author Ryan Baxter
*/
@RunWith(FilteredClassPathRunner.class)
@ClassPathExclusions({"ribbon-loadbalancer-{version:\\d.*}.jar"})
public class FeignCompressionTests {
private ConfigurableApplicationContext context;
@Before
public void setUp() {
context = new SpringApplicationBuilder().properties("feign.compression.response.enabled=true",
"feign.compression.request.enabled=true", "feign.okhttp.enabled=false").sources(PropertyPlaceholderAutoConfiguration.class,
ArchaiusAutoConfiguration.class, FeignAutoConfiguration.class, PlainConfig.class, FeignContentGzipEncodingAutoConfiguration.class,
FeignAcceptGzipEncodingAutoConfiguration.class).web(false).run();
}
@After
public void tearDown() {
if(context != null) {
context.close();
}
}
@Test
public void testInterceptors() {
FeignContext feignContext = context.getBean(FeignContext.class);
Map<String, RequestInterceptor> interceptors = feignContext.getInstances("foo", RequestInterceptor.class);
assertEquals(2, interceptors.size());
assertTrue(FeignAcceptGzipEncodingInterceptor.class.isInstance(interceptors.get("feignAcceptGzipEncodingInterceptor")));
assertTrue(FeignContentGzipEncodingInterceptor.class.isInstance(interceptors.get("feignContentGzipEncodingInterceptor")));
}
@Configuration
protected static class PlainConfig {
@Autowired
private Client client;
@Bean
public ApacheHttpClient client() {
/* We know our client is an AppacheHttpClient because we disabled the OK HTTP client. FeignAcceptGzipEncodingAutoConfiguration
* won't load unless there is a bean of type ApacheHttpClient (not Client) in this test because the bean is not
* yet created and so the application context doesnt know that the Client bean is actually an instance of ApacheHttpClient,
* therefore FeignAcceptGzipEncodingAutoConfiguration will not be loaded. We just create a bean here of type
* ApacheHttpClient so that the configuration will be loaded correctly.
*/
return (ApacheHttpClient)client;
}
}
}

View File

@@ -152,7 +152,56 @@ public class PreDecorationFilterTests {
this.filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertEquals("localhost:8080", ctx.getZuulRequestHeaders().get("x-forwarded-host"));
assertEquals("8080", ctx.getZuulRequestHeaders().get("x-forwarded-port"));
assertEquals("443,8080", ctx.getZuulRequestHeaders().get("x-forwarded-port"));
assertEquals("https,http", ctx.getZuulRequestHeaders().get("x-forwarded-proto"));
}
@Test
public void xForwardedProtoHttpOnlyAppends() throws Exception {
this.properties.setPrefix("/api");
this.request.setRequestURI("/api/foo/1");
this.request.setRemoteAddr("5.6.7.8");
this.request.setServerPort(8080);
this.request.addHeader("X-Forwarded-Proto", "http");
this.routeLocator.addRoute(
new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null));
this.filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertEquals("localhost:8080", ctx.getZuulRequestHeaders().get("x-forwarded-host"));
assertEquals("80,8080", ctx.getZuulRequestHeaders().get("x-forwarded-port"));
assertEquals("http,http", ctx.getZuulRequestHeaders().get("x-forwarded-proto"));
}
@Test
public void xForwardedPortOnlyAppends() throws Exception {
this.properties.setPrefix("/api");
this.request.setRequestURI("/api/foo/1");
this.request.setRemoteAddr("5.6.7.8");
this.request.setServerPort(8080);
this.request.addHeader("X-Forwarded-Port", "456");
this.routeLocator.addRoute(
new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null));
this.filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertEquals("localhost:8080", ctx.getZuulRequestHeaders().get("x-forwarded-host"));
assertEquals("456,8080", ctx.getZuulRequestHeaders().get("x-forwarded-port"));
assertEquals("http", ctx.getZuulRequestHeaders().get("x-forwarded-proto"));
}
@Test
public void xForwardedPortAndProtoAppends() throws Exception {
this.properties.setPrefix("/api");
this.request.setRequestURI("/api/foo/1");
this.request.setRemoteAddr("5.6.7.8");
this.request.setServerPort(8080);
this.request.addHeader("X-Forwarded-Proto", "https");
this.request.addHeader("X-Forwarded-Port", "456");
this.routeLocator.addRoute(
new ZuulRoute("foo", "/foo/**", "foo", null, false, null, null));
this.filter.run();
RequestContext ctx = RequestContext.getCurrentContext();
assertEquals("localhost:8080", ctx.getZuulRequestHeaders().get("x-forwarded-host"));
assertEquals("456,8080", ctx.getZuulRequestHeaders().get("x-forwarded-port"));
assertEquals("https,http", ctx.getZuulRequestHeaders().get("x-forwarded-proto"));
}

View File

@@ -119,7 +119,7 @@ public abstract class RibbonRetryIntegrationTestBase {
}
@Test
public void disbaleRetry() {
public void disableRetry() {
String uri = "/disableretry/everyothererror";
ResponseEntity<String> result = new TestRestTemplate().exchange(
"http://localhost:" + this.port + uri, HttpMethod.GET,

View File

@@ -5,11 +5,11 @@
<parent>
<artifactId>spring-cloud-dependencies-parent</artifactId>
<groupId>org.springframework.cloud</groupId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath/>
</parent>
<artifactId>spring-cloud-netflix-dependencies</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<packaging>pom</packaging>
<name>spring-cloud-netflix-dependencies</name>
<description>Spring Cloud Netflix Dependencies</description>
@@ -17,7 +17,7 @@
<archaius.version>0.7.4</archaius.version>
<eureka.version>1.6.2</eureka.version>
<feign.version>9.4.0</feign.version>
<hystrix.version>1.5.10</hystrix.version>
<hystrix.version>1.5.11</hystrix.version>
<ribbon.version>2.2.2</ribbon.version>
<servo.version>0.10.1</servo.version>
<zuul.version>1.3.0</zuul.version>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-netflix-eureka-client</artifactId>

View File

@@ -61,11 +61,19 @@ public class EurekaDiscoveryClientConfiguration {
@ConditionalOnClass(RefreshScopeRefreshedEvent.class)
protected static class EurekaClientConfigurationRefresher {
@Autowired(required = false)
private EurekaClient eurekaClient;
@Autowired(required = false)
private EurekaAutoServiceRegistration autoRegistration;
@EventListener(RefreshScopeRefreshedEvent.class)
public void onApplicationEvent(RefreshScopeRefreshedEvent event) {
//This will force the creation of the EurkaClient bean if not already created
//to make sure the client will be reregistered after a refresh event
if(eurekaClient != null) {
eurekaClient.getApplications();
}
if (autoRegistration != null) {
// register in case meta data changed
this.autoRegistration.stop();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,7 +38,11 @@ import com.netflix.discovery.EurekaClient;
import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
/**
* Spring configuration for configuring Ribbon defaults to be Eureka based
* if Eureka client is enabled
*
* @author Dave Syer
* @author Biju Kunjummen
*/
@Configuration
@EnableConfigurationProperties
@@ -65,8 +69,11 @@ public class RibbonEurekaAutoConfiguration {
@ConditionalOnBean(SpringClientFactory.class)
@ConditionalOnProperty(value = "ribbon.eureka.enabled", matchIfMissing = true)
static class Defaults {}
@ConditionalOnBean(EurekaClient.class)
static class EurekaBeans {}
@ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true)
static class OnEurekaClientEnabled {}
}
}

View File

@@ -0,0 +1,60 @@
/*
*
* * 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.config;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
import org.springframework.cloud.netflix.eureka.sample.RefreshEurekaSampleApplication;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.test.context.junit4.SpringRunner;
import com.netflix.discovery.EurekaClient;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* @author Ryan Baxter
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = RefreshEurekaSampleApplication.class)
public class ConfigRefreshTests {
@Autowired
private ApplicationEventPublisher publisher;
@Autowired
//Mocked in RefreshEurekaSampleApplication
private EurekaClient client;
@Test
// This test is used to verify that getApplications is called the correct number of times
// when a refresh event is fired. The getApplications call in EurekaClientConfigurationRefresher.onApplicationEvent
// ensures that the EurekaClient bean is recreated after a refresh event and that we reregister the client with
//the server
public void verifyGetApplications() {
if(publisher != null) {
publisher.publishEvent(new RefreshScopeRefreshedEvent());
}
verify(client, times(3)).getApplications();
}
}

View File

@@ -0,0 +1,47 @@
/*
*
* * 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.sample;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.CloudEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RestController;
import com.netflix.discovery.EurekaClient;
import static org.mockito.Mockito.mock;
/**
* @author Ryan Baxter
*/
@Configuration
@ComponentScan
@EnableAutoConfiguration
@RestController
@EnableDiscoveryClient
public class RefreshEurekaSampleApplication {
@Bean
public EurekaClient getClient() {
return mock(CloudEurekaClient.class);
}
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.ribbon.eureka;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ZoneAvoidanceRule;
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
import com.netflix.niws.loadbalancer.NIWSDiscoveryPing;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration;
import org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration;
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.netflix.ribbon.eureka.EurekaRibbonClientPreprocessorIntegrationTests.TestConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Ribbon Eureka client should be disabled if Eureka client is not enabled
*
* @author Biju Kunjummen
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = TestConfiguration.class, properties = "eureka.client.enabled=false")
@DirtiesContext
public class EurekaDisabledRibbonClientIntegrationTests {
@Autowired
private SpringClientFactory factory;
@Test
public void serverListShouldNotBeEurekaBased() throws Exception {
assertThat(getLoadBalancer().getServerListImpl())
.isNotInstanceOf(DomainExtractingServerList.class);
}
@Test
public void ruleDefaultsToZoneAvoidance() throws Exception {
ZoneAvoidanceRule.class.cast(getLoadBalancer().getRule());
}
@Test
public void pingShouldNotBeEurekaBased() throws Exception {
assertThat(getLoadBalancer().getPing()).isNotInstanceOf(NIWSDiscoveryPing.class);
}
@Test
public void serverIntrospectorShouldNotBeEurekaBased() throws Exception {
assertThat(this.factory.getInstance("foo", ServerIntrospector.class))
.isNotInstanceOf(EurekaServerIntrospector.class);
}
@SuppressWarnings("unchecked")
private ZoneAwareLoadBalancer<Server> getLoadBalancer() {
return (ZoneAwareLoadBalancer<Server>) this.factory.getLoadBalancer("foo");
}
@Configuration
@RibbonClient("foo")
@Import({ UtilAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
ArchaiusAutoConfiguration.class, RibbonAutoConfiguration.class,
EurekaDiscoveryClientConfiguration.class, EurekaClientAutoConfiguration.class,
RibbonEurekaAutoConfiguration.class })
protected static class TestConfiguration {
}
}

View File

@@ -30,6 +30,7 @@ import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
@@ -42,6 +43,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
@SpringBootTest(classes = RibbonEurekaAutoConfigurationTests.EurekaClientDisabledApp.class,
properties = { "eureka.client.enabled=false", "spring.application.name=eurekadisabledtest" },
webEnvironment = RANDOM_PORT)
@DirtiesContext
public class RibbonEurekaAutoConfigurationTests {
@Autowired

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-netflix-eureka-server</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-netflix-hystrix-amqp</artifactId>

View File

@@ -8,7 +8,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<properties>

View File

@@ -175,6 +175,7 @@
assertNotNull(data,"propertyValue_circuitBreakerSleepWindowInMilliseconds");
assertNotNull(data,"propertyValue_circuitBreakerErrorThresholdPercentage");
assertNotNull(data,"propertyValue_circuitBreakerForceOpen");
assertNotNull(data,"propertyValue_circuitBreakerForceClosed");
assertNotNull(data,"propertyValue_executionIsolationStrategy");
assertNotNull(data,"propertyValue_executionIsolationThreadTimeoutInMilliseconds");
assertNotNull(data,"propertyValue_executionIsolationThreadInterruptOnTimeout");
@@ -539,5 +540,3 @@
return x1 + x2;
}
})(window);

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-netflix-hystrix-stream</artifactId>
@@ -60,12 +60,6 @@
<artifactId>eureka-client</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
@@ -83,7 +77,7 @@
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
<artifactId>spring-cloud-stream-test-support</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

View File

@@ -19,13 +19,10 @@ package org.springframework.cloud.netflix.hystrix.stream;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.netflix.hystrix.HystrixConstants;
import lombok.Data;
/**
* @author Spencer Gibb
*/
@ConfigurationProperties("hystrix.stream.queue")
@Data
public class HystrixStreamProperties {
/** Flag to indicate that Hystrix Stream is enabled. Default is true. */
@@ -52,4 +49,68 @@ public class HystrixStreamProperties {
/** The size of the metrics queue. This queue drains to the stream. Defaults to 1000. */
private int size = 1000;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public boolean isPrefixMetricName() {
return prefixMetricName;
}
public void setPrefixMetricName(boolean prefixMetricName) {
this.prefixMetricName = prefixMetricName;
}
public boolean isSendId() {
return sendId;
}
public void setSendId(boolean sendId) {
this.sendId = sendId;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public long getSendRate() {
return sendRate;
}
public void setSendRate(long sendRate) {
this.sendRate = sendRate;
}
public long getGatherRate() {
return gatherRate;
}
public void setGatherRate(long gatherRate) {
this.gatherRate = gatherRate;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}

View File

@@ -22,16 +22,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.LinkedBlockingQueue;
import org.springframework.beans.BeansException;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.scheduling.annotation.Scheduled;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.netflix.hystrix.HystrixCircuitBreaker;
@@ -42,7 +32,18 @@ import com.netflix.hystrix.HystrixThreadPoolKey;
import com.netflix.hystrix.HystrixThreadPoolMetrics;
import com.netflix.hystrix.util.HystrixRollingNumberEvent;
import lombok.extern.apachecommons.CommonsLog;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.scheduling.annotation.Scheduled;
/**
* @author Spencer Gibb
@@ -50,8 +51,9 @@ import lombok.extern.apachecommons.CommonsLog;
* @see com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsPoller (nested
* private class MetricsPoller)
*/
@CommonsLog
public class HystrixStreamTask implements ApplicationContextAware {
private static Log log = LogFactory.getLog(HystrixStreamTask.class);
private MessageChannel outboundChannel;

View File

@@ -18,6 +18,7 @@ package org.springframework.cloud.netflix.hystrix.stream;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
@@ -39,6 +40,12 @@ import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
@DirtiesContext
public class HystrixStreamTests {
@Autowired
private HystrixStreamTask task;
@Autowired
private Application application;
@EnableAutoConfiguration
@EnableCircuitBreaker
@RestController
@@ -58,7 +65,8 @@ public class HystrixStreamTests {
@Test
public void contextLoads() {
this.application.hello();
this.task.gatherMetrics();
}
}

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-netflix-sidecar</artifactId>

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-netflix-spectator</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-netflix-turbine-stream</artifactId>
@@ -58,11 +58,6 @@
<artifactId>spring-cloud-commons</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-netflix-turbine</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-starter-archaius</artifactId>
@@ -36,12 +36,12 @@
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<!--<exclusions>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>-->
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-starter-atlas</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-starter-eureka-server</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-starter-eureka</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-starter-feign</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-starter-hystrix</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-starter-ribbon</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-starter-spectator</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-starter-turbine-amqp</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-starter-turbine-stream</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-starter-turbine</artifactId>

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-starter-zuul</artifactId>