|
|
|
|
@ -16,6 +16,9 @@
@@ -16,6 +16,9 @@
|
|
|
|
|
|
|
|
|
|
package org.springframework.boot.actuate.endpoint.jmx; |
|
|
|
|
|
|
|
|
|
import java.net.URL; |
|
|
|
|
import java.net.URLClassLoader; |
|
|
|
|
|
|
|
|
|
import javax.management.Attribute; |
|
|
|
|
import javax.management.AttributeList; |
|
|
|
|
import javax.management.AttributeNotFoundException; |
|
|
|
|
@ -32,6 +35,7 @@ import reactor.core.publisher.Mono;
@@ -32,6 +35,7 @@ import reactor.core.publisher.Mono;
|
|
|
|
|
import org.springframework.beans.FatalBeanException; |
|
|
|
|
import org.springframework.boot.actuate.endpoint.InvalidEndpointRequestException; |
|
|
|
|
import org.springframework.boot.actuate.endpoint.InvocationContext; |
|
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat; |
|
|
|
|
import static org.hamcrest.CoreMatchers.instanceOf; |
|
|
|
|
@ -63,19 +67,19 @@ public class EndpointMBeanTests {
@@ -63,19 +67,19 @@ public class EndpointMBeanTests {
|
|
|
|
|
public void createWhenResponseMapperIsNullShouldThrowException() { |
|
|
|
|
this.thrown.expect(IllegalArgumentException.class); |
|
|
|
|
this.thrown.expectMessage("ResponseMapper must not be null"); |
|
|
|
|
new EndpointMBean(null, mock(ExposableJmxEndpoint.class)); |
|
|
|
|
new EndpointMBean(null, null, mock(ExposableJmxEndpoint.class)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
public void createWhenEndpointIsNullShouldThrowException() { |
|
|
|
|
this.thrown.expect(IllegalArgumentException.class); |
|
|
|
|
this.thrown.expectMessage("Endpoint must not be null"); |
|
|
|
|
new EndpointMBean(mock(JmxOperationResponseMapper.class), null); |
|
|
|
|
new EndpointMBean(mock(JmxOperationResponseMapper.class), null, null); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
public void getMBeanInfoShouldReturnMBeanInfo() { |
|
|
|
|
EndpointMBean bean = new EndpointMBean(this.responseMapper, this.endpoint); |
|
|
|
|
EndpointMBean bean = createEndpointMBean(); |
|
|
|
|
MBeanInfo info = bean.getMBeanInfo(); |
|
|
|
|
assertThat(info.getDescription()).isEqualTo("MBean operations for endpoint test"); |
|
|
|
|
} |
|
|
|
|
@ -83,7 +87,7 @@ public class EndpointMBeanTests {
@@ -83,7 +87,7 @@ public class EndpointMBeanTests {
|
|
|
|
|
@Test |
|
|
|
|
public void invokeShouldInvokeJmxOperation() |
|
|
|
|
throws MBeanException, ReflectionException { |
|
|
|
|
EndpointMBean bean = new EndpointMBean(this.responseMapper, this.endpoint); |
|
|
|
|
EndpointMBean bean = createEndpointMBean(); |
|
|
|
|
Object result = bean.invoke("testOperation", NO_PARAMS, NO_SIGNATURE); |
|
|
|
|
assertThat(result).isEqualTo("result"); |
|
|
|
|
} |
|
|
|
|
@ -95,7 +99,7 @@ public class EndpointMBeanTests {
@@ -95,7 +99,7 @@ public class EndpointMBeanTests {
|
|
|
|
|
new TestJmxOperation((arguments) -> { |
|
|
|
|
throw new FatalBeanException("test failure"); |
|
|
|
|
})); |
|
|
|
|
EndpointMBean bean = new EndpointMBean(this.responseMapper, endpoint); |
|
|
|
|
EndpointMBean bean = new EndpointMBean(this.responseMapper, null, endpoint); |
|
|
|
|
this.thrown.expect(MBeanException.class); |
|
|
|
|
this.thrown.expectCause(instanceOf(IllegalStateException.class)); |
|
|
|
|
this.thrown.expectMessage("test failure"); |
|
|
|
|
@ -109,7 +113,7 @@ public class EndpointMBeanTests {
@@ -109,7 +113,7 @@ public class EndpointMBeanTests {
|
|
|
|
|
new TestJmxOperation((arguments) -> { |
|
|
|
|
throw new UnsupportedOperationException("test failure"); |
|
|
|
|
})); |
|
|
|
|
EndpointMBean bean = new EndpointMBean(this.responseMapper, endpoint); |
|
|
|
|
EndpointMBean bean = new EndpointMBean(this.responseMapper, null, endpoint); |
|
|
|
|
this.thrown.expect(MBeanException.class); |
|
|
|
|
this.thrown.expectCause(instanceOf(UnsupportedOperationException.class)); |
|
|
|
|
this.thrown.expectMessage("test failure"); |
|
|
|
|
@ -119,13 +123,29 @@ public class EndpointMBeanTests {
@@ -119,13 +123,29 @@ public class EndpointMBeanTests {
|
|
|
|
|
@Test |
|
|
|
|
public void invokeWhenActionNameIsNotAnOperationShouldThrowException() |
|
|
|
|
throws MBeanException, ReflectionException { |
|
|
|
|
EndpointMBean bean = new EndpointMBean(this.responseMapper, this.endpoint); |
|
|
|
|
EndpointMBean bean = createEndpointMBean(); |
|
|
|
|
this.thrown.expect(ReflectionException.class); |
|
|
|
|
this.thrown.expectCause(instanceOf(IllegalArgumentException.class)); |
|
|
|
|
this.thrown.expectMessage("no operation named missingOperation"); |
|
|
|
|
bean.invoke("missingOperation", NO_PARAMS, NO_SIGNATURE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
public void invokeShouldInvokeJmxOperationWithBeanClassLoader() |
|
|
|
|
throws ReflectionException, MBeanException { |
|
|
|
|
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); |
|
|
|
|
TestExposableJmxEndpoint endpoint = new TestExposableJmxEndpoint( |
|
|
|
|
new TestJmxOperation((arguments) -> ClassUtils.getDefaultClassLoader())); |
|
|
|
|
URLClassLoader beanClassLoader = new URLClassLoader(new URL[0], |
|
|
|
|
getClass().getClassLoader()); |
|
|
|
|
EndpointMBean bean = new EndpointMBean(this.responseMapper, beanClassLoader, |
|
|
|
|
endpoint); |
|
|
|
|
Object result = bean.invoke("testOperation", NO_PARAMS, NO_SIGNATURE); |
|
|
|
|
assertThat(result).isEqualTo(beanClassLoader); |
|
|
|
|
assertThat(Thread.currentThread().getContextClassLoader()) |
|
|
|
|
.isEqualTo(originalClassLoader); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
public void invokeWhenOperationIsInvalidShouldThrowException() |
|
|
|
|
throws MBeanException, ReflectionException { |
|
|
|
|
@ -138,7 +158,7 @@ public class EndpointMBeanTests {
@@ -138,7 +158,7 @@ public class EndpointMBeanTests {
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
|
TestExposableJmxEndpoint endpoint = new TestExposableJmxEndpoint(operation); |
|
|
|
|
EndpointMBean bean = new EndpointMBean(this.responseMapper, endpoint); |
|
|
|
|
EndpointMBean bean = new EndpointMBean(this.responseMapper, null, endpoint); |
|
|
|
|
this.thrown.expect(ReflectionException.class); |
|
|
|
|
this.thrown.expectCause(instanceOf(IllegalArgumentException.class)); |
|
|
|
|
this.thrown.expectMessage("test failure"); |
|
|
|
|
@ -150,7 +170,7 @@ public class EndpointMBeanTests {
@@ -150,7 +170,7 @@ public class EndpointMBeanTests {
|
|
|
|
|
throws MBeanException, ReflectionException { |
|
|
|
|
TestExposableJmxEndpoint endpoint = new TestExposableJmxEndpoint( |
|
|
|
|
new TestJmxOperation((arguments) -> Mono.just("monoResult"))); |
|
|
|
|
EndpointMBean bean = new EndpointMBean(this.responseMapper, endpoint); |
|
|
|
|
EndpointMBean bean = new EndpointMBean(this.responseMapper, null, endpoint); |
|
|
|
|
Object result = bean.invoke("testOperation", NO_PARAMS, NO_SIGNATURE); |
|
|
|
|
assertThat(result).isEqualTo("monoResult"); |
|
|
|
|
} |
|
|
|
|
@ -159,7 +179,7 @@ public class EndpointMBeanTests {
@@ -159,7 +179,7 @@ public class EndpointMBeanTests {
|
|
|
|
|
public void invokeShouldCallResponseMapper() |
|
|
|
|
throws MBeanException, ReflectionException { |
|
|
|
|
TestJmxOperationResponseMapper responseMapper = spy(this.responseMapper); |
|
|
|
|
EndpointMBean bean = new EndpointMBean(responseMapper, this.endpoint); |
|
|
|
|
EndpointMBean bean = new EndpointMBean(responseMapper, null, this.endpoint); |
|
|
|
|
bean.invoke("testOperation", NO_PARAMS, NO_SIGNATURE); |
|
|
|
|
verify(responseMapper).mapResponseType(String.class); |
|
|
|
|
verify(responseMapper).mapResponse("result"); |
|
|
|
|
@ -168,7 +188,7 @@ public class EndpointMBeanTests {
@@ -168,7 +188,7 @@ public class EndpointMBeanTests {
|
|
|
|
|
@Test |
|
|
|
|
public void getAttributeShouldThrowException() |
|
|
|
|
throws AttributeNotFoundException, MBeanException, ReflectionException { |
|
|
|
|
EndpointMBean bean = new EndpointMBean(this.responseMapper, this.endpoint); |
|
|
|
|
EndpointMBean bean = createEndpointMBean(); |
|
|
|
|
this.thrown.expect(AttributeNotFoundException.class); |
|
|
|
|
this.thrown.expectMessage("EndpointMBeans do not support attributes"); |
|
|
|
|
bean.getAttribute("test"); |
|
|
|
|
@ -177,7 +197,7 @@ public class EndpointMBeanTests {
@@ -177,7 +197,7 @@ public class EndpointMBeanTests {
|
|
|
|
|
@Test |
|
|
|
|
public void setAttributeShouldThrowException() throws AttributeNotFoundException, |
|
|
|
|
InvalidAttributeValueException, MBeanException, ReflectionException { |
|
|
|
|
EndpointMBean bean = new EndpointMBean(this.responseMapper, this.endpoint); |
|
|
|
|
EndpointMBean bean = createEndpointMBean(); |
|
|
|
|
this.thrown.expect(AttributeNotFoundException.class); |
|
|
|
|
this.thrown.expectMessage("EndpointMBeans do not support attributes"); |
|
|
|
|
bean.setAttribute(new Attribute("test", "test")); |
|
|
|
|
@ -185,18 +205,22 @@ public class EndpointMBeanTests {
@@ -185,18 +205,22 @@ public class EndpointMBeanTests {
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
public void getAttributesShouldReturnEmptyAttributeList() { |
|
|
|
|
EndpointMBean bean = new EndpointMBean(this.responseMapper, this.endpoint); |
|
|
|
|
EndpointMBean bean = createEndpointMBean(); |
|
|
|
|
AttributeList attributes = bean.getAttributes(new String[] { "test" }); |
|
|
|
|
assertThat(attributes).isEmpty(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
public void setAttributesShouldReturnEmptyAttributeList() { |
|
|
|
|
EndpointMBean bean = new EndpointMBean(this.responseMapper, this.endpoint); |
|
|
|
|
EndpointMBean bean = createEndpointMBean(); |
|
|
|
|
AttributeList sourceAttributes = new AttributeList(); |
|
|
|
|
sourceAttributes.add(new Attribute("test", "test")); |
|
|
|
|
AttributeList attributes = bean.setAttributes(sourceAttributes); |
|
|
|
|
assertThat(attributes).isEmpty(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private EndpointMBean createEndpointMBean() { |
|
|
|
|
return new EndpointMBean(this.responseMapper, null, this.endpoint); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|