Ensure JMX endpoints are uniquely named in a context hierarchy
Closes gh-31718
This commit is contained in:
parent
043354f93b
commit
628c2cd0b1
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* 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.
|
||||
|
@ -43,6 +43,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
|||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
|
||||
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
|
||||
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
@ -86,7 +87,7 @@ public class JmxEndpointAutoConfiguration {
|
|||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(EndpointObjectNameFactory.class)
|
||||
@ConditionalOnMissingBean(value = EndpointObjectNameFactory.class, search = SearchStrategy.CURRENT)
|
||||
public DefaultEndpointObjectNameFactory endpointObjectNameFactory(MBeanServer mBeanServer,
|
||||
Environment environment) {
|
||||
String contextId = ObjectUtils.getIdentityHexString(this.applicationContext);
|
||||
|
|
|
@ -16,9 +16,13 @@
|
|||
|
||||
package org.springframework.boot.actuate.autoconfigure.endpoint.jmx;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
@ -35,8 +39,11 @@ import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
|
|||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
|
||||
/**
|
||||
* Tests for {@link JmxEndpointAutoConfiguration}.
|
||||
|
@ -78,6 +85,26 @@ class JmxEndpointAutoConfigurationTests {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void jmxEndpointWithContextHierarchyGeneratesUniqueNamesForEachEndpoint() throws Exception {
|
||||
given(this.mBeanServer.queryNames(any(), any()))
|
||||
.willReturn(new HashSet<>(Arrays.asList(new ObjectName("test:test=test"))));
|
||||
ArgumentCaptor<ObjectName> objectName = ArgumentCaptor.forClass(ObjectName.class);
|
||||
this.contextRunner.withPropertyValues("spring.jmx.enabled=true").with(mockMBeanServer()).run((parent) -> {
|
||||
this.contextRunner.withPropertyValues("spring.jmx.enabled=true").withParent(parent).run((child) -> {
|
||||
});
|
||||
this.contextRunner.withPropertyValues("spring.jmx.enabled=true").withParent(parent).run((child) -> {
|
||||
});
|
||||
});
|
||||
then(this.mBeanServer).should(times(3)).registerMBean(any(Object.class), objectName.capture());
|
||||
Set<ObjectName> uniqueValues = new HashSet<>(objectName.getAllValues());
|
||||
assertThat(uniqueValues).hasSize(3);
|
||||
assertThat(uniqueValues).allMatch((name) -> name.getDomain().equals("org.springframework.boot"));
|
||||
assertThat(uniqueValues).allMatch((name) -> name.getKeyProperty("type").equals("Endpoint"));
|
||||
assertThat(uniqueValues).allMatch((name) -> name.getKeyProperty("name").equals("Test"));
|
||||
assertThat(uniqueValues).allMatch((name) -> name.getKeyProperty("context") != null);
|
||||
}
|
||||
|
||||
private Function<ApplicationContextRunner, ApplicationContextRunner> mockMBeanServer() {
|
||||
return (ctxRunner) -> ctxRunner.withBean("mbeanServer", MBeanServer.class, () -> this.mBeanServer);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue