diff --git a/org.springframework.integration.jmx/.classpath b/org.springframework.integration.jmx/.classpath index e4250ac755..2ed41b03f4 100644 --- a/org.springframework.integration.jmx/.classpath +++ b/org.springframework.integration.jmx/.classpath @@ -10,6 +10,7 @@ + diff --git a/org.springframework.integration.jmx/ivy.xml b/org.springframework.integration.jmx/ivy.xml index f41c1ca30a..8f7a042c8a 100644 --- a/org.springframework.integration.jmx/ivy.xml +++ b/org.springframework.integration.jmx/ivy.xml @@ -22,6 +22,7 @@ + diff --git a/org.springframework.integration.jmx/src/main/java/org/springframework/integration/jmx/OperationInvokingHandler.java b/org.springframework.integration.jmx/src/main/java/org/springframework/integration/jmx/OperationInvokingHandler.java index 4b2947af55..a238d20714 100644 --- a/org.springframework.integration.jmx/src/main/java/org/springframework/integration/jmx/OperationInvokingHandler.java +++ b/org.springframework.integration.jmx/src/main/java/org/springframework/integration/jmx/OperationInvokingHandler.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; import javax.management.JMException; +import javax.management.MBeanInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanParameterInfo; import javax.management.MBeanServer; @@ -39,7 +40,17 @@ import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; /** + * As the name suggests this MessageHandler will invoke JMX operation after resolving theÊ + * 'objectName', 'operationName' and mapping operation parameters from the message payload. + * When operation has multiple parameters they could be provided as List or Map payload. + * Both 'objectName' and 'operationName' could be provided inÊtwo different ways;
+ * 1. Setting 'defaultObjectName' via {@link #setDefaultObjectName(String)} and + * 'defaultOperationName' via {@link #setDefaultOperationName(String)}
+ * 2. Supplying values with Message headers such as {@link JmxHeaders#OBJECT_NAME} + * and {@link JmxHeaders#OPERATION_NAME}
+ * * @author Mark Fisher + * @author Oleg Zhurakousky * @since 2.0 */ public class OperationInvokingHandler extends AbstractReplyProducingMessageHandler implements InitializingBean { @@ -80,7 +91,8 @@ public class OperationInvokingHandler extends AbstractReplyProducingMessageHandl String operationName = this.resolveOperationName(requestMessage); Map paramsFromMessage = this.resolveParameters(requestMessage); try { - MBeanOperationInfo[] opInfoArray = this.server.getMBeanInfo(objectName).getOperations(); + MBeanInfo mbeanInfo = this.server.getMBeanInfo(objectName); + MBeanOperationInfo[] opInfoArray = mbeanInfo.getOperations(); boolean hasNoArgOption = false; for (MBeanOperationInfo opInfo : opInfoArray) { if (operationName.equals(opInfo.getName())) { @@ -110,11 +122,14 @@ public class OperationInvokingHandler extends AbstractReplyProducingMessageHandl return this.server.invoke(objectName, operationName, null, null); } throw new MessagingException(requestMessage, "failed to find JMX operation '" - + operationName + "' on MBean [" + objectName + "]"); + + operationName + "' on MBean [" + objectName + "]" + " (implClass:" + mbeanInfo.getClassName() + + ")" + " with " + paramsFromMessage.size() + " parameters: " + + paramsFromMessage.keySet()); } catch (JMException e) { throw new MessageHandlingException(requestMessage, "failed to invoke JMX operation '" + - operationName + "' on MBean [" + objectName + "]", e); + operationName + "' on MBean [" + objectName + "]" + " with " + + paramsFromMessage.size() + " parameters: " + paramsFromMessage.keySet(), e); } } diff --git a/org.springframework.integration.jmx/src/test/java/org/springframework/integration/jmx/OperationInvokingHandlerTests.java b/org.springframework.integration.jmx/src/test/java/org/springframework/integration/jmx/OperationInvokingHandlerTests.java index 53087ad6fc..54dd87ebcf 100644 --- a/org.springframework.integration.jmx/src/test/java/org/springframework/integration/jmx/OperationInvokingHandlerTests.java +++ b/org.springframework.integration.jmx/src/test/java/org/springframework/integration/jmx/OperationInvokingHandlerTests.java @@ -32,12 +32,14 @@ import org.junit.Test; import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.core.Message; +import org.springframework.integration.core.MessagingException; import org.springframework.integration.message.MessageBuilder; import org.springframework.jmx.support.MBeanServerFactoryBean; import org.springframework.jmx.support.ObjectNameManager; /** * @author Mark Fisher + * @author Oleg Zhurakousky * @since 2.0 */ public class OperationInvokingHandlerTests { @@ -80,6 +82,37 @@ public class OperationInvokingHandlerTests { assertNotNull(reply); assertEquals("foobar", reply.getPayload()); } + + @Test + public void invocationWithPayloadNoReturnValue() throws Exception { + QueueChannel outputChannel = new QueueChannel(); + OperationInvokingHandler handler = new OperationInvokingHandler(); + handler.setServer(this.server); + handler.setDefaultObjectName(this.objectName); + handler.setOutputChannel(outputChannel); + handler.afterPropertiesSet(); + Message message = MessageBuilder.withPayload("foo") + .setHeader(JmxHeaders.OPERATION_NAME, "y").build(); + handler.handleMessage(message); + } + + @Test(expected=MessagingException.class) + public void invocationWithMapPayloadNotEnoughParameters() throws Exception { + QueueChannel outputChannel = new QueueChannel(); + OperationInvokingHandler handler = new OperationInvokingHandler(); + handler.setServer(this.server); + handler.setDefaultObjectName(this.objectName); + handler.setOutputChannel(outputChannel); + handler.afterPropertiesSet(); + Map params = new HashMap(); + params.put("p1", "foo"); + Message message = MessageBuilder.withPayload(params) + .setHeader(JmxHeaders.OPERATION_NAME, "x").build(); + handler.handleMessage(message); + Message reply = outputChannel.receive(0); + assertNotNull(reply); + assertEquals("foobar", reply.getPayload()); + } @Test public void invocationWithListPayload() throws Exception { @@ -98,12 +131,13 @@ public class OperationInvokingHandlerTests { assertEquals("foo123", reply.getPayload()); } - public static interface TestOpsMBean { String x(String s1, String s2); String x(String s, Integer i); + + void y(String s); } @@ -116,6 +150,8 @@ public class OperationInvokingHandlerTests { public String x(String s, Integer i) { return s + i; } + + public void y(String s){} } }