Migrate /hystrix.stream to management context.

fixes gh-2309i
parent 8011b66e
/*
* Copyright 2013-2015 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.endpoint;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
// import org.springframework.boot.actuate.endpoint.Endpoint;
// import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.ServletWrappingController;
//FIXME 2.0.x
public abstract class ServletWrappingEndpoint implements InitializingBean,
ApplicationContextAware, ServletContextAware/*, MvcEndpoint*/ {
// TODO: move to spring-boot?
private String path;
private boolean sensitive;
private boolean enabled = true;
private final ServletWrappingController controller = new ServletWrappingController();
@Override
public void afterPropertiesSet() throws Exception {
this.controller.afterPropertiesSet();
}
@Override
public void setServletContext(ServletContext servletContext) {
this.controller.setServletContext(servletContext);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.controller.setApplicationContext(applicationContext);
}
protected ServletWrappingEndpoint(Class<? extends Servlet> servletClass,
String servletName, String path, boolean sensitive, boolean enabled) {
this.controller.setServletClass(servletClass);
this.controller.setServletName(servletName);
this.path = path;
this.sensitive = sensitive;
this.enabled = enabled;
}
@RequestMapping("**")
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response)
throws Exception {
return this.controller.handleRequest(request, response);
}
public boolean isEnabled() {
return this.enabled;
}
public ServletWrappingController getController() {
return this.controller;
}
/*@Override
public String getPath() {
return this.path;
}
@Override
public boolean isSensitive() {
return this.sensitive;
}
@Override
public Class<? extends Endpoint<?>> getEndpointType() {
return null;
}*/
}
/* /*
* Copyright 2013-2016 the original author or authors. * Copyright 2013-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -16,20 +16,16 @@ ...@@ -16,20 +16,16 @@
package org.springframework.cloud.netflix.hystrix; package org.springframework.cloud.netflix.hystrix;
import com.netflix.hystrix.Hystrix;
import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.apache.catalina.core.ApplicationContext; import org.apache.catalina.core.ApplicationContext;
import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.DisposableBean;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.cloud.client.actuator.HasFeatures; import org.springframework.cloud.client.actuator.HasFeatures;
import org.springframework.cloud.client.actuator.NamedFeature; import org.springframework.cloud.client.actuator.NamedFeature;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import com.netflix.hystrix.Hystrix;
import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect;
/** /**
* @author Spencer Gibb * @author Spencer Gibb
* @author Christian Dupuis * @author Christian Dupuis
...@@ -53,23 +49,6 @@ public class HystrixCircuitBreakerConfiguration { ...@@ -53,23 +49,6 @@ public class HystrixCircuitBreakerConfiguration {
return HasFeatures.namedFeatures(new NamedFeature("Hystrix", HystrixCommandAspect.class)); return HasFeatures.namedFeatures(new NamedFeature("Hystrix", HystrixCommandAspect.class));
} }
@Configuration
@ConditionalOnProperty(value = "hystrix.stream.endpoint.enabled", matchIfMissing = true)
@ConditionalOnWebApplication
@ConditionalOnClass({ Health.class, HystrixMetricsStreamServlet.class })
protected static class HystrixWebConfiguration {
@Bean
public HystrixStreamEndpoint hystrixStreamEndpoint() {
return new HystrixStreamEndpoint();
}
@Bean
public HasFeatures hystrixStreamFeature() {
return HasFeatures.namedFeature("Hystrix Stream Servlet", HystrixStreamEndpoint.class);
}
}
//FIXME: 2.0.0 //FIXME: 2.0.0
/*@Configuration /*@Configuration
@ConditionalOnProperty(value = "hystrix.metrics.enabled", matchIfMissing = true) @ConditionalOnProperty(value = "hystrix.metrics.enabled", matchIfMissing = true)
......
/*
* 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.hystrix;
import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect;
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.servlet.ManagementServletContext;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
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 com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
/**
* See original {@link org.springframework.boot.actuate.autoconfigure.jolokia.JolokiaManagementContextConfiguration}
*/
@ManagementContextConfiguration
@ConditionalOnProperty(value = "management.hystrix.enabled", matchIfMissing = true)
@ConditionalOnWebApplication
@ConditionalOnBean(HystrixCommandAspect.class) // only install the stream if enabled
@ConditionalOnClass({ Health.class, HystrixMetricsStreamServlet.class })
@EnableConfigurationProperties(HystrixProperties.class)
class HystrixManagementContextConfiguration {
private final ManagementServletContext managementServletContext;
private final HystrixProperties properties;
public HystrixManagementContextConfiguration(
ManagementServletContext managementServletContext,
HystrixProperties properties) {
this.managementServletContext = managementServletContext;
this.properties = properties;
}
@Bean
public ServletRegistrationBean<HystrixMetricsStreamServlet> jolokiaServlet() {
String path = this.managementServletContext.getContextPath()
+ this.properties.getPath();
String urlMapping = (path.endsWith("/") ? path + "*" : path + "/*");
ServletRegistrationBean<HystrixMetricsStreamServlet> registration = new ServletRegistrationBean<>(
new HystrixMetricsStreamServlet(), urlMapping);
registration.setInitParameters(this.properties.getConfig());
return registration;
}
@Bean
public HasFeatures hystrixStreamFeature() {
return HasFeatures.namedFeature("Hystrix Stream Servlet", HystrixMetricsStreamServlet.class);
}
}
/*
* 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.hystrix;
import java.util.HashMap;
import java.util.Map;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Configuration properties for Hystrix Servlet.
*
* @author Spencer Gibb
* @since 2.0.0
*/
@ConfigurationProperties(prefix = "management.hystrix")
public class HystrixProperties {
/**
* Enable Hystrix Stream.
*/
private boolean enabled;
/**
* Path at which Hystrix Stream will be available.
*/
private String path = "/hystrix.stream";
/**
* Hystrix settings. These are traditionally set using servlet parameters. Refer to
* the documentation of Hystrix for more details.
*/
private final Map<String, String> config = new HashMap<>();
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getPath() {
return this.path;
}
public void setPath(String path) {
this.path = path;
}
public Map<String, String> getConfig() {
return this.config;
}
}
/*
* Copyright 2013-2014 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.hystrix;
import org.springframework.cloud.netflix.endpoint.ServletWrappingEndpoint;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
/**
* @author Spencer Gibb
*/
public class HystrixStreamEndpoint extends ServletWrappingEndpoint {
public HystrixStreamEndpoint() {
super(HystrixMetricsStreamServlet.class, "hystrixStream", "/hystrix.stream",
false, true);
}
}
...@@ -13,3 +13,5 @@ org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfiguration ...@@ -13,3 +13,5 @@ org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfiguration
org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker=\ org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker=\
org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfiguration org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfiguration
org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration=\
org.springframework.cloud.netflix.hystrix.HystrixManagementContextConfiguration
\ No newline at end of file
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*
*/ */
package org.springframework.cloud.netflix.hystrix; package org.springframework.cloud.netflix.hystrix;
...@@ -24,15 +23,14 @@ import java.util.List; ...@@ -24,15 +23,14 @@ import java.util.List;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.junit.Ignore;
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.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.web.server.LocalServerPort;
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.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
...@@ -65,14 +63,12 @@ public class HystrixStreamEndpointTests { ...@@ -65,14 +63,12 @@ public class HystrixStreamEndpointTests {
private int port = 0; private int port = 0;
@Test @Test
@Ignore // FIXME: 2.0.x
public void pathStartsWithSlash() { public void pathStartsWithSlash() {
HystrixStreamEndpoint endpoint = new HystrixStreamEndpoint(); HystrixProperties properties = new HystrixProperties();
// assertEquals("/hystrix.stream", endpoint.getPath()); assertEquals("/hystrix.stream", properties.getPath());
} }
@Test @Test
@Ignore // FIXME: 2.0.x
public void hystrixStreamWorks() throws Exception { public void hystrixStreamWorks() throws Exception {
String url = "http://localhost:" + port; String url = "http://localhost:" + port;
// you have to hit a Hystrix circuit breaker before the stream sends anything // you have to hit a Hystrix circuit breaker before the stream sends anything
......
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