Commit 0239f106 by Ryan Baxter

Merge branch 'master' of github.com:spring-cloud/spring-cloud-netflix

parents 4c4accea 2ff40924
...@@ -680,6 +680,29 @@ Spring Cloud provides a `spring-cloud-starter-netflix-turbine` that has all the ...@@ -680,6 +680,29 @@ Spring Cloud provides a `spring-cloud-starter-netflix-turbine` that has all the
NOTE: By default, Spring Cloud lets Turbine use the host and port to allow multiple processes per host, per cluster. NOTE: By default, Spring Cloud lets Turbine use the host and port to allow multiple processes per host, per cluster.
If you want the native Netflix behavior built into Turbine to _not_ allow multiple processes per host, per cluster (the key to the instance ID is the hostname), set `turbine.combineHostPort=false`. If you want the native Netflix behavior built into Turbine to _not_ allow multiple processes per host, per cluster (the key to the instance ID is the hostname), set `turbine.combineHostPort=false`.
==== Clusters Endpoint
In some situations it might be useful for other applications to know what custers have been configured
in Turbine. To support this you can use the `/clusters` endpoint which will return a JSON array of
all the configured clusters.
.GET /clusters
[source,json]
----
[
{
"name": "RACES",
"link": "http://localhost:8383/turbine.stream?cluster=RACES"
},
{
"name": "WEB",
"link": "http://localhost:8383/turbine.stream?cluster=WEB"
}
]
----
This endpoint can be disabled by setting `turbine.endpoints.clusters.enabled` to `false`.
=== Turbine Stream === Turbine Stream
In some environments (such as in a PaaS setting), the classic Turbine model of pulling metrics from all the distributed Hystrix commands does not work. In some environments (such as in a PaaS setting), the classic Turbine model of pulling metrics from all the distributed Hystrix commands does not work.
...@@ -1559,6 +1582,12 @@ public class ZuulConfig { ...@@ -1559,6 +1582,12 @@ public class ZuulConfig {
CAUTION: Use this filter carefully. The filter acts on the `Location` header of ALL `3XX` response codes, which may not be appropriate in all scenarios, such as when redirecting the user to an external URL. CAUTION: Use this filter carefully. The filter acts on the `Location` header of ALL `3XX` response codes, which may not be appropriate in all scenarios, such as when redirecting the user to an external URL.
=== Metrics
Zuul will provide metrics under the Actuator metrics endpoint for any failures that might occur when routing requests.
These metrics can be viewed by hitting `/actuator/metrics`. The metrics will have a name that has the format
`ZUUL::EXCEPTION:errorCause:statusCode`.
[[zuul-developer-guide]] [[zuul-developer-guide]]
=== Zuul Developer Guide === Zuul Developer Guide
......
...@@ -4,8 +4,10 @@ import java.util.Objects; ...@@ -4,8 +4,10 @@ import java.util.Objects;
public class ClusterInformation { public class ClusterInformation {
private final String name; private String name;
private final String link; private String link;
public ClusterInformation(){};
public ClusterInformation(String name, String link) { public ClusterInformation(String name, String link) {
this.name = name; this.name = name;
...@@ -20,6 +22,14 @@ public class ClusterInformation { ...@@ -20,6 +22,14 @@ public class ClusterInformation {
return link; return link;
} }
public void setName(String name) {
this.name = name;
}
public void setLink(String link) {
this.link = link;
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;
......
...@@ -20,6 +20,7 @@ import com.netflix.turbine.monitor.cluster.ClusterMonitorFactory; ...@@ -20,6 +20,7 @@ import com.netflix.turbine.monitor.cluster.ClusterMonitorFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.actuator.HasFeatures; import org.springframework.cloud.client.actuator.HasFeatures;
...@@ -57,6 +58,18 @@ public class TurbineHttpConfiguration { ...@@ -57,6 +58,18 @@ public class TurbineHttpConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public TurbineInformationService turbineInformationService() {
return new TurbineInformationService();
}
@Bean
@ConditionalOnProperty(value = "turbine.endpoints.clusters.enabled", matchIfMissing = true)
public TurbineController turbineController(TurbineInformationService service) {
return new TurbineController(service);
}
@Bean
@ConditionalOnMissingBean
public TurbineAggregatorProperties turbineAggregatorProperties() { public TurbineAggregatorProperties turbineAggregatorProperties() {
return new TurbineAggregatorProperties(); return new TurbineAggregatorProperties();
} }
......
...@@ -16,13 +16,23 @@ ...@@ -16,13 +16,23 @@
package org.springframework.cloud.netflix.turbine; package org.springframework.cloud.netflix.turbine;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.assertEquals;
/** /**
* @author Spencer Gibb * @author Spencer Gibb
*/ */
...@@ -30,12 +40,38 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; ...@@ -30,12 +40,38 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@SpringBootTest(classes = TurbineHttpTests.TurbineHttpSampleApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) @SpringBootTest(classes = TurbineHttpTests.TurbineHttpSampleApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
public class TurbineHttpTests { public class TurbineHttpTests {
private static final ClusterInformation foo = new ClusterInformation("foo", "http://foo");
private static final ClusterInformation bar = new ClusterInformation("bar", "http://bar");
@Autowired
TestRestTemplate rest;
@EnableAutoConfiguration @EnableAutoConfiguration
@EnableTurbine @EnableTurbine
public static class TurbineHttpSampleApplication { public static class TurbineHttpSampleApplication {
@Configuration
static class MyConfig {
@Bean
TurbineInformationService myInfoService() {
return new TurbineInformationService() {
@Override
public Collection<ClusterInformation> getClusterInformations(HttpServletRequest request) {
List<ClusterInformation> clusterInformationList = new ArrayList<ClusterInformation>();
clusterInformationList.add(foo);
clusterInformationList.add(bar);
return clusterInformationList;
}
};
}
}
} }
@Test @Test
public void contextLoads() { public void contextLoads() {
ClusterInformation[] clusters = rest.getForObject("/clusters", ClusterInformation[].class);
assertEquals(2, clusters.length);
assertEquals(foo, clusters[0]);
assertEquals(bar, clusters[1]);
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment