Merge branch 'sh/postgresql-writer'
[collectd.git] / bindings / java / org / collectd / java / GenericJMXConfConnection.java
1 /*
2  * collectd/java - org/collectd/java/GenericJMXConfConnection.java
3  * Copyright (C) 2009-2012  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 collectd.org>
20  */
21
22 package org.collectd.java;
23
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Iterator;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.net.InetAddress;
30
31 import javax.management.MBeanServerConnection;
32 import javax.management.ObjectName;
33 import javax.management.MalformedObjectNameException;
34
35 import javax.management.remote.JMXServiceURL;
36 import javax.management.remote.JMXConnector;
37 import javax.management.remote.JMXConnectorFactory;
38
39 import org.collectd.api.Collectd;
40 import org.collectd.api.PluginData;
41 import org.collectd.api.OConfigValue;
42 import org.collectd.api.OConfigItem;
43
44 class GenericJMXConfConnection
45 {
46   private String _username = null;
47   private String _password = null;
48   private String _host = null;
49   private String _instance_prefix = null;
50   private String _service_url = null;
51   private MBeanServerConnection _jmx_connection = null;
52   private List<GenericJMXConfMBean> _mbeans = null;
53
54   /*
55    * private methods
56    */
57   private String getConfigString (OConfigItem ci) /* {{{ */
58   {
59     List<OConfigValue> values;
60     OConfigValue v;
61
62     values = ci.getValues ();
63     if (values.size () != 1)
64     {
65       Collectd.logError ("GenericJMXConfConnection: The " + ci.getKey ()
66           + " configuration option needs exactly one string argument.");
67       return (null);
68     }
69
70     v = values.get (0);
71     if (v.getType () != OConfigValue.OCONFIG_TYPE_STRING)
72     {
73       Collectd.logError ("GenericJMXConfConnection: The " + ci.getKey ()
74           + " configuration option needs exactly one string argument.");
75       return (null);
76     }
77
78     return (v.getString ());
79   } /* }}} String getConfigString */
80
81   private String getHost () /* {{{ */
82   {
83     if (this._host != null)
84     {
85       return (this._host);
86     }
87
88     try
89     {
90       InetAddress localHost = InetAddress.getLocalHost();
91       return (localHost.getHostName ());
92     }
93     catch (UnknownHostException e)
94     {
95       return ("localhost");
96     }
97   } /* }}} String getHost */
98
99 private void connect () /* {{{ */
100 {
101   JMXServiceURL service_url;
102   JMXConnector connector;
103   Map environment;
104
105   if (_jmx_connection != null)
106     return;
107
108   environment = null;
109   if (this._password != null)
110   {
111     String[] credentials;
112
113     if (this._username == null)
114       this._username = new String ("monitorRole");
115
116     credentials = new String[] { this._username, this._password };
117
118     environment = new HashMap ();
119     environment.put (JMXConnector.CREDENTIALS, credentials);
120   }
121
122   try
123   {
124     service_url = new JMXServiceURL (this._service_url);
125     connector = JMXConnectorFactory.connect (service_url, environment);
126     _jmx_connection = connector.getMBeanServerConnection ();
127   }
128   catch (Exception e)
129   {
130     Collectd.logError ("GenericJMXConfConnection: "
131         + "Creating MBean server connection failed: " + e);
132     return;
133   }
134 } /* }}} void connect */
135
136 /*
137  * public methods
138  *
139  * <Connection>
140  *   Host "tomcat0.mycompany"
141  *   ServiceURL "service:jmx:rmi:///jndi/rmi://localhost:17264/jmxrmi"
142  *   Collect "java.lang:type=GarbageCollector,name=Copy"
143  *   Collect "java.lang:type=Memory"
144  * </Connection>
145  *
146  */
147   public GenericJMXConfConnection (OConfigItem ci) /* {{{ */
148     throws IllegalArgumentException
149   {
150     List<OConfigItem> children;
151     Iterator<OConfigItem> iter;
152
153     this._mbeans = new ArrayList<GenericJMXConfMBean> ();
154
155     children = ci.getChildren ();
156     iter = children.iterator ();
157     while (iter.hasNext ())
158     {
159       OConfigItem child = iter.next ();
160
161       if (child.getKey ().equalsIgnoreCase ("Host"))
162       {
163         String tmp = getConfigString (child);
164         if (tmp != null)
165           this._host = tmp;
166       }
167       else if (child.getKey ().equalsIgnoreCase ("User"))
168       {
169         String tmp = getConfigString (child);
170         if (tmp != null)
171           this._username = tmp;
172       }
173       else if (child.getKey ().equalsIgnoreCase ("Password"))
174       {
175         String tmp = getConfigString (child);
176         if (tmp != null)
177           this._password = tmp;
178       }
179       else if (child.getKey ().equalsIgnoreCase ("ServiceURL"))
180       {
181         String tmp = getConfigString (child);
182         if (tmp != null)
183           this._service_url = tmp;
184       }
185       else if (child.getKey ().equalsIgnoreCase ("InstancePrefix"))
186       {
187         String tmp = getConfigString (child);
188         if (tmp != null)
189           this._instance_prefix = tmp;
190       }
191       else if (child.getKey ().equalsIgnoreCase ("Collect"))
192       {
193         String tmp = getConfigString (child);
194         if (tmp != null)
195         {
196           GenericJMXConfMBean mbean;
197
198           mbean = GenericJMX.getMBean (tmp);
199           if (mbean == null)
200             throw (new IllegalArgumentException ("No such MBean defined: "
201                   + tmp + ". Please make sure all `MBean' blocks appear "
202                   + "before (above) all `Connection' blocks."));
203           Collectd.logDebug ("GenericJMXConfConnection: " + this._host + ": Add " + tmp);
204           this._mbeans.add (mbean);
205         }
206       }
207       else
208         throw (new IllegalArgumentException ("Unknown option: "
209               + child.getKey ()));
210     }
211
212     if (this._service_url == null)
213       throw (new IllegalArgumentException ("No service URL was defined."));
214     if (this._mbeans.size () == 0)
215       throw (new IllegalArgumentException ("No valid collect statement "
216             + "present."));
217   } /* }}} GenericJMXConfConnection (OConfigItem ci) */
218
219   public void query () /* {{{ */
220   {
221     PluginData pd;
222
223     connect ();
224
225     if (this._jmx_connection == null)
226       return;
227
228     Collectd.logDebug ("GenericJMXConfConnection.query: "
229         + "Reading " + this._mbeans.size () + " mbeans from "
230         + ((this._host != null) ? this._host : "(null)"));
231
232     pd = new PluginData ();
233     pd.setHost (this.getHost ());
234     pd.setPlugin ("GenericJMX");
235
236     for (int i = 0; i < this._mbeans.size (); i++)
237     {
238       int status;
239
240       status = this._mbeans.get (i).query (this._jmx_connection, pd,
241           this._instance_prefix);
242       if (status != 0)
243       {
244         this._jmx_connection = null;
245         return;
246       }
247     } /* for */
248   } /* }}} void query */
249
250   public String toString ()
251   {
252     return (new String ("host = " + this._host + "; "
253           + "url = " + this._service_url));
254   }
255 }
256
257 /* vim: set sw=2 sts=2 et fdm=marker : */