mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2025-02-25 18:55:28 -06:00
add initial JMX driver implementation
This commit is contained in:
parent
fff55212da
commit
0b3d30caf0
44
driver-jmx/pom.xml
Normal file
44
driver-jmx/pom.xml
Normal file
@ -0,0 +1,44 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
<parent>
|
||||
<artifactId>mvn-defaults</artifactId>
|
||||
<groupId>io.nosqlbench</groupId>
|
||||
<version>3.12.129-SNAPSHOT</version>
|
||||
<relativePath>../mvn-defaults</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>driver-jmx</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>${project.artifactId}</name>
|
||||
<description>
|
||||
A JMX nosqlbench ActivityType (AT) driver module;
|
||||
This provides the ability to query system via JMX
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.nosqlbench</groupId>
|
||||
<artifactId>engine-api</artifactId>
|
||||
<version>3.12.129-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- test scope only -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,37 @@
|
||||
package io.nosqlbench.driver.jmx;
|
||||
|
||||
import io.nosqlbench.driver.jmx.ops.JmxOp;
|
||||
import io.nosqlbench.engine.api.activityapi.core.SyncAction;
|
||||
import io.nosqlbench.engine.api.activityapi.planning.OpSequence;
|
||||
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class JMXAction implements SyncAction {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(JMXAction.class);
|
||||
|
||||
private final ActivityDef activityDef;
|
||||
private final int slot;
|
||||
private final JMXActivity activity;
|
||||
private OpSequence<ReadyJmxOp> sequencer;
|
||||
|
||||
public JMXAction(ActivityDef activityDef, int slot, JMXActivity activity) {
|
||||
this.activityDef = activityDef;
|
||||
this.slot = slot;
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
this.sequencer = activity.getSequencer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int runCycle(long value) {
|
||||
ReadyJmxOp readyJmxOp = sequencer.get(value);
|
||||
JmxOp jmxOp = readyJmxOp.bind(value);
|
||||
jmxOp.execute();
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package io.nosqlbench.driver.jmx;
|
||||
|
||||
import io.nosqlbench.engine.api.activityapi.core.Action;
|
||||
import io.nosqlbench.engine.api.activityapi.core.ActionDispenser;
|
||||
|
||||
public class JMXActionDispenser implements ActionDispenser {
|
||||
private JMXActivity activity;
|
||||
|
||||
public JMXActionDispenser(JMXActivity activity) {
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Action getAction(int slot) {
|
||||
return new JMXAction(activity.getActivityDef(),slot,activity);
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package io.nosqlbench.driver.jmx;
|
||||
|
||||
import io.nosqlbench.engine.api.activityapi.core.Activity;
|
||||
import io.nosqlbench.engine.api.activityapi.planning.OpSequence;
|
||||
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
|
||||
import io.nosqlbench.engine.api.activityimpl.SimpleActivity;
|
||||
|
||||
public class JMXActivity extends SimpleActivity implements Activity {
|
||||
|
||||
private OpSequence<ReadyJmxOp> sequence;
|
||||
|
||||
public JMXActivity(ActivityDef activityDef) {
|
||||
super(activityDef);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initActivity() {
|
||||
super.initActivity();
|
||||
this.sequence = createOpSequenceFromCommands(ReadyJmxOp::new);
|
||||
}
|
||||
|
||||
public OpSequence<ReadyJmxOp> getSequencer() {
|
||||
return sequence;
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package io.nosqlbench.driver.jmx;
|
||||
|
||||
import io.nosqlbench.engine.api.activityapi.core.ActionDispenser;
|
||||
import io.nosqlbench.engine.api.activityapi.core.ActivityType;
|
||||
import io.nosqlbench.engine.api.activityimpl.ActivityDef;
|
||||
import io.nosqlbench.nb.annotations.Service;
|
||||
|
||||
@Service(ActivityType.class)
|
||||
public class JMXActivityType implements ActivityType<JMXActivity> {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "jmx";
|
||||
}
|
||||
|
||||
@Override
|
||||
public JMXActivity getActivity(ActivityDef activityDef) {
|
||||
return new JMXActivity(activityDef);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionDispenser getActionDispenser(JMXActivity activity) {
|
||||
return new JMXActionDispenser(activity);
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package io.nosqlbench.driver.jmx;
|
||||
|
||||
import io.nosqlbench.driver.jmx.ops.JMXExplainOperation;
|
||||
import io.nosqlbench.driver.jmx.ops.JMXReadOperation;
|
||||
import io.nosqlbench.driver.jmx.ops.JmxOp;
|
||||
import io.nosqlbench.engine.api.templating.CommandTemplate;
|
||||
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.remote.JMXConnector;
|
||||
import javax.management.remote.JMXConnectorFactory;
|
||||
import javax.management.remote.JMXServiceURL;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ReadyJmxOp {
|
||||
|
||||
private final CommandTemplate command;
|
||||
|
||||
public ReadyJmxOp(CommandTemplate command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
public JmxOp bind(long value) {
|
||||
Map<String, String> cmdmap = command.getCommand(value);
|
||||
JMXConnector connector = bindConnector(cmdmap);
|
||||
|
||||
if (!cmdmap.containsKey("object")) {
|
||||
throw new RuntimeException("You must specify an object in a jmx operation as in object=...");
|
||||
}
|
||||
|
||||
ObjectName objectName = null;
|
||||
try {
|
||||
String object = cmdmap.get("object");
|
||||
if (object==null) {
|
||||
throw new RuntimeException("You must specify an object name for any JMX operation.");
|
||||
}
|
||||
objectName = new ObjectName(object);
|
||||
} catch (MalformedObjectNameException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (cmdmap.containsKey("readvar")) {
|
||||
return new JMXReadOperation(connector, objectName, cmdmap.get("readvar"), cmdmap.get("as_type"),cmdmap.get("as_name"));
|
||||
} else if (cmdmap.containsKey("explain")) {
|
||||
return new JMXExplainOperation(connector,objectName);
|
||||
}
|
||||
|
||||
throw new RuntimeException("No valid form of JMX operation was determined from the provided command details:" + cmdmap.toString());
|
||||
}
|
||||
|
||||
private JMXConnector bindConnector(Map<String, String> cmdmap) {
|
||||
|
||||
JMXConnector connector = null;
|
||||
try {
|
||||
JMXServiceURL url = bindJMXServiceURL(cmdmap);
|
||||
connector = JMXConnectorFactory.connect(url);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return connector;
|
||||
}
|
||||
|
||||
private JMXServiceURL bindJMXServiceURL(Map<String, String> cmdmap) {
|
||||
JMXServiceURL url = null;
|
||||
try {
|
||||
if (cmdmap.containsKey("url")) {
|
||||
url = new JMXServiceURL(cmdmap.get("url"));
|
||||
} else {
|
||||
if (cmdmap.containsKey("host")) {
|
||||
throw new RuntimeException("You must provide at least a host if you do not provide a url.");
|
||||
}
|
||||
String protocol = cmdmap.get("protocol");
|
||||
String host = cmdmap.get("host");
|
||||
int port = Optional.ofNullable(cmdmap.get("port")).map(Integer::parseInt).orElse(0);
|
||||
String path = cmdmap.get("path");
|
||||
url = new JMXServiceURL(protocol, host, port, path);
|
||||
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package io.nosqlbench.driver.jmx;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ValueConverter {
|
||||
|
||||
public static Object convert(String typeName, Object o) {
|
||||
|
||||
if (!typeName.contains(".")) {
|
||||
if (Number.class.isAssignableFrom(o.getClass())) {
|
||||
switch (typeName) {
|
||||
case "String":
|
||||
return o.toString();
|
||||
case "long":
|
||||
case "Long":
|
||||
return (((Number) o).longValue());
|
||||
case "int":
|
||||
case "Integer":
|
||||
return (((Number) o).intValue());
|
||||
case "double":
|
||||
case "Double":
|
||||
return (((Number) o).doubleValue());
|
||||
case "float":
|
||||
case "Float":
|
||||
return (((Number) o).floatValue());
|
||||
case "short":
|
||||
case "Short":
|
||||
return (((Number) o).shortValue());
|
||||
case "byte":
|
||||
case "Byte":
|
||||
return (((Number) o).byteValue());
|
||||
default:
|
||||
throw new RuntimeException("For numeric values, you can only convert to long,int,double,float,byte,short or String");
|
||||
}
|
||||
} else {
|
||||
String value;
|
||||
if (CharSequence.class.isAssignableFrom(o.getClass())) {
|
||||
value = (String) o;
|
||||
} else {
|
||||
value = o.toString();
|
||||
}
|
||||
switch (typeName) {
|
||||
case "String":
|
||||
return value;
|
||||
case "long":
|
||||
case "Long":
|
||||
return Long.parseLong(value);
|
||||
case "int":
|
||||
case "Integer":
|
||||
return Integer.parseInt(value);
|
||||
case "double":
|
||||
case "Double":
|
||||
return Double.parseDouble(value);
|
||||
case "float":
|
||||
case "Float":
|
||||
return Float.parseFloat(value);
|
||||
case "short":
|
||||
case "Short":
|
||||
return Short.parseShort(value);
|
||||
case "byte":
|
||||
case "Byte":
|
||||
return Byte.parseByte(value);
|
||||
default:
|
||||
throw new RuntimeException("For String values, you can only convert to long, int, double, float, short, byte, or String");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Class<?> aClass = Class.forName(typeName);
|
||||
return aClass.cast(o);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
package io.nosqlbench.driver.jmx.formats;
|
||||
|
||||
import javax.management.*;
|
||||
import java.util.Map;
|
||||
|
||||
public class MBeanInfoConsoleFormat {
|
||||
|
||||
private static Map<Integer,String> MbeanOpImpacts = Map.of(
|
||||
MBeanOperationInfo.ACTION,"ACTION",
|
||||
MBeanOperationInfo.ACTION_INFO,"ACTION_INFO",
|
||||
MBeanOperationInfo.UNKNOWN,"UNKNOWN",
|
||||
MBeanOperationInfo.INFO,"INFO");
|
||||
|
||||
// Not including Descriptors here
|
||||
public static String formatAsText(MBeanInfo info, ObjectName objectName) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("### MBeanInfo for '").append(objectName).append("'\n");
|
||||
|
||||
String className = info.getClassName();
|
||||
sb.append("# classname: ").append(className).append("\n");
|
||||
|
||||
String description = info.getDescription();
|
||||
sb.append("# ").append(description).append("\n");
|
||||
|
||||
MBeanConstructorInfo[] constructors = info.getConstructors();
|
||||
if (constructors.length > 0) {
|
||||
sb.append("## constructors:\n");
|
||||
for (MBeanConstructorInfo constructor : constructors) {
|
||||
|
||||
String ctorDesc = constructor.getDescription();
|
||||
sb.append("# ").append(ctorDesc).append("\n");
|
||||
|
||||
String name = constructor.getName();
|
||||
sb.append("# ").append(name).append("(");
|
||||
sb.append(pramDetail(constructor.getSignature(), " "));
|
||||
sb.append(" )\n");
|
||||
// sb.append(" [").append(descriptorDetail(constructor.getDescriptor())).append("]\n");
|
||||
}
|
||||
}
|
||||
|
||||
MBeanAttributeInfo[] attributes = info.getAttributes();
|
||||
if (attributes.length > 0) {
|
||||
sb.append("## attributes:\n");
|
||||
|
||||
for (MBeanAttributeInfo attribute : attributes) {
|
||||
String attrDesc = attribute.getDescription();
|
||||
String attrName = attribute.getName();
|
||||
String attrType = attribute.getType();
|
||||
sb.append("# ").append(attrDesc).append("\n");
|
||||
sb.append("- '").append(attrName).append("' type=").append(attrType);
|
||||
sb.append("readable=").append(attribute.isReadable()).append(" writable=").append(attribute.isWritable()).append(" is_is=").append(attribute.isIs());
|
||||
sb.append("\n");
|
||||
// sb.append(" [").append(descriptorDetail(attribute.getDescriptor())).append("]\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
MBeanNotificationInfo[] notifications = info.getNotifications();
|
||||
if (notifications.length > 0) {
|
||||
sb.append("## notifications:\n");
|
||||
for (MBeanNotificationInfo notification : notifications) {
|
||||
String notifName = notification.getName();
|
||||
String notifDesc = notification.getDescription();
|
||||
String[] notifTypes = notification.getNotifTypes();
|
||||
Class<? extends MBeanNotificationInfo> notifClass = notification.getClass();
|
||||
sb.append("# ").append(notifDesc).append("\n");
|
||||
sb.append("- ").append(notifName).append(" [").append(descriptorDetail(notification.getDescriptor())).append("]\n");
|
||||
|
||||
if (notifTypes.length > 0) {
|
||||
for (String notifType : notifTypes) {
|
||||
sb.append(" - ").append(notifType).append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MBeanOperationInfo[] operations = info.getOperations();
|
||||
if (operations.length > 0) {
|
||||
sb.append("## operations:\n");
|
||||
for (MBeanOperationInfo operation : operations) {
|
||||
String opDesc = operation.getDescription();
|
||||
String opName = operation.getName();
|
||||
MBeanParameterInfo[] opSig = operation.getSignature();
|
||||
Class<? extends MBeanOperationInfo> opClass = operation.getClass();
|
||||
|
||||
sb.append("# ").append(opDesc).append("\n");
|
||||
sb.append("- ").append(opName).append("(");
|
||||
sb.append(pramDetail(operation.getSignature(), " "));
|
||||
sb.append(") -> ").append(operation.getReturnType());
|
||||
sb.append(" impact=").append(MbeanOpImpacts.get(operation.getImpact())).append("\n");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String descriptorDetail(Descriptor descriptor) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("valid=").append(descriptor.isValid());
|
||||
String[] fieldNames = descriptor.getFieldNames();
|
||||
for (String field : fieldNames) {
|
||||
sb.append(" ").append(field).append("=").append(descriptor.getFieldValue(field));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String pramDetail(MBeanParameterInfo[] signature, String prefix) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (MBeanParameterInfo paramInfo : signature) {
|
||||
String desc = paramInfo.getDescription();
|
||||
if (desc != null) {
|
||||
sb.append(prefix).append(" # ").append(desc).append("\n");
|
||||
}
|
||||
sb.append(prefix).append(" - ").append(paramInfo.getName()).append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package io.nosqlbench.driver.jmx.ops;
|
||||
|
||||
import io.nosqlbench.driver.jmx.formats.MBeanInfoConsoleFormat;
|
||||
|
||||
import javax.management.*;
|
||||
import javax.management.remote.JMXConnector;
|
||||
import java.io.IOException;
|
||||
|
||||
public class JMXExplainOperation extends JmxOp {
|
||||
public JMXExplainOperation(JMXConnector connector, ObjectName objectName) {
|
||||
super(connector,objectName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
MBeanServerConnection bean = getMBeanConnection();
|
||||
try {
|
||||
MBeanInfo info = bean.getMBeanInfo(objectName);
|
||||
String mbeanInfoText = MBeanInfoConsoleFormat.formatAsText(info, objectName);
|
||||
System.out.println(mbeanInfoText);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package io.nosqlbench.driver.jmx.ops;
|
||||
|
||||
import io.nosqlbench.driver.jmx.ValueConverter;
|
||||
import io.nosqlbench.virtdata.library.basics.core.threadstate.SharedState;
|
||||
import org.apache.commons.math4.analysis.function.Exp;
|
||||
|
||||
import javax.management.*;
|
||||
import javax.management.remote.JMXConnector;
|
||||
import javax.management.remote.JMXServiceURL;
|
||||
import java.io.IOException;
|
||||
|
||||
public class JMXReadOperation extends JmxOp {
|
||||
private final String attribute;
|
||||
private final String asType;
|
||||
private final String asName;
|
||||
|
||||
public JMXReadOperation(JMXConnector connector, ObjectName objectName, String attribute, String asType, String asName) {
|
||||
super(connector, objectName);
|
||||
this.attribute = attribute;
|
||||
this.asType = asType;
|
||||
this.asName = asName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
try {
|
||||
Object value = getMBeanConnection().getAttribute(objectName, this.attribute);
|
||||
logger.trace("read attribute '" + value +"': " + value);
|
||||
|
||||
if (asType!=null) {
|
||||
value = ValueConverter.convert(asType,value);
|
||||
}
|
||||
|
||||
String storedName = (asName==null) ? attribute : asName;
|
||||
SharedState.tl_ObjectMap.get().put(storedName,value);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package io.nosqlbench.driver.jmx.ops;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.management.MBeanServerConnection;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.remote.JMXConnector;
|
||||
|
||||
/**
|
||||
* All JMX Operations should built on this base type.
|
||||
*/
|
||||
public abstract class JmxOp {
|
||||
|
||||
protected final static Logger logger = LoggerFactory.getLogger(JmxOp.class);
|
||||
|
||||
protected JMXConnector connector;
|
||||
protected ObjectName objectName;
|
||||
|
||||
public JmxOp(JMXConnector connector, ObjectName objectName) {
|
||||
this.connector = connector;
|
||||
this.objectName = objectName;
|
||||
}
|
||||
|
||||
public MBeanServerConnection getMBeanConnection() {
|
||||
MBeanServerConnection connection = null;
|
||||
try {
|
||||
connection = connector.getMBeanServerConnection();
|
||||
return connection;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void execute();
|
||||
}
|
71
driver-jmx/src/main/resources/jmx.md
Normal file
71
driver-jmx/src/main/resources/jmx.md
Normal file
@ -0,0 +1,71 @@
|
||||
# JMX Driver
|
||||
|
||||
The JMX Driver allows you to do various JMX operations against a JMX service URL
|
||||
and object name.
|
||||
|
||||
You must specify the service URL and object name in the op template. Alternately, you can specify
|
||||
the protocol, host, port and path. Each cycle, the full JMX operation is derived from the
|
||||
op template, and executed.
|
||||
|
||||
In the first version of this driver, only reads are supported.
|
||||
|
||||
# Connection Options
|
||||
|
||||
JMX transports can be configured in a myriad of ways. The options below allow you to add
|
||||
connection options such as SSL and authentication.
|
||||
|
||||
- **ssl** - Use SSL settings provided. Thes SSL settings are from the NoSQLBench standard
|
||||
SSL support
|
||||
|
||||
# Example Operations
|
||||
|
||||
## readvar
|
||||
|
||||
The readvar operation is used to read a named attribute of the named object and store it in the
|
||||
thread local variable map.
|
||||
|
||||
```
|
||||
statements:
|
||||
- read1:
|
||||
url: service:jmx:rmi:///jndi/rmi://dsehost:7199/jmxrmi
|
||||
object: org.apache.cassandra.metrics:type=Compaction,name=PendingTasks
|
||||
readvar: Value
|
||||
as_type: int
|
||||
as_name: pending_tasks
|
||||
```
|
||||
|
||||
The `as_type` and `as_name` are optional, and if provided will set the name and data type used in
|
||||
the thread local variable map.
|
||||
|
||||
- *as_type* can be any of long, int, double, float, byte, short, or String. If the original type
|
||||
is convertable to a number, then it will be converted to a number and then to the desired type. If it
|
||||
is not, it will be converted to String form first and then to the desired type. If the type name
|
||||
contains dots, as in a fully-qualified class name, then direct class casting will be used if the
|
||||
types are compatible.
|
||||
|
||||
A combined format is available if you don't want to put every command property on a separate line.
|
||||
In this format, the first entry in the command map is taken as the command name and a set of key=value
|
||||
command arguments. It is semantically equivalent to the above example, only more compact.
|
||||
|
||||
```
|
||||
statements:
|
||||
- read1: readvar=Value as_type=int as_name=pending_tasks
|
||||
url: service:jmx:rmi:///jndi/rmi://dsehost:7199/jmxrmi
|
||||
object: org.apache.cassandra.metrics:type=Compaction,name=PendingTasks
|
||||
```
|
||||
|
||||
## explain
|
||||
|
||||
If you want to see the details about a managed object, you can use the explain command:
|
||||
|
||||
```
|
||||
statements:
|
||||
- explain1:
|
||||
url: service:jmx:rmi:///jndi/rmi://dsehost:7199/jmxrmi
|
||||
object: org.apache.cassandra.metrics:type=Compaction,name=PendingTasks
|
||||
explain: object
|
||||
```
|
||||
|
||||
This will use the MBeanInfo to interrogate the named management bean and provide a summary
|
||||
of it's available attriburtes, operations, notifications, and constructors to stdout.
|
||||
This is not meant for bulk testing, but more for explaining and documenting JMX beans.
|
@ -0,0 +1,15 @@
|
||||
package io.nosqlbench.driver.jmx;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ValueConverterTest {
|
||||
|
||||
@Test
|
||||
public void testConvertStringDouble() {
|
||||
String s = "3";
|
||||
double d = (double) ValueConverter.convert("double", s);
|
||||
}
|
||||
|
||||
}
|
10
driver-jmx/src/test/resources/activities/jmx-test-1.yaml
Normal file
10
driver-jmx/src/test/resources/activities/jmx-test-1.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
# (src/test/resources/activities/) jmx-test-1.yaml
|
||||
statements:
|
||||
- read1:
|
||||
url: service:jmx:rmi:///jndi/rmi://dsehost:7199/jmxrmi
|
||||
object: org.apache.cassandra.metrics:type=Compaction,name=PendingTasks
|
||||
readvar: Value
|
||||
as_type: int
|
||||
as_name: pending_tasks
|
||||
|
||||
|
8
driver-jmx/src/test/resources/activities/jmx-test-2.yaml
Normal file
8
driver-jmx/src/test/resources/activities/jmx-test-2.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
# (src/test/resources/activities/) jmx-test-2.yaml
|
||||
statements:
|
||||
- explain1:
|
||||
url: service:jmx:rmi:///jndi/rmi://dsehost:7199/jmxrmi
|
||||
object: org.apache.cassandra.metrics:type=Compaction,name=PendingTasks
|
||||
explain: object
|
||||
|
||||
|
4
driver-jmx/src/test/resources/activities/jmx-test-3.yaml
Normal file
4
driver-jmx/src/test/resources/activities/jmx-test-3.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
statements:
|
||||
- read1: readvar=Value as_type=int as_name=pending_tasks
|
||||
url: service:jmx:rmi:///jndi/rmi://dsehost:7199/jmxrmi
|
||||
object: org.apache.cassandra.metrics:type=Compaction,name=PendingTasks
|
@ -86,6 +86,12 @@
|
||||
<version>3.12.129-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.nosqlbench</groupId>
|
||||
<artifactId>driver-jmx</artifactId>
|
||||
<version>3.12.129-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.nosqlbench</groupId>
|
||||
<artifactId>driver-cql-shaded</artifactId>
|
||||
|
Loading…
Reference in New Issue
Block a user