import java.util.Iterator;
import java.util.ArrayList;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
+import javax.management.openmbean.OpenType;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.InvalidKeyException;
*/
class GenericJMXConfValue
{
- private String ds_name;
+ private String _ds_name;
private DataSet _ds;
private List<String> _attributes;
private String _instance_prefix;
+ private List<String> _instance_from;
private boolean _is_table;
+ /**
+ * Converts a generic (OpenType) object to a number.
+ *
+ * Returns null if a conversion is not possible or not implemented.
+ */
private Number genericObjectToNumber (Object obj, int ds_type) /* {{{ */
{
if (obj instanceof String)
return (null);
}
}
+ else if (obj instanceof Byte)
+ {
+ return (new Byte ((Byte) obj));
+ }
+ else if (obj instanceof Short)
+ {
+ return (new Short ((Short) obj));
+ }
else if (obj instanceof Integer)
{
return (new Integer ((Integer) obj));
{
return (new Long ((Long) obj));
}
+ else if (obj instanceof Float)
+ {
+ return (new Float ((Float) obj));
+ }
else if (obj instanceof Double)
{
return (new Double ((Double) obj));
}
+ else if (obj instanceof BigDecimal)
+ {
+ return (BigDecimal.ZERO.add ((BigDecimal) obj));
+ }
+ else if (obj instanceof BigInteger)
+ {
+ return (BigInteger.ZERO.add ((BigInteger) obj));
+ }
return (null);
} /* }}} Number genericObjectToNumber */
+ /**
+ * Converts a generic list to a list of numbers.
+ *
+ * Returns null if one or more objects could not be converted.
+ */
private List<Number> genericListToNumber (List<Object> objects) /* {{{ */
{
List<Number> ret = new ArrayList<Number> ();
return (ret);
} /* }}} List<Number> genericListToNumber */
+ /**
+ * Converts a list of CompositeData to a list of numbers.
+ *
+ * From each <em>CompositeData </em> the key <em>key</em> is received and all
+ * those values are converted to a number. If one of the
+ * <em>CompositeData</em> doesn't have the specified key or one returned
+ * object cannot converted to a number then the function will return null.
+ */
private List<Number> genericCompositeToNumber (List<CompositeData> cdlist, /* {{{ */
String key)
{
return (genericListToNumber (objects));
} /* }}} List<Number> genericCompositeToNumber */
- private void submitTable (List<Object> objects, ValueList vl) /* {{{ */
+ private void submitTable (List<Object> objects, ValueList vl, /* {{{ */
+ String instancePrefix)
{
List<CompositeData> cdlist;
Set<String> keySet = null;
continue;
}
- if (this._instance_prefix == null)
+ if (instancePrefix == null)
vl.setTypeInstance (key);
else
- vl.setTypeInstance (this._instance_prefix + key);
+ vl.setTypeInstance (instancePrefix + key);
vl.setValues (values);
Collectd.dispatchValues (vl);
}
} /* }}} void submitTable */
- private void submitScalar (List<Object> objects, ValueList vl) /* {{{ */
+ private void submitScalar (List<Object> objects, ValueList vl, /* {{{ */
+ String instancePrefix)
{
List<Number> values;
return;
}
- if (this._instance_prefix == null)
+ if (instancePrefix == null)
vl.setTypeInstance ("");
else
- vl.setTypeInstance (this._instance_prefix);
+ vl.setTypeInstance (instancePrefix);
vl.setValues (values);
Collectd.dispatchValues (vl);
else
{
if (value instanceof CompositeData)
- return (queryAttributeRecursive ((CompositeData) value, attrNameList));
+ return (queryAttributeRecursive((CompositeData) value, attrNameList));
+ else if (value instanceof OpenType)
+ {
+ OpenType ot = (OpenType) value;
+ Collectd.logNotice ("GenericJMXConfValue: Handling of OpenType \""
+ + ot.getTypeName () + "\" is not yet implemented.");
+ return (null);
+ }
else
+ {
+ Collectd.logError ("GenericJMXConfValue: Received object of "
+ + "unknown class.");
return (null);
+ }
}
} /* }}} Object queryAttribute */
+ private String join (String separator, List<String> list) /* {{{ */
+ {
+ StringBuffer sb;
+
+ sb = new StringBuffer ();
+
+ for (int i = 0; i < list.size (); i++)
+ {
+ if (i > 0)
+ sb.append ("-");
+ sb.append (list.get (i));
+ }
+
+ return (sb.toString ());
+ } /* }}} String join */
+
private String getConfigString (OConfigItem ci) /* {{{ */
{
List<OConfigValue> values;
List<OConfigItem> children;
Iterator<OConfigItem> iter;
- this.ds_name = null;
+ this._ds_name = null;
this._ds = null;
this._attributes = new ArrayList<String> ();
this._instance_prefix = null;
+ this._instance_from = new ArrayList<String> ();
this._is_table = false;
/*
{
String tmp = getConfigString (child);
if (tmp != null)
- this.ds_name = tmp;
+ this._ds_name = tmp;
}
else if (child.getKey ().equalsIgnoreCase ("Table"))
{
if (tmp != null)
this._instance_prefix = tmp;
}
+ else if (child.getKey ().equalsIgnoreCase ("InstanceFrom"))
+ {
+ String tmp = getConfigString (child);
+ if (tmp != null)
+ this._instance_from.add (tmp);
+ }
else
throw (new IllegalArgumentException ("Unknown option: "
+ child.getKey ()));
}
- if (this.ds_name == null)
+ if (this._ds_name == null)
throw (new IllegalArgumentException ("No data set was defined."));
else if (this._attributes.size () == 0)
throw (new IllegalArgumentException ("No attribute was defined."));
* Query values via JMX according to the object's configuration and dispatch
* them to collectd.
*
- * @param conn Connection to the MBeanServer.
+ * @param conn Connection to the MBeanServer.
* @param objName Object name of the MBean to query.
* @param pd Preset naming components. The members host, plugin and
* plugin instance will be used.
ValueList vl;
List<DataSource> dsrc;
List<Object> values;
+ List<String> instanceList;
+ String instancePrefix;
if (this._ds == null)
{
- this._ds = Collectd.getDS (this.ds_name);
+ this._ds = Collectd.getDS (this._ds_name);
if (this._ds == null)
{
Collectd.logError ("GenericJMXConfValue: Unknown type: "
- + this.ds_name);
+ + this._ds_name);
return;
}
}
if (dsrc.size () != this._attributes.size ())
{
Collectd.logError ("GenericJMXConfValue.query: The data set "
- + ds_name + " has " + this._ds.getDataSources ().size ()
+ + this._ds_name + " has " + this._ds.getDataSources ().size ()
+ " data sources, but there were " + this._attributes.size ()
+ " attributes configured. This doesn't match!");
this._ds = null;
}
vl = new ValueList (pd);
- vl.setType (this.ds_name);
- vl.setTypeInstance (this._instance_prefix);
+ vl.setType (this._ds_name);
- values = new ArrayList<Object> ();
+ /*
+ * Build the instnace prefix from the fixed string prefix and the
+ * properties of the objName.
+ */
+ instanceList = new ArrayList<String> ();
+ for (int i = 0; i < this._instance_from.size (); i++)
+ {
+ String propertyName;
+ String propertyValue;
+ propertyName = this._instance_from.get (i);
+ propertyValue = objName.getKeyProperty (propertyName);
+ if (propertyValue == null)
+ {
+ Collectd.logError ("GenericJMXConfMBean: "
+ + "No such property in object name: " + propertyName);
+ }
+ else
+ {
+ instanceList.add (propertyValue);
+ }
+ }
+
+ if (this._instance_prefix != null)
+ instancePrefix = new String (this._instance_prefix
+ + join ("-", instanceList));
+ else
+ instancePrefix = join ("-", instanceList);
+
+ /*
+ * Build a list of `Object's which is then passed to `submitTable' and
+ * `submitScalar'.
+ */
+ values = new ArrayList<Object> ();
assert (dsrc.size () == this._attributes.size ());
for (int i = 0; i < this._attributes.size (); i++)
{
}
if (this._is_table)
- submitTable (values, vl);
+ submitTable (values, vl, instancePrefix);
else
- submitScalar (values, vl);
+ submitScalar (values, vl, instancePrefix);
} /* }}} void query */
-}
+} /* class GenericJMXConfValue */
/* vim: set sw=2 sts=2 et fdm=marker : */