Merge branch '2.7.x'
This commit is contained in:
commit
cabfb98a89
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2019 the original author or authors.
|
* Copyright 2012-2022 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.
|
||||||
|
|
@ -22,7 +22,7 @@ import javax.management.ObjectName;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.endpoint.jmx.EndpointObjectNameFactory;
|
import org.springframework.boot.actuate.endpoint.jmx.EndpointObjectNameFactory;
|
||||||
import org.springframework.boot.actuate.endpoint.jmx.ExposableJmxEndpoint;
|
import org.springframework.boot.actuate.endpoint.jmx.ExposableJmxEndpoint;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.boot.autoconfigure.jmx.JmxProperties;
|
||||||
import org.springframework.jmx.support.ObjectNameManager;
|
import org.springframework.jmx.support.ObjectNameManager;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
@ -37,21 +37,18 @@ class DefaultEndpointObjectNameFactory implements EndpointObjectNameFactory {
|
||||||
|
|
||||||
private final JmxEndpointProperties properties;
|
private final JmxEndpointProperties properties;
|
||||||
|
|
||||||
private final Environment environment;
|
private final JmxProperties jmxProperties;
|
||||||
|
|
||||||
private final MBeanServer mBeanServer;
|
private final MBeanServer mBeanServer;
|
||||||
|
|
||||||
private final String contextId;
|
private final String contextId;
|
||||||
|
|
||||||
private final boolean uniqueNames;
|
DefaultEndpointObjectNameFactory(JmxEndpointProperties properties, JmxProperties jmxProperties,
|
||||||
|
MBeanServer mBeanServer, String contextId) {
|
||||||
DefaultEndpointObjectNameFactory(JmxEndpointProperties properties, Environment environment, MBeanServer mBeanServer,
|
|
||||||
String contextId) {
|
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
this.environment = environment;
|
this.jmxProperties = jmxProperties;
|
||||||
this.mBeanServer = mBeanServer;
|
this.mBeanServer = mBeanServer;
|
||||||
this.contextId = contextId;
|
this.contextId = contextId;
|
||||||
this.uniqueNames = environment.getProperty("spring.jmx.unique-names", Boolean.class, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -63,7 +60,7 @@ class DefaultEndpointObjectNameFactory implements EndpointObjectNameFactory {
|
||||||
if (this.mBeanServer != null && hasMBean(baseName)) {
|
if (this.mBeanServer != null && hasMBean(baseName)) {
|
||||||
builder.append(",context=").append(this.contextId);
|
builder.append(",context=").append(this.contextId);
|
||||||
}
|
}
|
||||||
if (this.uniqueNames) {
|
if (this.jmxProperties.isUniqueNames()) {
|
||||||
String identity = ObjectUtils.getIdentityHexString(endpoint);
|
String identity = ObjectUtils.getIdentityHexString(endpoint);
|
||||||
builder.append(",identity=").append(identity);
|
builder.append(",identity=").append(identity);
|
||||||
}
|
}
|
||||||
|
|
@ -75,7 +72,10 @@ class DefaultEndpointObjectNameFactory implements EndpointObjectNameFactory {
|
||||||
if (StringUtils.hasText(this.properties.getDomain())) {
|
if (StringUtils.hasText(this.properties.getDomain())) {
|
||||||
return this.properties.getDomain();
|
return this.properties.getDomain();
|
||||||
}
|
}
|
||||||
return this.environment.getProperty("spring.jmx.default-domain", "org.springframework.boot");
|
if (StringUtils.hasText(this.jmxProperties.getDefaultDomain())) {
|
||||||
|
return this.jmxProperties.getDefaultDomain();
|
||||||
|
}
|
||||||
|
return "org.springframework.boot";
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasMBean(String baseObjectName) throws MalformedObjectNameException {
|
private boolean hasMBean(String baseObjectName) throws MalformedObjectNameException {
|
||||||
|
|
|
||||||
|
|
@ -44,10 +44,10 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
|
||||||
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.jmx.JmxProperties;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -60,7 +60,7 @@ import org.springframework.util.ObjectUtils;
|
||||||
* @since 2.0.0
|
* @since 2.0.0
|
||||||
*/
|
*/
|
||||||
@AutoConfiguration(after = { JmxAutoConfiguration.class, EndpointAutoConfiguration.class })
|
@AutoConfiguration(after = { JmxAutoConfiguration.class, EndpointAutoConfiguration.class })
|
||||||
@EnableConfigurationProperties(JmxEndpointProperties.class)
|
@EnableConfigurationProperties({ JmxEndpointProperties.class, JmxProperties.class })
|
||||||
@ConditionalOnProperty(prefix = "spring.jmx", name = "enabled", havingValue = "true")
|
@ConditionalOnProperty(prefix = "spring.jmx", name = "enabled", havingValue = "true")
|
||||||
public class JmxEndpointAutoConfiguration {
|
public class JmxEndpointAutoConfiguration {
|
||||||
|
|
||||||
|
|
@ -68,9 +68,13 @@ public class JmxEndpointAutoConfiguration {
|
||||||
|
|
||||||
private final JmxEndpointProperties properties;
|
private final JmxEndpointProperties properties;
|
||||||
|
|
||||||
public JmxEndpointAutoConfiguration(ApplicationContext applicationContext, JmxEndpointProperties properties) {
|
private final JmxProperties jmxProperties;
|
||||||
|
|
||||||
|
public JmxEndpointAutoConfiguration(ApplicationContext applicationContext, JmxEndpointProperties properties,
|
||||||
|
JmxProperties jmxProperties) {
|
||||||
this.applicationContext = applicationContext;
|
this.applicationContext = applicationContext;
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
|
this.jmxProperties = jmxProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|
@ -85,10 +89,9 @@ public class JmxEndpointAutoConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(EndpointObjectNameFactory.class)
|
@ConditionalOnMissingBean(EndpointObjectNameFactory.class)
|
||||||
public DefaultEndpointObjectNameFactory endpointObjectNameFactory(MBeanServer mBeanServer,
|
public DefaultEndpointObjectNameFactory endpointObjectNameFactory(MBeanServer mBeanServer) {
|
||||||
Environment environment) {
|
|
||||||
String contextId = ObjectUtils.getIdentityHexString(this.applicationContext);
|
String contextId = ObjectUtils.getIdentityHexString(this.applicationContext);
|
||||||
return new DefaultEndpointObjectNameFactory(this.properties, environment, mBeanServer, contextId);
|
return new DefaultEndpointObjectNameFactory(this.properties, this.jmxProperties, mBeanServer, contextId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2019 the original author or authors.
|
* Copyright 2012-2022 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.
|
||||||
|
|
@ -26,7 +26,7 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.endpoint.EndpointId;
|
import org.springframework.boot.actuate.endpoint.EndpointId;
|
||||||
import org.springframework.boot.actuate.endpoint.jmx.ExposableJmxEndpoint;
|
import org.springframework.boot.actuate.endpoint.jmx.ExposableJmxEndpoint;
|
||||||
import org.springframework.mock.env.MockEnvironment;
|
import org.springframework.boot.autoconfigure.jmx.JmxProperties;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
@ -40,10 +40,10 @@ import static org.mockito.Mockito.mock;
|
||||||
*/
|
*/
|
||||||
class DefaultEndpointObjectNameFactoryTests {
|
class DefaultEndpointObjectNameFactoryTests {
|
||||||
|
|
||||||
private final MockEnvironment environment = new MockEnvironment();
|
|
||||||
|
|
||||||
private final JmxEndpointProperties properties = new JmxEndpointProperties();
|
private final JmxEndpointProperties properties = new JmxEndpointProperties();
|
||||||
|
|
||||||
|
private final JmxProperties jmxProperties = new JmxProperties();
|
||||||
|
|
||||||
private final MBeanServer mBeanServer = mock(MBeanServer.class);
|
private final MBeanServer mBeanServer = mock(MBeanServer.class);
|
||||||
|
|
||||||
private String contextId;
|
private String contextId;
|
||||||
|
|
@ -69,7 +69,7 @@ class DefaultEndpointObjectNameFactoryTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void generateObjectNameWithUniqueNames() {
|
void generateObjectNameWithUniqueNames() {
|
||||||
this.environment.setProperty("spring.jmx.unique-names", "true");
|
this.jmxProperties.setUniqueNames(true);
|
||||||
assertUniqueObjectName();
|
assertUniqueObjectName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,7 +103,7 @@ class DefaultEndpointObjectNameFactoryTests {
|
||||||
|
|
||||||
private ObjectName generateObjectName(ExposableJmxEndpoint endpoint) {
|
private ObjectName generateObjectName(ExposableJmxEndpoint endpoint) {
|
||||||
try {
|
try {
|
||||||
return new DefaultEndpointObjectNameFactory(this.properties, this.environment, this.mBeanServer,
|
return new DefaultEndpointObjectNameFactory(this.properties, this.jmxProperties, this.mBeanServer,
|
||||||
this.contextId).getObjectName(endpoint);
|
this.contextId).getObjectName(endpoint);
|
||||||
}
|
}
|
||||||
catch (MalformedObjectNameException ex) {
|
catch (MalformedObjectNameException ex) {
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandi
|
||||||
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
|
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.jmx.JmxProperties;
|
||||||
import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration;
|
import org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.sql.init.OnDatabaseInitializationCondition;
|
import org.springframework.boot.autoconfigure.sql.init.OnDatabaseInitializationCondition;
|
||||||
import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration;
|
import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration;
|
||||||
|
|
@ -46,7 +47,6 @@ import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Conditional;
|
import org.springframework.context.annotation.Conditional;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.integration.config.EnableIntegration;
|
import org.springframework.integration.config.EnableIntegration;
|
||||||
import org.springframework.integration.config.EnableIntegrationManagement;
|
import org.springframework.integration.config.EnableIntegrationManagement;
|
||||||
import org.springframework.integration.config.IntegrationManagementConfigurer;
|
import org.springframework.integration.config.IntegrationManagementConfigurer;
|
||||||
|
|
@ -84,7 +84,7 @@ import org.springframework.util.StringUtils;
|
||||||
@AutoConfiguration(after = { DataSourceAutoConfiguration.class, JmxAutoConfiguration.class,
|
@AutoConfiguration(after = { DataSourceAutoConfiguration.class, JmxAutoConfiguration.class,
|
||||||
TaskSchedulingAutoConfiguration.class })
|
TaskSchedulingAutoConfiguration.class })
|
||||||
@ConditionalOnClass(EnableIntegration.class)
|
@ConditionalOnClass(EnableIntegration.class)
|
||||||
@EnableConfigurationProperties(IntegrationProperties.class)
|
@EnableConfigurationProperties({ IntegrationProperties.class, JmxProperties.class })
|
||||||
public class IntegrationAutoConfiguration {
|
public class IntegrationAutoConfiguration {
|
||||||
|
|
||||||
@Bean(name = IntegrationContextUtils.INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME)
|
@Bean(name = IntegrationContextUtils.INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME)
|
||||||
|
|
@ -186,14 +186,13 @@ public class IntegrationAutoConfiguration {
|
||||||
protected static class IntegrationJmxConfiguration {
|
protected static class IntegrationJmxConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public IntegrationMBeanExporter integrationMbeanExporter(BeanFactory beanFactory, Environment environment) {
|
public IntegrationMBeanExporter integrationMbeanExporter(BeanFactory beanFactory, JmxProperties properties) {
|
||||||
IntegrationMBeanExporter exporter = new IntegrationMBeanExporter();
|
IntegrationMBeanExporter exporter = new IntegrationMBeanExporter();
|
||||||
String defaultDomain = environment.getProperty("spring.jmx.default-domain");
|
String defaultDomain = properties.getDefaultDomain();
|
||||||
if (StringUtils.hasLength(defaultDomain)) {
|
if (StringUtils.hasLength(defaultDomain)) {
|
||||||
exporter.setDefaultDomain(defaultDomain);
|
exporter.setDefaultDomain(defaultDomain);
|
||||||
}
|
}
|
||||||
String serverBean = environment.getProperty("spring.jmx.server", "mbeanServer");
|
exporter.setServer(beanFactory.getBean(properties.getServer(), MBeanServer.class));
|
||||||
exporter.setServer(beanFactory.getBean(serverBean, MBeanServer.class));
|
|
||||||
return exporter;
|
return exporter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,10 @@ 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.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
|
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.EnableMBeanExport;
|
import org.springframework.context.annotation.EnableMBeanExport;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.jmx.export.MBeanExporter;
|
import org.springframework.jmx.export.MBeanExporter;
|
||||||
import org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource;
|
import org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource;
|
||||||
import org.springframework.jmx.export.annotation.AnnotationMBeanExporter;
|
import org.springframework.jmx.export.annotation.AnnotationMBeanExporter;
|
||||||
|
|
@ -47,17 +47,19 @@ import org.springframework.util.StringUtils;
|
||||||
* @author Christian Dupuis
|
* @author Christian Dupuis
|
||||||
* @author Madhura Bhave
|
* @author Madhura Bhave
|
||||||
* @author Artsiom Yudovin
|
* @author Artsiom Yudovin
|
||||||
|
* @author Scott Frederick
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@AutoConfiguration
|
@AutoConfiguration
|
||||||
|
@EnableConfigurationProperties(JmxProperties.class)
|
||||||
@ConditionalOnClass({ MBeanExporter.class })
|
@ConditionalOnClass({ MBeanExporter.class })
|
||||||
@ConditionalOnProperty(prefix = "spring.jmx", name = "enabled", havingValue = "true")
|
@ConditionalOnProperty(prefix = "spring.jmx", name = "enabled", havingValue = "true")
|
||||||
public class JmxAutoConfiguration {
|
public class JmxAutoConfiguration {
|
||||||
|
|
||||||
private final Environment environment;
|
private final JmxProperties properties;
|
||||||
|
|
||||||
public JmxAutoConfiguration(Environment environment) {
|
public JmxAutoConfiguration(JmxProperties properties) {
|
||||||
this.environment = environment;
|
this.properties = properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|
@ -67,10 +69,11 @@ public class JmxAutoConfiguration {
|
||||||
AnnotationMBeanExporter exporter = new AnnotationMBeanExporter();
|
AnnotationMBeanExporter exporter = new AnnotationMBeanExporter();
|
||||||
exporter.setRegistrationPolicy(RegistrationPolicy.FAIL_ON_EXISTING);
|
exporter.setRegistrationPolicy(RegistrationPolicy.FAIL_ON_EXISTING);
|
||||||
exporter.setNamingStrategy(namingStrategy);
|
exporter.setNamingStrategy(namingStrategy);
|
||||||
String serverBean = this.environment.getProperty("spring.jmx.server", "mbeanServer");
|
String serverBean = this.properties.getServer();
|
||||||
if (StringUtils.hasLength(serverBean)) {
|
if (StringUtils.hasLength(serverBean)) {
|
||||||
exporter.setServer(beanFactory.getBean(serverBean, MBeanServer.class));
|
exporter.setServer(beanFactory.getBean(serverBean, MBeanServer.class));
|
||||||
}
|
}
|
||||||
|
exporter.setEnsureUniqueRuntimeObjectNames(this.properties.isUniqueNames());
|
||||||
return exporter;
|
return exporter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,12 +81,11 @@ public class JmxAutoConfiguration {
|
||||||
@ConditionalOnMissingBean(value = ObjectNamingStrategy.class, search = SearchStrategy.CURRENT)
|
@ConditionalOnMissingBean(value = ObjectNamingStrategy.class, search = SearchStrategy.CURRENT)
|
||||||
public ParentAwareNamingStrategy objectNamingStrategy() {
|
public ParentAwareNamingStrategy objectNamingStrategy() {
|
||||||
ParentAwareNamingStrategy namingStrategy = new ParentAwareNamingStrategy(new AnnotationJmxAttributeSource());
|
ParentAwareNamingStrategy namingStrategy = new ParentAwareNamingStrategy(new AnnotationJmxAttributeSource());
|
||||||
String defaultDomain = this.environment.getProperty("spring.jmx.default-domain");
|
String defaultDomain = this.properties.getDefaultDomain();
|
||||||
if (StringUtils.hasLength(defaultDomain)) {
|
if (StringUtils.hasLength(defaultDomain)) {
|
||||||
namingStrategy.setDefaultDomain(defaultDomain);
|
namingStrategy.setDefaultDomain(defaultDomain);
|
||||||
}
|
}
|
||||||
boolean uniqueNames = this.environment.getProperty("spring.jmx.unique-names", Boolean.class, false);
|
namingStrategy.setEnsureUniqueRuntimeObjectNames(this.properties.isUniqueNames());
|
||||||
namingStrategy.setEnsureUniqueRuntimeObjectNames(uniqueNames);
|
|
||||||
return namingStrategy;
|
return namingStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2022 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
|
||||||
|
*
|
||||||
|
* https://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.autoconfigure.jmx;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration properties for JMX.
|
||||||
|
*
|
||||||
|
* @author Scott Frederick
|
||||||
|
* @since 2.7.0
|
||||||
|
*/
|
||||||
|
@ConfigurationProperties(prefix = "spring.jmx")
|
||||||
|
public class JmxProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose management beans to the JMX domain.
|
||||||
|
*/
|
||||||
|
private boolean enabled = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether unique runtime object names should be ensured.
|
||||||
|
*/
|
||||||
|
private boolean uniqueNames = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MBeanServer bean name.
|
||||||
|
*/
|
||||||
|
private String server = "mbeanServer";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JMX domain name.
|
||||||
|
*/
|
||||||
|
private String defaultDomain;
|
||||||
|
|
||||||
|
public boolean getEnabled() {
|
||||||
|
return this.enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUniqueNames() {
|
||||||
|
return this.uniqueNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUniqueNames(boolean uniqueNames) {
|
||||||
|
this.uniqueNames = uniqueNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServer() {
|
||||||
|
return this.server;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServer(String server) {
|
||||||
|
this.server = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDefaultDomain() {
|
||||||
|
return this.defaultDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultDomain(String defaultDomain) {
|
||||||
|
this.defaultDomain = defaultDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1108,29 +1108,6 @@
|
||||||
"level": "error"
|
"level": "error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "spring.jmx.default-domain",
|
|
||||||
"type": "java.lang.String",
|
|
||||||
"description": "JMX domain name."
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "spring.jmx.enabled",
|
|
||||||
"type": "java.lang.Boolean",
|
|
||||||
"description": "Expose management beans to the JMX domain.",
|
|
||||||
"defaultValue": false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "spring.jmx.server",
|
|
||||||
"type": "java.lang.String",
|
|
||||||
"description": "MBeanServer bean name.",
|
|
||||||
"defaultValue": "mbeanServer"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "spring.jmx.unique-names",
|
|
||||||
"type": "java.lang.Boolean",
|
|
||||||
"description": "Whether unique runtime object names should be ensured.",
|
|
||||||
"defaultValue": false
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "spring.jpa.open-in-view",
|
"name": "spring.jpa.open-in-view",
|
||||||
"defaultValue": true
|
"defaultValue": true
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2019 the original author or authors.
|
* Copyright 2012-2022 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,12 +16,12 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.jmx;
|
package org.springframework.boot.autoconfigure.jmx;
|
||||||
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||||
import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration;
|
import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration;
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
import org.springframework.boot.context.annotation.UserConfigurations;
|
||||||
|
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
@ -32,114 +32,95 @@ import org.springframework.jmx.export.annotation.ManagedAttribute;
|
||||||
import org.springframework.jmx.export.annotation.ManagedOperation;
|
import org.springframework.jmx.export.annotation.ManagedOperation;
|
||||||
import org.springframework.jmx.export.annotation.ManagedResource;
|
import org.springframework.jmx.export.annotation.ManagedResource;
|
||||||
import org.springframework.jmx.export.naming.MetadataNamingStrategy;
|
import org.springframework.jmx.export.naming.MetadataNamingStrategy;
|
||||||
import org.springframework.mock.env.MockEnvironment;
|
import org.springframework.jmx.export.naming.ObjectNamingStrategy;
|
||||||
import org.springframework.test.util.ReflectionTestUtils;
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link JmxAutoConfiguration}.
|
* Tests for {@link JmxAutoConfiguration}.
|
||||||
*
|
*
|
||||||
* @author Christian Dupuis
|
* @author Christian Dupuis
|
||||||
* @author Artsiom Yudovin
|
* @author Artsiom Yudovin
|
||||||
|
* @author Scott Frederick
|
||||||
*/
|
*/
|
||||||
class JmxAutoConfigurationTests {
|
class JmxAutoConfigurationTests {
|
||||||
|
|
||||||
private AnnotationConfigApplicationContext context;
|
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||||
|
.withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class));
|
||||||
@AfterEach
|
|
||||||
void tearDown() {
|
|
||||||
if (this.context != null) {
|
|
||||||
this.context.close();
|
|
||||||
if (this.context.getParent() != null) {
|
|
||||||
((ConfigurableApplicationContext) this.context.getParent()).close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testDefaultMBeanExport() {
|
void testDefaultMBeanExport() {
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
this.contextRunner.run((context) -> {
|
||||||
this.context.register(JmxAutoConfiguration.class);
|
assertThat(context).doesNotHaveBean(MBeanExporter.class);
|
||||||
this.context.refresh();
|
assertThat(context).doesNotHaveBean(ObjectNamingStrategy.class);
|
||||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
});
|
||||||
.isThrownBy(() -> this.context.getBean(MBeanExporter.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testEnabledMBeanExport() {
|
|
||||||
MockEnvironment env = new MockEnvironment();
|
|
||||||
env.setProperty("spring.jmx.enabled", "true");
|
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
|
||||||
this.context.setEnvironment(env);
|
|
||||||
this.context.register(JmxAutoConfiguration.class);
|
|
||||||
this.context.refresh();
|
|
||||||
assertThat(this.context.getBean(MBeanExporter.class)).isNotNull();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testDisabledMBeanExport() {
|
void testDisabledMBeanExport() {
|
||||||
MockEnvironment env = new MockEnvironment();
|
this.contextRunner.withPropertyValues("spring.jmx.enabled=false").run((context) -> {
|
||||||
env.setProperty("spring.jmx.enabled", "false");
|
assertThat(context).doesNotHaveBean(MBeanExporter.class);
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
assertThat(context).doesNotHaveBean(ObjectNamingStrategy.class);
|
||||||
this.context.setEnvironment(env);
|
});
|
||||||
this.context.register(TestConfiguration.class, JmxAutoConfiguration.class);
|
}
|
||||||
this.context.refresh();
|
|
||||||
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
@Test
|
||||||
.isThrownBy(() -> this.context.getBean(MBeanExporter.class));
|
void testEnabledMBeanExport() {
|
||||||
|
this.contextRunner.withPropertyValues("spring.jmx.enabled=true").run((context) -> {
|
||||||
|
assertThat(context).hasSingleBean(MBeanExporter.class);
|
||||||
|
assertThat(context).hasSingleBean(ParentAwareNamingStrategy.class);
|
||||||
|
MBeanExporter exporter = context.getBean(MBeanExporter.class);
|
||||||
|
assertThat(exporter).hasFieldOrPropertyWithValue("ensureUniqueRuntimeObjectNames", false);
|
||||||
|
MetadataNamingStrategy naming = (MetadataNamingStrategy) ReflectionTestUtils.getField(exporter,
|
||||||
|
"namingStrategy");
|
||||||
|
assertThat(naming).hasFieldOrPropertyWithValue("ensureUniqueRuntimeObjectNames", false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testDefaultDomainConfiguredOnMBeanExport() {
|
void testDefaultDomainConfiguredOnMBeanExport() {
|
||||||
MockEnvironment env = new MockEnvironment();
|
this.contextRunner.withPropertyValues("spring.jmx.enabled=true", "spring.jmx.default-domain=my-test-domain",
|
||||||
env.setProperty("spring.jmx.enabled", "true");
|
"spring.jmx.unique-names=true").run((context) -> {
|
||||||
env.setProperty("spring.jmx.default-domain", "my-test-domain");
|
assertThat(context).hasSingleBean(MBeanExporter.class);
|
||||||
env.setProperty("spring.jmx.unique-names", "true");
|
MBeanExporter exporter = context.getBean(MBeanExporter.class);
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
assertThat(exporter).hasFieldOrPropertyWithValue("ensureUniqueRuntimeObjectNames", true);
|
||||||
this.context.setEnvironment(env);
|
MetadataNamingStrategy naming = (MetadataNamingStrategy) ReflectionTestUtils.getField(exporter,
|
||||||
this.context.register(TestConfiguration.class, JmxAutoConfiguration.class);
|
"namingStrategy");
|
||||||
this.context.refresh();
|
assertThat(naming).hasFieldOrPropertyWithValue("defaultDomain", "my-test-domain");
|
||||||
MBeanExporter mBeanExporter = this.context.getBean(MBeanExporter.class);
|
assertThat(naming).hasFieldOrPropertyWithValue("ensureUniqueRuntimeObjectNames", true);
|
||||||
assertThat(mBeanExporter).isNotNull();
|
});
|
||||||
MetadataNamingStrategy naming = (MetadataNamingStrategy) ReflectionTestUtils.getField(mBeanExporter,
|
|
||||||
"namingStrategy");
|
|
||||||
assertThat(naming).hasFieldOrPropertyWithValue("defaultDomain", "my-test-domain");
|
|
||||||
assertThat(naming).hasFieldOrPropertyWithValue("ensureUniqueRuntimeObjectNames", true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testBasicParentContext() {
|
void testBasicParentContext() {
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
try (AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext()) {
|
||||||
this.context.register(JmxAutoConfiguration.class);
|
parent.register(JmxAutoConfiguration.class);
|
||||||
this.context.refresh();
|
parent.refresh();
|
||||||
AnnotationConfigApplicationContext parent = this.context;
|
this.contextRunner.withParent(parent).run((context) -> assertThat(context.isRunning()));
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
}
|
||||||
this.context.setParent(parent);
|
|
||||||
this.context.register(JmxAutoConfiguration.class);
|
|
||||||
this.context.refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testParentContext() {
|
void testParentContext() {
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
try (AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext()) {
|
||||||
this.context.register(JmxAutoConfiguration.class, TestConfiguration.class);
|
parent.register(JmxAutoConfiguration.class, TestConfiguration.class);
|
||||||
this.context.refresh();
|
parent.refresh();
|
||||||
AnnotationConfigApplicationContext parent = this.context;
|
this.contextRunner.withParent(parent).withConfiguration(UserConfigurations.of(TestConfiguration.class))
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
.run((context) -> assertThat(context.isRunning()));
|
||||||
this.context.setParent(parent);
|
}
|
||||||
this.context.register(JmxAutoConfiguration.class, TestConfiguration.class);
|
|
||||||
this.context.refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void customJmxDomain() {
|
void customJmxDomain() {
|
||||||
this.context = new AnnotationConfigApplicationContext();
|
this.contextRunner.withConfiguration(UserConfigurations.of(CustomJmxDomainConfiguration.class))
|
||||||
this.context.register(CustomJmxDomainConfiguration.class, JmxAutoConfiguration.class,
|
.withConfiguration(
|
||||||
IntegrationAutoConfiguration.class);
|
AutoConfigurations.of(JmxAutoConfiguration.class, IntegrationAutoConfiguration.class))
|
||||||
this.context.refresh();
|
.run((context) -> {
|
||||||
IntegrationMBeanExporter mbeanExporter = this.context.getBean(IntegrationMBeanExporter.class);
|
assertThat(context).hasSingleBean(IntegrationMBeanExporter.class);
|
||||||
assertThat(mbeanExporter).hasFieldOrPropertyWithValue("domain", "foo.my");
|
IntegrationMBeanExporter exporter = context.getBean(IntegrationMBeanExporter.class);
|
||||||
|
assertThat(exporter).hasFieldOrPropertyWithValue("domain", "foo.my");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue