BAEL 5842 - Calling JMX MBean Method from a Shell Script (#13028)
* bael 5842 * bael-5842 - editor review 1
This commit is contained in:
parent
0fd77aa664
commit
88f2eca118
|
@ -0,0 +1,25 @@
|
||||||
|
package com.baeldung.jmxshell;
|
||||||
|
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
import javax.management.MBeanServer;
|
||||||
|
import javax.management.ObjectName;
|
||||||
|
|
||||||
|
import com.baeldung.jmxshell.bean.Calculator;
|
||||||
|
|
||||||
|
public class JmxCalculatorMain {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
|
||||||
|
server.registerMBean(new Calculator(), new ObjectName("com.baeldung.jxmshell:type=basic,name=calculator"));
|
||||||
|
|
||||||
|
System.out.printf("mbean registered. pid: %s\n", ManagementFactory.getRuntimeMXBean()
|
||||||
|
.getName());
|
||||||
|
|
||||||
|
try (Scanner scanner = new Scanner(System.in)) {
|
||||||
|
System.out.println("<press enter to terminate>");
|
||||||
|
scanner.nextLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.baeldung.jmxshell.bean;
|
||||||
|
|
||||||
|
public class Calculator implements CalculatorMBean {
|
||||||
|
|
||||||
|
private Integer a = 0;
|
||||||
|
private Integer b = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer sum() {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getA() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setA(Integer a) {
|
||||||
|
this.a = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getB() {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setB(Integer b) {
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.baeldung.jmxshell.bean;
|
||||||
|
|
||||||
|
public interface CalculatorMBean {
|
||||||
|
|
||||||
|
Integer sum();
|
||||||
|
|
||||||
|
Integer getA();
|
||||||
|
|
||||||
|
void setA(Integer a);
|
||||||
|
|
||||||
|
Integer getB();
|
||||||
|
|
||||||
|
void setB(Integer b);
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.baeldung.jmxshell.custom;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import javax.management.Attribute;
|
||||||
|
import javax.management.MBeanAttributeInfo;
|
||||||
|
import javax.management.MBeanInfo;
|
||||||
|
import javax.management.MBeanServerConnection;
|
||||||
|
import javax.management.ObjectName;
|
||||||
|
import javax.management.remote.JMXConnectorFactory;
|
||||||
|
import javax.management.remote.JMXServiceURL;
|
||||||
|
|
||||||
|
public class JmxConnectionWrapper {
|
||||||
|
|
||||||
|
private final Map<String, MBeanAttributeInfo> attributeMap;
|
||||||
|
private final MBeanServerConnection connection;
|
||||||
|
private final ObjectName objectName;
|
||||||
|
|
||||||
|
public JmxConnectionWrapper(String url, String beanName) throws Exception {
|
||||||
|
objectName = new ObjectName(beanName);
|
||||||
|
|
||||||
|
connection = JMXConnectorFactory.connect(new JMXServiceURL(url))
|
||||||
|
.getMBeanServerConnection();
|
||||||
|
|
||||||
|
MBeanInfo bean = connection.getMBeanInfo(objectName);
|
||||||
|
MBeanAttributeInfo[] attributes = bean.getAttributes();
|
||||||
|
|
||||||
|
this.attributeMap = Stream.of(attributes)
|
||||||
|
.peek(System.out::println)
|
||||||
|
.collect(Collectors.toMap(MBeanAttributeInfo::getName, Function.identity()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasAttribute(String attributeName) {
|
||||||
|
return attributeMap.containsKey(attributeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object attributeValue(String name, String value) throws Exception {
|
||||||
|
if (value != null) {
|
||||||
|
connection.setAttribute(objectName, new Attribute(name, parse(value)));
|
||||||
|
}
|
||||||
|
return connection.getAttribute(objectName, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object invoke(String operation) throws Exception {
|
||||||
|
String[] signature = new String[] {};
|
||||||
|
Object[] params = new Object[] {};
|
||||||
|
|
||||||
|
return connection.invoke(objectName, operation, params, signature);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object parse(String value) {
|
||||||
|
if (value == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (value.matches("\\d+")) {
|
||||||
|
return Integer.valueOf(value);
|
||||||
|
} else if (value.trim()
|
||||||
|
.toLowerCase()
|
||||||
|
.matches("true|false")) {
|
||||||
|
return Boolean.valueOf(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value.equals("null") ? null : value;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.baeldung.jmxshell.custom;
|
||||||
|
|
||||||
|
public class JmxInvoker {
|
||||||
|
|
||||||
|
public static void main(String... args) throws Exception {
|
||||||
|
String serviceURL = args[0];
|
||||||
|
String name = args[1];
|
||||||
|
String operation = args[2];
|
||||||
|
String attributeValue = null;
|
||||||
|
if (args.length > 3) {
|
||||||
|
attributeValue = args[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
String result = execute(serviceURL, name, operation, attributeValue);
|
||||||
|
System.out.println(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String execute(String url, String mBeanName, String operation, String attributeValue) {
|
||||||
|
try {
|
||||||
|
JmxConnectionWrapper connection = new JmxConnectionWrapper(url, mBeanName);
|
||||||
|
|
||||||
|
if (connection.hasAttribute(operation)) {
|
||||||
|
Object value = connection.attributeValue(operation, attributeValue);
|
||||||
|
return operation + "=" + value;
|
||||||
|
} else {
|
||||||
|
Object result = connection.invoke(operation);
|
||||||
|
return operation + "(): " + result;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return e.getClass() + ": " + e.getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
#!/bin/sh
|
||||||
|
jar='/tmp/core-java-perf.jar'
|
||||||
|
address='localhost:11234'
|
||||||
|
mbean='com.baeldung.jxmshell:name=calculator,type=basic'
|
||||||
|
operation='sum'
|
||||||
|
|
||||||
|
while test $# -gt 0
|
||||||
|
do
|
||||||
|
case "$1" in
|
||||||
|
--jar)
|
||||||
|
shift
|
||||||
|
jar="$1"
|
||||||
|
;;
|
||||||
|
--address)
|
||||||
|
shift
|
||||||
|
address="$1"
|
||||||
|
;;
|
||||||
|
--mbean)
|
||||||
|
shift
|
||||||
|
mbean="$1"
|
||||||
|
;;
|
||||||
|
--run|-x)
|
||||||
|
shift
|
||||||
|
operation="$1"
|
||||||
|
;;
|
||||||
|
--get)
|
||||||
|
shift
|
||||||
|
operation="$1"
|
||||||
|
;;
|
||||||
|
--set)
|
||||||
|
shift
|
||||||
|
operation="$1 $2"
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
echo "bad option '$1'"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
java -cp "$jar" com.baeldung.jmxshell.custom.JmxInvoker \
|
||||||
|
"service:jmx:rmi:///jndi/rmi://$address/jmxrmi" \
|
||||||
|
"$mbean" \
|
||||||
|
"$operation"
|
|
@ -0,0 +1,54 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
jar='/tmp/cmdline-jmxclient-0.10.3.jar'
|
||||||
|
address='localhost:11234'
|
||||||
|
|
||||||
|
mbean='com.baeldung.jxmshell:name=calculator,type=basic'
|
||||||
|
operation='sum'
|
||||||
|
command="$mbean"
|
||||||
|
|
||||||
|
while test $# -gt 0
|
||||||
|
do
|
||||||
|
case "$1" in
|
||||||
|
--jar)
|
||||||
|
shift
|
||||||
|
jar="$1"
|
||||||
|
;;
|
||||||
|
--address)
|
||||||
|
shift
|
||||||
|
address="$1"
|
||||||
|
;;
|
||||||
|
--mbean)
|
||||||
|
shift
|
||||||
|
mbean="$1"
|
||||||
|
;;
|
||||||
|
--run|-x)
|
||||||
|
shift
|
||||||
|
operation="$1"
|
||||||
|
|
||||||
|
command="${mbean} ${operation}"
|
||||||
|
;;
|
||||||
|
--set)
|
||||||
|
shift
|
||||||
|
operation="$1"
|
||||||
|
|
||||||
|
shift
|
||||||
|
attribute_value="$1"
|
||||||
|
|
||||||
|
command="${mbean} ${operation}=${attribute_value}"
|
||||||
|
;;
|
||||||
|
--get)
|
||||||
|
shift
|
||||||
|
operation="$1"
|
||||||
|
|
||||||
|
command="${mbean} ${operation}"
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
echo "bad option '$1'"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
java -jar "$jar" - "$address" "$command"
|
|
@ -0,0 +1,22 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
$jar = "/tmp/jmxterm-1.0.4-uber.jar";
|
||||||
|
|
||||||
|
$host = "localhost";
|
||||||
|
$port = 11234;
|
||||||
|
|
||||||
|
$mbean = $ARGV[0] || "com.baeldung.jxmshell:name=calculator,type=basic";
|
||||||
|
$operation = $ARGV[1] || "sum";
|
||||||
|
|
||||||
|
open JMX, "| java -jar $jar -n";
|
||||||
|
|
||||||
|
print JMX "open $host:$port\n";
|
||||||
|
$attribute_value = $ARGV[2];
|
||||||
|
if (defined $attribute_value) {
|
||||||
|
print JMX "set -b ${mbean} ${operation} ${attribute_value}\n";
|
||||||
|
} else {
|
||||||
|
print JMX "run -b ${mbean} ${operation}\n";
|
||||||
|
}
|
||||||
|
print JMX "close\n";
|
||||||
|
|
||||||
|
close JMX;
|
|
@ -0,0 +1,46 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
jar='/tmp/jmxterm-1.0.4-uber.jar'
|
||||||
|
address='localhost:11234'
|
||||||
|
|
||||||
|
mbean='com.baeldung.jxmshell:name=calculator,type=basic'
|
||||||
|
operation='sum'
|
||||||
|
command="info -b $mbean"
|
||||||
|
|
||||||
|
while test $# -gt 0
|
||||||
|
do
|
||||||
|
case "$1" in
|
||||||
|
--jar|-j)
|
||||||
|
shift; jar="$1"
|
||||||
|
;;
|
||||||
|
--address|-l)
|
||||||
|
shift; address="$1"
|
||||||
|
;;
|
||||||
|
--mbean|-b)
|
||||||
|
shift; mbean="$1"
|
||||||
|
;;
|
||||||
|
--run|-x)
|
||||||
|
shift; operation="$1"
|
||||||
|
|
||||||
|
command="run -b ${mbean} ${operation}"
|
||||||
|
;;
|
||||||
|
--set)
|
||||||
|
shift; operation="$1"
|
||||||
|
shift; attribute_value="$1"
|
||||||
|
|
||||||
|
command="set -b ${mbean} ${operation} ${attribute_value}"
|
||||||
|
;;
|
||||||
|
--get)
|
||||||
|
shift; operation="$1"
|
||||||
|
|
||||||
|
command="get -b ${mbean} ${operation}"
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
echo "bad option '$1'"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "$command" | java -jar "$jar" -l "$address" -n -v silent
|
|
@ -0,0 +1,47 @@
|
||||||
|
package com.baeldung.jmxshell.custom;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
|
||||||
|
import org.junit.jupiter.api.Order;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
|
|
||||||
|
@TestMethodOrder(OrderAnnotation.class)
|
||||||
|
class JmxInvokerLiveTest {
|
||||||
|
|
||||||
|
private static final String JMX_URL = "service:jmx:rmi:///jndi/rmi://localhost:11234/jmxrmi";
|
||||||
|
private static final String JMX_MBEAN_NAME = "com.baeldung.jxmshell:name=calculator,type=basic";
|
||||||
|
private static final String ATTRIBUTE_A = "A";
|
||||||
|
private static final String ATTRIBUTE_B = "B";
|
||||||
|
private static final String SUM_OPERATION = "sum";
|
||||||
|
private static final Integer ATTRIBUTE_VALUE = 1;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(1)
|
||||||
|
void givenAttributeValue_whenSetAttributeA_thenResultMatches() {
|
||||||
|
String attributeValue = ATTRIBUTE_VALUE.toString();
|
||||||
|
|
||||||
|
String result = JmxInvoker.execute(JMX_URL, JMX_MBEAN_NAME, ATTRIBUTE_A, attributeValue);
|
||||||
|
|
||||||
|
assertEquals(ATTRIBUTE_A + "=" + attributeValue, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(2)
|
||||||
|
void givenAttributeValue_whenSetAttributeB_thenResultMatches() {
|
||||||
|
String attributeValue = ATTRIBUTE_VALUE.toString();
|
||||||
|
|
||||||
|
String result = JmxInvoker.execute(JMX_URL, JMX_MBEAN_NAME, ATTRIBUTE_B, attributeValue);
|
||||||
|
|
||||||
|
assertEquals(ATTRIBUTE_B + "=" + attributeValue, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(3)
|
||||||
|
void whenSumOperation_thenSumIsCorrect() {
|
||||||
|
String result = JmxInvoker.execute(JMX_URL, JMX_MBEAN_NAME, SUM_OPERATION, null);
|
||||||
|
|
||||||
|
assertEquals(SUM_OPERATION + "(): " + (ATTRIBUTE_VALUE + ATTRIBUTE_VALUE), result);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue