KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > controller > jmx > RmiConnector


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2004 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: c-jdbc@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Marc Wick.
22  * Contributor(s): ______________________.
23  */

24
25 package org.objectweb.cjdbc.controller.jmx;
26
27 import java.net.InetAddress JavaDoc;
28 import java.net.UnknownHostException JavaDoc;
29 import java.rmi.Remote JavaDoc;
30 import java.rmi.registry.LocateRegistry JavaDoc;
31 import java.rmi.server.UnicastRemoteObject JavaDoc;
32 import java.util.ArrayList JavaDoc;
33 import java.util.Date JavaDoc;
34 import java.util.Hashtable JavaDoc;
35 import java.util.Iterator JavaDoc;
36 import java.util.List JavaDoc;
37
38 import javax.management.Notification JavaDoc;
39 import javax.management.remote.JMXAuthenticator JavaDoc;
40 import javax.management.remote.JMXConnectorServer JavaDoc;
41 import javax.management.remote.rmi.RMIConnectorServer JavaDoc;
42 import javax.naming.Context JavaDoc;
43
44 import org.objectweb.cjdbc.common.i18n.Translate;
45 import org.objectweb.cjdbc.common.jmx.JmxException;
46 import org.objectweb.cjdbc.common.jmx.notifications.JmxNotification;
47 import org.objectweb.cjdbc.common.log.Trace;
48 import org.objectweb.cjdbc.common.net.RMISSLClientSocketFactory;
49 import org.objectweb.cjdbc.common.net.RMISSLServerSocketFactory;
50 import org.objectweb.cjdbc.common.net.SSLConfiguration;
51 import org.objectweb.cjdbc.common.net.SocketFactoryFactory;
52 import org.objectweb.cjdbc.controller.authentication.PasswordAuthenticator;
53
54 /**
55  * This class defines a RmiConnector
56  *
57  * @author <a HREF="mailto:marc.wick@monte-bre.ch">Marc Wick </a>
58  * @version 1.0
59  */

60 public class RmiConnector
61 {
62   static Trace logger = Trace
63                                                .getLogger("org.objectweb.cjdbc.controller.jmx");
64
65   private String JavaDoc controllerName;
66   private String JavaDoc hostName;
67   private int port;
68   private JMXAuthenticator JavaDoc authenticator;
69   private SSLConfiguration sslConfig;
70
71   /**
72    * we have to keep a reference to the server to avoid it from being garbage
73    * collected otherwise the client will throw a java.rmi.NoSuchObjectException
74    * (problem experienced with ssl connections)
75    */

76   private JMXConnectorServer JavaDoc connection;
77   private Remote JavaDoc rmiRegistry;
78
79   private static List JavaDoc rmiConnectors = new ArrayList JavaDoc();
80
81   /**
82    * Creates a new <code>RmiConnector.java</code> object
83    *
84    * @param controllerName for reference when sending notification
85    * @param hostName the name of the host we bind to, if null the default
86    * InetAddress.getLocalHost().getHostName() is used
87    * @param port the port the rmi registry is listening on
88    * @param authenticator the jmxauthenticator used for the connection
89    * @param sslConfig ssl configuration
90    * @throws JmxException the name of the localhost could not be determined
91    */

92   public RmiConnector(String JavaDoc controllerName, String JavaDoc hostName, int port,
93       JMXAuthenticator JavaDoc authenticator, SSLConfiguration sslConfig)
94       throws JmxException
95   {
96     if (hostName != null)
97     {
98       this.hostName = hostName;
99     }
100     else
101     {
102       try
103       {
104         /** TODO: dssmith - determine applicability of getLocalHost() */
105         this.hostName = InetAddress.getLocalHost().getHostName();
106       }
107       catch (UnknownHostException JavaDoc ex)
108       {
109         throw new JmxException(ex);
110       }
111     }
112     this.controllerName = controllerName;
113     this.port = port;
114     this.authenticator = authenticator;
115     this.sslConfig = sslConfig;
116
117     addRmiConnector(this);
118   }
119
120   /**
121    * Returns the authenticator value.
122    *
123    * @return Returns the authenticator.
124    */

125   public JMXAuthenticator JavaDoc getAuthenticator()
126   {
127     return authenticator;
128   }
129
130   /**
131    * Sets the authenticator value.
132    *
133    * @param authenticator The authenticator to set.
134    */

135   public void setAuthenticator(JMXAuthenticator JavaDoc authenticator)
136   {
137     this.authenticator = authenticator;
138   }
139
140   /**
141    * Returns the port value.
142    *
143    * @return Returns the port.
144    */

145   public int getPort()
146   {
147     return port;
148   }
149
150   /**
151    * Sets the port value.
152    *
153    * @param port The port to set.
154    */

155   public void setPort(int port)
156   {
157     this.port = port;
158   }
159
160   /**
161    * Returns the sslConfig value.
162    *
163    * @return Returns the sslConfig.
164    */

165   public SSLConfiguration getSslConfig()
166   {
167     return sslConfig;
168   }
169
170   /**
171    * Sets the sslConfig value.
172    *
173    * @param sslConfig The sslConfig to set.
174    */

175   public void setSslConfig(SSLConfiguration sslConfig)
176   {
177     this.sslConfig = sslConfig;
178   }
179
180   /**
181    * Returns the connection value.
182    *
183    * @return Returns the connection.
184    */

185   public JMXConnectorServer JavaDoc getConnection()
186   {
187     return connection;
188   }
189
190   /**
191    * start the rmi connector and the rmi naming service
192    *
193    * @throws JmxException an exception
194    */

195   public void start() throws JmxException
196   {
197     createNamingService();
198     createJRMPAdaptor();
199   }
200
201   /**
202    * stop the rmi connector and the rmi registry
203    *
204    * @throws JmxException an exception
205    */

206   public void stop() throws JmxException
207   {
208     try
209     {
210       if (connection != null)
211         connection.stop();
212       if (rmiRegistry != null)
213         UnicastRemoteObject.unexportObject(rmiRegistry, true);
214     }
215     catch (Exception JavaDoc e)
216     {
217       throw new JmxException(e);
218     }
219     finally
220     {
221       connection = null;
222       rmiRegistry = null;
223     }
224   }
225
226   /**
227    * Create naming service and starts rmi
228    *
229    * @throws JmxException if creation fails
230    */

231   private void createNamingService() throws JmxException
232   {
233     try
234     {
235       // create and start the naming service
236
logger.info(Translate.get("jmx.create.naming.service", new String JavaDoc[]{""
237           + port}));
238       rmiRegistry = LocateRegistry.createRegistry(port);
239     }
240     catch (Exception JavaDoc e)
241     {
242       throw new JmxException(e);
243     }
244   }
245
246   private void createJRMPAdaptor() throws JmxException
247   {
248     try
249     {
250       // create the JRMP adaptator
251
logger.info(Translate.get("jmx.create.jrmp.adaptor", "" + port));
252
253       // Set the jndi name with which it will be registered
254
// JNDI properties
255
logger.debug(Translate.get("jmx.prepare.jndi"));
256
257       javax.management.remote.JMXServiceURL JavaDoc address = new javax.management.remote.JMXServiceURL JavaDoc(
258           "rmi", hostName, 0, "/jndi/jrmp");
259
260       java.util.Map JavaDoc environment = new java.util.HashMap JavaDoc();
261       environment.put(Context.INITIAL_CONTEXT_FACTORY,
262           "com.sun.jndi.rmi.registry.RegistryContextFactory");
263       environment.put(Context.PROVIDER_URL, "rmi://" + hostName + ":" + port);
264
265       if (authenticator == null)
266       {
267         authenticator = PasswordAuthenticator.NO_AUTHENICATION;
268       }
269
270       if (authenticator != null)
271       {
272         environment.put(JMXConnectorServer.AUTHENTICATOR, authenticator);
273       }
274
275       // ssl enabled ?
276
if (sslConfig != null)
277       {
278         logger.info(Translate.get("jmx.create.jrmp.ssl.enabled"));
279
280         RMISSLClientSocketFactory csf = new RMISSLClientSocketFactory();
281         RMISSLServerSocketFactory ssf = new RMISSLServerSocketFactory(
282             SocketFactoryFactory.createServerFactory(sslConfig));
283         environment.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE,
284             csf);
285         environment.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE,
286             ssf);
287       }
288
289       connection = javax.management.remote.JMXConnectorServerFactory
290           .newJMXConnectorServer(address, environment, MBeanServerManager
291               .getInstance());
292
293       connection.start();
294     }
295     catch (Exception JavaDoc e)
296     {
297       throw new JmxException(e);
298     }
299   }
300
301   /**
302    * Returns a list of rmiConnectors .
303    *
304    * @return Returns list of RmiConnector.
305    */

306   public static List JavaDoc getRmiConnectors()
307   {
308     return rmiConnectors;
309   }
310
311   /**
312    * Adds an rmiConnector to the list.
313    *
314    * @param pRmiConnector The rmiConnector to add.
315    */

316   private static synchronized void addRmiConnector(RmiConnector pRmiConnector)
317   {
318     rmiConnectors.add(pRmiConnector);
319   }
320
321   /**
322    * @return Returns the controllerName.
323    */

324   public String JavaDoc getControllerName()
325   {
326     return controllerName;
327   }
328
329   /**
330    * @return Returns the hostName.
331    */

332   public String JavaDoc getHostName()
333   {
334     return hostName;
335   }
336
337   private Date JavaDoc myDate;
338   private long time;
339   private JmxNotification cjdbcNotification;
340   private Notification JavaDoc notification;
341   private static long sequence = 0;
342
343   /**
344    * This method sends notification to all client registered to an instance of
345    * the <code>RmiConnector</code> class. The <code>JmxNotification</code>
346    * class is used here to create an object with all the information gathered in
347    * parameters, and then is serialized in xml for interaction on the client
348    * side.
349    *
350    * @see JmxNotification
351    * @param mbean the mbean that is generating the notification
352    * @param type the type as seen in <code>CjdbcNotificationList</code>
353    * @param priority notification level as seen in
354    * <code>CjdbcNotificationList</code>
355    * @param description a string description of the notification
356    * @param data a hashtable of data that can be used to give more information
357    * on the notification
358    */

359   public synchronized void sendNotification(AbstractStandardMBean mbean,
360       String JavaDoc type, String JavaDoc priority, String JavaDoc description, Hashtable JavaDoc data)
361   {
362
363     myDate = new Date JavaDoc();
364     time = myDate.getTime();
365
366     cjdbcNotification = new JmxNotification(priority, "" + sequence, type,
367         description, "" + time, controllerName, mbean.getClass().getName(),
368         "mbeanName", hostName, "" + port, data);
369     notification = new Notification JavaDoc(type, mbean, sequence, myDate.getTime(),
370         description);
371     notification.setUserData(cjdbcNotification.toString());
372     mbean.sendNotification(notification);
373   }
374
375   /**
376    * Broadcast a jmx notification to any client connected to any RmiConnector
377    * registered in the static list. The method is static because it is sending
378    * notifications to all rmi connectors.
379    *
380    * @param mbean the mbean that is generating the notification
381    * @param type the type as seen in <code>CjdbcNotificationList</code>
382    * @param priority notification level as seen in
383    * <code>CjdbcNotificationList</code>
384    * @param description a string description of the notification
385    * @param data a hashtable of data that can be used to give more information
386    * on the notification
387    */

388   public static void broadcastNotification(AbstractStandardMBean mbean,
389       String JavaDoc type, String JavaDoc priority, String JavaDoc description, Hashtable JavaDoc data)
390   {
391     sequence++;
392     logger.info("Sending notification:" + description + "(Message No:"
393         + sequence + ")");
394     Iterator JavaDoc iter = rmiConnectors.iterator();
395     RmiConnector rmi;
396     while (iter.hasNext())
397     {
398       rmi = ((RmiConnector) iter.next());
399       rmi.sendNotification(mbean, type, priority, description, data);
400     }
401   }
402 }
Popular Tags