b1fbfb3ec18c14fadf0ae56c845d8ff76a0f5417
[collectd.git] / bindings / java / org / collectd / java / GenericJMXConfMBean.java
1 /*
2  * collectd/java - org/collectd/java/GenericJMXConfMBean.java
3  * Copyright (C) 2009,2010  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  */
21
22 package org.collectd.java;
23
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Set;
27 import java.util.ArrayList;
28
29 import javax.management.MBeanServerConnection;
30 import javax.management.ObjectName;
31 import javax.management.MalformedObjectNameException;
32
33 import org.collectd.api.Collectd;
34 import org.collectd.api.PluginData;
35 import org.collectd.api.OConfigValue;
36 import org.collectd.api.OConfigItem;
37
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;
45
46   private String getConfigString (OConfigItem ci) /* {{{ */
47   {
48     List<OConfigValue> values;
49     OConfigValue v;
50
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     }
58
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     }
66
67     return (v.getString ());
68   } /* }}} String getConfigString */
69
70 /*
71  * <MBean "alias name">
72  *   ObjectName "object name"
73  *   InstancePrefix "foobar"
74  *   InstanceFrom "name"
75  *   <Value />
76  *   <Value />
77  *   :
78  * </MBean>
79  */
80   public GenericJMXConfMBean (OConfigItem ci) /* {{{ */
81     throws IllegalArgumentException
82   {
83     List<OConfigItem> children;
84     Iterator<OConfigItem> iter;
85
86     this._name = getConfigString (ci);
87     if (this._name == null)
88       throw (new IllegalArgumentException ("No alias name was defined. "
89             + "MBean blocks need exactly one string argument."));
90
91     this._obj_name = null;
92     this._instance_prefix = null;
93     this._instance_from = new ArrayList<String> ();
94     this._values = new ArrayList<GenericJMXConfValue> ();
95
96     children = ci.getChildren ();
97     iter = children.iterator ();
98     while (iter.hasNext ())
99     {
100       OConfigItem child = iter.next ();
101
102       Collectd.logDebug ("GenericJMXConfMBean: child.getKey () = "
103           + child.getKey ());
104       if (child.getKey ().equalsIgnoreCase ("ObjectName"))
105       {
106         String tmp = getConfigString (child);
107         if (tmp == null)
108           continue;
109
110         try
111         {
112           this._obj_name = new ObjectName (tmp);
113         }
114         catch (MalformedObjectNameException e)
115         {
116           throw (new IllegalArgumentException ("Not a valid object name: "
117                 + tmp, e));
118         }
119       }
120       else if (child.getKey ().equalsIgnoreCase ("InstancePrefix"))
121       {
122         String tmp = getConfigString (child);
123         if (tmp != null)
124           this._instance_prefix = tmp;
125       }
126       else if (child.getKey ().equalsIgnoreCase ("InstanceFrom"))
127       {
128         String tmp = getConfigString (child);
129         if (tmp != null)
130           this._instance_from.add (tmp);
131       }
132       else if (child.getKey ().equalsIgnoreCase ("Value"))
133       {
134         GenericJMXConfValue cv;
135
136         cv = new GenericJMXConfValue (child);
137         this._values.add (cv);
138       }
139       else
140         throw (new IllegalArgumentException ("Unknown option: "
141               + child.getKey ()));
142     }
143
144     if (this._obj_name == null)
145       throw (new IllegalArgumentException ("No object name was defined."));
146
147     if (this._values.size () == 0)
148       throw (new IllegalArgumentException ("No value block was defined."));
149
150   } /* }}} GenericJMXConfMBean (OConfigItem ci) */
151
152   public String getName () /* {{{ */
153   {
154     return (this._name);
155   } /* }}} */
156
157   public int query (MBeanServerConnection conn, PluginData pd, /* {{{ */
158       String instance_prefix)
159   {
160     Set<ObjectName> names;
161     Iterator<ObjectName> iter;
162
163     try
164     {
165       names = conn.queryNames (this._obj_name, /* query = */ null);
166     }
167     catch (Exception e)
168     {
169       Collectd.logError ("GenericJMXConfMBean: queryNames failed: " + e);
170       return (-1);
171     }
172
173     if (names.size () == 0)
174     {
175       Collectd.logWarning ("GenericJMXConfMBean: No MBean matched "
176           + "the ObjectName " + this._obj_name);
177     }
178
179     iter = names.iterator ();
180     while (iter.hasNext ())
181     {
182       ObjectName   objName;
183       PluginData   pd_tmp;
184       List<String> instanceList;
185       StringBuffer instance;
186
187       objName      = iter.next ();
188       pd_tmp       = new PluginData (pd);
189       instanceList = new ArrayList<String> ();
190       instance     = new StringBuffer ();
191
192       Collectd.logDebug ("GenericJMXConfMBean: objName = "
193           + objName.toString ());
194
195       for (int i = 0; i < this._instance_from.size (); i++)
196       {
197         String propertyName;
198         String propertyValue;
199
200         propertyName = this._instance_from.get (i);
201         propertyValue = objName.getKeyProperty (propertyName);
202         if (propertyValue == null)
203         {
204           Collectd.logError ("GenericJMXConfMBean: "
205               + "No such property in object name: " + propertyName);
206         }
207         else
208         {
209           instanceList.add (propertyValue);
210         }
211       }
212
213       if (instance_prefix != null)
214         instance.append (instance_prefix);
215
216       if (this._instance_prefix != null)
217         instance.append (this._instance_prefix);
218
219       for (int i = 0; i < instanceList.size (); i++)
220       {
221         if (i > 0)
222           instance.append ("-");
223         instance.append (instanceList.get (i));
224       }
225
226       pd_tmp.setPluginInstance (instance.toString ());
227
228       Collectd.logDebug ("GenericJMXConfMBean: instance = " + instance.toString ());
229
230       for (int i = 0; i < this._values.size (); i++)
231         this._values.get (i).query (conn, objName, pd_tmp);
232     }
233
234     return (0);
235   } /* }}} void query */
236 }
237
238 /* vim: set sw=2 sts=2 et fdm=marker : */