Merge pull request #3339 from jkohen/patch-1
[collectd.git] / bindings / java / org / collectd / java / GenericJMXConfMBean.java
1 /**
2  * collectd - bindings/java/org/collectd/java/GenericJMXConfMBean.java
3  * Copyright (C) 2009,2010  Florian octo Forster
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  * Authors:
24  *   Florian octo Forster <octo at collectd.org>
25  */
26
27 package org.collectd.java;
28
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Set;
32 import java.util.ArrayList;
33
34 import javax.management.MBeanServerConnection;
35 import javax.management.ObjectName;
36 import javax.management.MalformedObjectNameException;
37
38 import org.collectd.api.Collectd;
39 import org.collectd.api.PluginData;
40 import org.collectd.api.OConfigValue;
41 import org.collectd.api.OConfigItem;
42
43 class GenericJMXConfMBean
44 {
45   private String _name; /* name by which this mapping is referenced */
46   private ObjectName _obj_name;
47   private String _instance_prefix;
48   private List<String> _instance_from;
49   private List<GenericJMXConfValue> _values;
50
51   private String getConfigString (OConfigItem ci) /* {{{ */
52   {
53     List<OConfigValue> values;
54     OConfigValue v;
55
56     values = ci.getValues ();
57     if (values.size () != 1)
58     {
59       Collectd.logError ("GenericJMXConfMBean: The " + ci.getKey ()
60           + " configuration option needs exactly one string argument.");
61       return (null);
62     }
63
64     v = values.get (0);
65     if (v.getType () != OConfigValue.OCONFIG_TYPE_STRING)
66     {
67       Collectd.logError ("GenericJMXConfMBean: The " + ci.getKey ()
68           + " configuration option needs exactly one string argument.");
69       return (null);
70     }
71
72     return (v.getString ());
73   } /* }}} String getConfigString */
74
75 /*
76  * <MBean "alias name">
77  *   ObjectName "object name"
78  *   InstancePrefix "foobar"
79  *   InstanceFrom "name"
80  *   <Value />
81  *   <Value />
82  *   :
83  * </MBean>
84  */
85   public GenericJMXConfMBean (OConfigItem ci) /* {{{ */
86     throws IllegalArgumentException
87   {
88     List<OConfigItem> children;
89     Iterator<OConfigItem> iter;
90
91     this._name = getConfigString (ci);
92     if (this._name == null)
93       throw (new IllegalArgumentException ("No alias name was defined. "
94             + "MBean blocks need exactly one string argument."));
95
96     this._obj_name = null;
97     this._instance_prefix = null;
98     this._instance_from = new ArrayList<String> ();
99     this._values = new ArrayList<GenericJMXConfValue> ();
100
101     children = ci.getChildren ();
102     iter = children.iterator ();
103     while (iter.hasNext ())
104     {
105       OConfigItem child = iter.next ();
106
107       Collectd.logDebug ("GenericJMXConfMBean: child.getKey () = "
108           + child.getKey ());
109       if (child.getKey ().equalsIgnoreCase ("ObjectName"))
110       {
111         String tmp = getConfigString (child);
112         if (tmp == null)
113           continue;
114
115         try
116         {
117           this._obj_name = new ObjectName (tmp);
118         }
119         catch (MalformedObjectNameException e)
120         {
121           throw (new IllegalArgumentException ("Not a valid object name: "
122                 + tmp, e));
123         }
124       }
125       else if (child.getKey ().equalsIgnoreCase ("InstancePrefix"))
126       {
127         String tmp = getConfigString (child);
128         if (tmp != null)
129           this._instance_prefix = tmp;
130       }
131       else if (child.getKey ().equalsIgnoreCase ("InstanceFrom"))
132       {
133         String tmp = getConfigString (child);
134         if (tmp != null)
135           this._instance_from.add (tmp);
136       }
137       else if (child.getKey ().equalsIgnoreCase ("Value"))
138       {
139         GenericJMXConfValue cv;
140
141         cv = new GenericJMXConfValue (child);
142         this._values.add (cv);
143       }
144       else
145         throw (new IllegalArgumentException ("Unknown option: "
146               + child.getKey ()));
147     }
148
149     if (this._obj_name == null)
150       throw (new IllegalArgumentException ("No object name was defined."));
151
152     if (this._values.size () == 0)
153       throw (new IllegalArgumentException ("No value block was defined."));
154
155   } /* }}} GenericJMXConfMBean (OConfigItem ci) */
156
157   public String getName () /* {{{ */
158   {
159     return (this._name);
160   } /* }}} */
161
162   public int query (MBeanServerConnection conn, PluginData pd, /* {{{ */
163       String instance_prefix)
164   {
165     Set<ObjectName> names;
166     Iterator<ObjectName> iter;
167
168     try
169     {
170       names = conn.queryNames (this._obj_name, /* query = */ null);
171     }
172     catch (Exception e)
173     {
174       Collectd.logError ("GenericJMXConfMBean: queryNames failed: " + e);
175       return (-1);
176     }
177
178     if (names.size () == 0)
179     {
180       Collectd.logWarning ("GenericJMXConfMBean: No MBean matched "
181           + "the ObjectName " + this._obj_name);
182     }
183
184     iter = names.iterator ();
185     while (iter.hasNext ())
186     {
187       ObjectName   objName;
188       PluginData   pd_tmp;
189       List<String> instanceList;
190       StringBuffer instance;
191
192       objName      = iter.next ();
193       pd_tmp       = new PluginData (pd);
194       instanceList = new ArrayList<String> ();
195       instance     = new StringBuffer ();
196
197       Collectd.logDebug ("GenericJMXConfMBean: objName = "
198           + objName.toString ());
199
200       for (int i = 0; i < this._instance_from.size (); i++)
201       {
202         String propertyName;
203         String propertyValue;
204
205         propertyName = this._instance_from.get (i);
206         propertyValue = objName.getKeyProperty (propertyName);
207         if (propertyValue == null)
208         {
209           Collectd.logError ("GenericJMXConfMBean: "
210               + "No such property in object name: " + propertyName);
211         }
212         else
213         {
214           instanceList.add (propertyValue);
215         }
216       }
217
218       if (instance_prefix != null)
219         instance.append (instance_prefix);
220
221       if (this._instance_prefix != null)
222         instance.append (this._instance_prefix);
223
224       for (int i = 0; i < instanceList.size (); i++)
225       {
226         if (i > 0)
227           instance.append ("-");
228         instance.append (instanceList.get (i));
229       }
230
231       pd_tmp.setPluginInstance (instance.toString ());
232
233       Collectd.logDebug ("GenericJMXConfMBean: instance = " + instance.toString ());
234
235       for (int i = 0; i < this._values.size (); i++)
236         this._values.get (i).query (conn, objName, pd_tmp);
237     }
238
239     return (0);
240   } /* }}} void query */
241 }
242
243 /* vim: set sw=2 sts=2 et fdm=marker : */