1 /*
2 * collectd/java - org/collectd/java/GenericJMXConfMBean.java
3 * Copyright (C) 2009 Florian octo Forster
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; only version 2 of the License is applicable.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *
18 * Authors:
19 * Florian octo Forster <octo at verplant.org>
20 */
22 package org.collectd.java;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Set;
27 import java.util.ArrayList;
29 import javax.management.MBeanServerConnection;
30 import javax.management.ObjectName;
31 import javax.management.MalformedObjectNameException;
33 import org.collectd.api.Collectd;
34 import org.collectd.api.PluginData;
35 import org.collectd.api.OConfigValue;
36 import org.collectd.api.OConfigItem;
38 class GenericJMXConfMBean
39 {
40 private String _name; /* name by which this mapping is referenced */
41 private ObjectName _obj_name;
42 private String _instance_prefix;
43 private List<String> _instance_from;
44 private List<GenericJMXConfValue> _values;
46 private String getConfigString (OConfigItem ci) /* {{{ */
47 {
48 List<OConfigValue> values;
49 OConfigValue v;
51 values = ci.getValues ();
52 if (values.size () != 1)
53 {
54 Collectd.logError ("GenericJMXConfMBean: The " + ci.getKey ()
55 + " configuration option needs exactly one string argument.");
56 return (null);
57 }
59 v = values.get (0);
60 if (v.getType () != OConfigValue.OCONFIG_TYPE_STRING)
61 {
62 Collectd.logError ("GenericJMXConfMBean: The " + ci.getKey ()
63 + " configuration option needs exactly one string argument.");
64 return (null);
65 }
67 return (v.getString ());
68 } /* }}} String getConfigString */
70 private String join (String separator, List<String> list) /* {{{ */
71 {
72 StringBuffer sb;
74 sb = new StringBuffer ();
76 for (int i = 0; i < list.size (); i++)
77 {
78 if (i > 0)
79 sb.append ("-");
80 sb.append (list.get (i));
81 }
83 return (sb.toString ());
84 } /* }}} String join */
86 /*
87 * <MBean "alias name">
88 * ObjectName "object name"
89 * InstancePrefix "foobar"
90 * InstanceFrom "name"
91 * <Value />
92 * <Value />
93 * :
94 * </MBean>
95 */
96 public GenericJMXConfMBean (OConfigItem ci) /* {{{ */
97 throws IllegalArgumentException
98 {
99 List<OConfigItem> children;
100 Iterator<OConfigItem> iter;
102 this._name = getConfigString (ci);
103 if (this._name == null)
104 throw (new IllegalArgumentException ("No alias name was defined. "
105 + "MBean blocks need exactly one string argument."));
107 this._obj_name = null;
108 this._instance_prefix = null;
109 this._instance_from = new ArrayList<String> ();
110 this._values = new ArrayList<GenericJMXConfValue> ();
112 children = ci.getChildren ();
113 iter = children.iterator ();
114 while (iter.hasNext ())
115 {
116 OConfigItem child = iter.next ();
118 Collectd.logDebug ("GenericJMXConfMBean: child.getKey () = "
119 + child.getKey ());
120 if (child.getKey ().equalsIgnoreCase ("ObjectName"))
121 {
122 String tmp = getConfigString (child);
123 if (tmp == null)
124 continue;
126 try
127 {
128 this._obj_name = new ObjectName (tmp);
129 }
130 catch (MalformedObjectNameException e)
131 {
132 throw (new IllegalArgumentException ("Not a valid object name: "
133 + tmp, e));
134 }
135 }
136 else if (child.getKey ().equalsIgnoreCase ("InstancePrefix"))
137 {
138 String tmp = getConfigString (child);
139 if (tmp != null)
140 this._instance_prefix = tmp;
141 }
142 else if (child.getKey ().equalsIgnoreCase ("InstanceFrom"))
143 {
144 String tmp = getConfigString (child);
145 if (tmp != null)
146 this._instance_from.add (tmp);
147 }
148 else if (child.getKey ().equalsIgnoreCase ("Value"))
149 {
150 GenericJMXConfValue cv;
152 cv = new GenericJMXConfValue (child);
153 this._values.add (cv);
154 }
155 else
156 throw (new IllegalArgumentException ("Unknown option: "
157 + child.getKey ()));
158 }
160 if (this._obj_name == null)
161 throw (new IllegalArgumentException ("No object name was defined."));
163 if (this._values.size () == 0)
164 throw (new IllegalArgumentException ("No value block was defined."));
166 } /* }}} GenericJMXConfMBean (OConfigItem ci) */
168 public String getName () /* {{{ */
169 {
170 return (this._name);
171 } /* }}} */
173 public void query (MBeanServerConnection conn, PluginData pd) /* {{{ */
174 {
175 Set<ObjectName> names;
176 Iterator<ObjectName> iter;
178 try
179 {
180 names = conn.queryNames (this._obj_name, /* query = */ null);
181 }
182 catch (Exception e)
183 {
184 Collectd.logError ("GenericJMXConfMBean: queryNames failed: " + e);
185 return;
186 }
188 if (names.size () == 0)
189 {
190 Collectd.logWarning ("GenericJMXConfMBean: No MBean matched "
191 + "the ObjectName " + this._obj_name);
192 }
194 iter = names.iterator ();
195 while (iter.hasNext ())
196 {
197 ObjectName objName;
198 PluginData pd_tmp;
199 List<String> instanceList;
200 String instance;
202 objName = iter.next ();
203 pd_tmp = new PluginData (pd);
204 instanceList = new ArrayList<String> ();
206 Collectd.logDebug ("GenericJMXConfMBean: objName = "
207 + objName.toString ());
209 for (int i = 0; i < this._instance_from.size (); i++)
210 {
211 String propertyName;
212 String propertyValue;
214 propertyName = this._instance_from.get (i);
215 propertyValue = objName.getKeyProperty (propertyName);
216 if (propertyValue == null)
217 {
218 Collectd.logError ("GenericJMXConfMBean: "
219 + "No such property in object name: " + propertyName);
220 }
221 else
222 {
223 instanceList.add (propertyValue);
224 }
225 }
227 if (this._instance_prefix != null)
228 instance = new String (this._instance_prefix
229 + join ("-", instanceList));
230 else
231 instance = join ("-", instanceList);
232 pd_tmp.setPluginInstance (instance);
234 Collectd.logDebug ("GenericJMXConfMBean: instance = " + instance);
236 for (int i = 0; i < this._values.size (); i++)
237 this._values.get (i).query (conn, objName, pd_tmp);
238 }
239 } /* }}} void query */
240 }
242 /* vim: set sw=2 sts=2 et fdm=marker : */