Add auto configure support for Jolokia a JMX-HTTP bridge

This commit is contained in:
Christian Dupuis 2013-11-22 18:05:27 +01:00
parent b14c607d36
commit 2d058570ca
6 changed files with 301 additions and 1 deletions

View File

@ -65,7 +65,7 @@
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<optional>true</optional>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
@ -77,6 +77,11 @@
<artifactId>crash.embed.spring</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-core</artifactId>
<optional>true</optional>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework</groupId>

View File

@ -0,0 +1,103 @@
/*
* Copyright 2013 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.boot.actuate.autoconfigure;
import java.util.Map;
import org.jolokia.http.AgentServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.JolokiaEndpoint;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
/**
* {@link EnableAutoConfiguration Auto-configuration} for embedding Jolokia, a JMX-HTTP
* bridge giving an alternative to JSR-160 connectors.
*
* <p>
* This configuration will get automatically enabled as soon as the Jolokia
* {@link AgentServlet} is on the classpath. To disable set
* <code>endpoints.jolokia.enabled: false</code>.
*
* <p>
* Additional configuration parameters for Jolokia can be provided by specifying
* <code>jolokia.config. ...</code> properties. See the <a
* href="http://jolokia.org">http://jolokia.org</a> web site for more information on
* supported configuration parameters.
*
* @author Christian Dupuis
*/
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({ AgentServlet.class })
@ConditionalOnBean(EmbeddedServletContainerFactory.class)
@AutoConfigureBefore(ManagementSecurityAutoConfiguration.class)
@AutoConfigureAfter(EmbeddedServletContainerAutoConfiguration.class)
@ConditionalOnExpression("${endpoints.jolokia.enabled:true}")
public class JolokiaAutoConfiguration {
private RelaxedPropertyResolver environment;
@Autowired
public void setEnvironment(Environment environment) {
this.environment = new RelaxedPropertyResolver(environment);
}
@Bean
@ConditionalOnMissingBean({ AgentServlet.class })
public AgentServlet jolokiaServlet() {
return new AgentServlet();
}
@Bean
@ConditionalOnMissingBean()
public ServletRegistrationBean jolokiaServletRegistration() {
ServletRegistrationBean registrationBean = new ServletRegistrationBean(
jolokiaServlet(), this.environment.getProperty("endpoints.jolokia.path",
"/jolokia") + "/*");
addInitParameters(registrationBean);
return registrationBean;
}
@Bean
@ConditionalOnMissingBean
public JolokiaEndpoint jolokiaEndpoint() {
return new JolokiaEndpoint();
}
protected void addInitParameters(ServletRegistrationBean registrationBean) {
Map<String, Object> configParameters = this.environment
.getSubProperties("jolokia.config.");
for (Map.Entry<String, Object> configParameter : configParameters.entrySet()) {
registrationBean.addInitParameter(configParameter.getKey(), configParameter
.getValue().toString());
}
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright 2013 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.boot.actuate.endpoint;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.http.HttpMethod;
/**
* {@link Endpoint} implementation to register the Jolokia infrastructure with the Boot
* management subsystem.
*
* @author Christian Dupuis
*/
@ConfigurationProperties(name = "endpoints.jolokia", ignoreUnknownFields = false)
public class JolokiaEndpoint extends AbstractEndpoint<String> {
public JolokiaEndpoint() {
super("/jolokia");
}
@Override
public String invoke() {
return null;
}
@Override
public HttpMethod[] methods() {
return NO_HTTP_METHOD;
}
}

View File

@ -4,6 +4,7 @@ org.springframework.boot.actuate.autoconfigure.CrshAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.ErrorMvcAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.JolokiaAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.ManagementServerPropertiesAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.MetricFilterAutoConfiguration,\
org.springframework.boot.actuate.autoconfigure.MetricRepositoryAutoConfiguration,\

View File

@ -0,0 +1,105 @@
/*
* Copyright 2013 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.boot.actuate.autoconfigure;
import javax.servlet.Servlet;
import javax.servlet.ServletRegistration;
import org.jolokia.http.AgentServlet;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration;
import org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.MockEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.MockEmbeddedServletContainerFactory.RegisteredServlet;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* Tests for {@link JolokiaAutoConfiguration}.
*
* @author Christian Dupuis
*/
public class JolokiaAutoConfigurationTests {
private AnnotationConfigEmbeddedWebApplicationContext context;
@After
public void close() {
if (this.context != null) {
this.context.close();
}
if (Config.containerFactory != null) {
Config.containerFactory = null;
}
}
@Test
public void agentServletRegisteredWithAppContext() throws Exception {
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
this.context.register(Config.class, WebMvcAutoConfiguration.class,
JolokiaAutoConfiguration.class);
this.context.refresh();
assertEquals(1, this.context.getBeanNamesForType(AgentServlet.class).length);
}
@Test
public void agentServletRegisteredWithServletContainer() throws Exception {
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
this.context.register(Config.class, WebMvcAutoConfiguration.class,
JolokiaAutoConfiguration.class);
this.context.refresh();
Servlet servlet = null;
ServletRegistration.Dynamic registration = null;
for (RegisteredServlet registeredServlet : Config.containerFactory.getContainer()
.getRegisteredServlets()) {
if (registeredServlet.getServlet() instanceof AgentServlet) {
servlet = registeredServlet.getServlet();
registration = registeredServlet.getRegistration();
}
}
assertNotNull(servlet);
assertNotNull(registration);
}
@Configuration
protected static class Config {
protected static MockEmbeddedServletContainerFactory containerFactory = null;
@Bean
public EmbeddedServletContainerFactory containerFactory() {
if (containerFactory == null) {
containerFactory = new MockEmbeddedServletContainerFactory();
}
return containerFactory;
}
@Bean
public EmbeddedServletContainerCustomizerBeanPostProcessor embeddedServletContainerCustomizerBeanPostProcessor() {
return new EmbeddedServletContainerCustomizerBeanPostProcessor();
}
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright 2013 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.boot.actuate.endpoint;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Christian Dupuis
*/
public class JolokiaEndpointTests extends AbstractEndpointTests<JolokiaEndpoint> {
public JolokiaEndpointTests() {
super(Config.class, JolokiaEndpoint.class, "/jolokia", true, "endpoints.jolokia");
}
@Configuration
@EnableConfigurationProperties
public static class Config {
@Bean
public JolokiaEndpoint endpoint() {
return new JolokiaEndpoint();
}
}
}