Main Page | Packages | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

RmiConnector.java

00001 /**
00002  * C-JDBC: Clustered JDBC.
00003  * Copyright (C) 2002-2004 French National Institute For Research In Computer
00004  * Science And Control (INRIA).
00005  * Contact: c-jdbc@objectweb.org
00006  * 
00007  * This library is free software; you can redistribute it and/or modify it
00008  * under the terms of the GNU Lesser General Public License as published by the
00009  * Free Software Foundation; either version 2.1 of the License, or any later
00010  * version.
00011  * 
00012  * This library is distributed in the hope that it will be useful, but WITHOUT
00013  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
00015  * for more details.
00016  * 
00017  * You should have received a copy of the GNU Lesser General Public License
00018  * along with this library; if not, write to the Free Software Foundation,
00019  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00020  *
00021  * Initial developer(s): Marc Wick.
00022  * Contributor(s): ______________________.
00023  */
00024 
00025 package org.objectweb.cjdbc.controller.jmx;
00026 
00027 import java.net.InetAddress;
00028 import java.net.UnknownHostException;
00029 import java.rmi.Remote;
00030 import java.rmi.registry.LocateRegistry;
00031 import java.rmi.server.UnicastRemoteObject;
00032 import java.util.ArrayList;
00033 import java.util.Date;
00034 import java.util.Hashtable;
00035 import java.util.Iterator;
00036 import java.util.List;
00037 
00038 import javax.management.Notification;
00039 import javax.management.remote.JMXAuthenticator;
00040 import javax.management.remote.JMXConnectorServer;
00041 import javax.management.remote.rmi.RMIConnectorServer;
00042 import javax.naming.Context;
00043 
00044 import org.objectweb.cjdbc.common.i18n.Translate;
00045 import org.objectweb.cjdbc.common.jmx.JmxException;
00046 import org.objectweb.cjdbc.common.jmx.notifications.JmxNotification;
00047 import org.objectweb.cjdbc.common.log.Trace;
00048 import org.objectweb.cjdbc.common.net.RMISSLClientSocketFactory;
00049 import org.objectweb.cjdbc.common.net.RMISSLServerSocketFactory;
00050 import org.objectweb.cjdbc.common.net.SSLConfiguration;
00051 import org.objectweb.cjdbc.common.net.SocketFactoryFactory;
00052 import org.objectweb.cjdbc.controller.authentication.PasswordAuthenticator;
00053 
00054 /**
00055  * This class defines a RmiConnector
00056  * 
00057  * @author <a href="mailto:marc.wick@monte-bre.ch">Marc Wick </a>
00058  * @version 1.0
00059  */
00060 public class RmiConnector
00061 {
00062   static Trace               logger        = Trace
00063                                                .getLogger("org.objectweb.cjdbc.controller.jmx");
00064 
00065   private String             controllerName;
00066   private String             hostName;
00067   private int                port;
00068   private JMXAuthenticator   authenticator;
00069   private SSLConfiguration   sslConfig;
00070 
00071   /**
00072    * we have to keep a reference to the server to avoid it from being garbage
00073    * collected otherwise the client will throw a java.rmi.NoSuchObjectException
00074    * (problem experienced with ssl connections)
00075    */
00076   private JMXConnectorServer connection;
00077   private Remote             rmiRegistry;
00078 
00079   private static List        rmiConnectors = new ArrayList();
00080 
00081   /**
00082    * Creates a new <code>RmiConnector.java</code> object
00083    * 
00084    * @param controllerName for reference when sending notification
00085    * @param hostName the name of the host we bind to, if null the default
00086    *          InetAddress.getLocalHost().getHostName() is used
00087    * @param port the port the rmi registry is listening on
00088    * @param authenticator the jmxauthenticator used for the connection
00089    * @param sslConfig ssl configuration
00090    * @throws JmxException the name of the localhost could not be determined
00091    */
00092   public RmiConnector(String controllerName, String hostName, int port,
00093       JMXAuthenticator authenticator, SSLConfiguration sslConfig)
00094       throws JmxException
00095   {
00096     if (hostName != null)
00097     {
00098       this.hostName = hostName;
00099     }
00100     else
00101     {
00102       try
00103       {
00104         /** TODO: dssmith - determine applicability of getLocalHost() */
00105         this.hostName = InetAddress.getLocalHost().getHostName();
00106       }
00107       catch (UnknownHostException ex)
00108       {
00109         throw new JmxException(ex);
00110       }
00111     }
00112     this.controllerName = controllerName;
00113     this.port = port;
00114     this.authenticator = authenticator;
00115     this.sslConfig = sslConfig;
00116 
00117     addRmiConnector(this);
00118   }
00119 
00120   /**
00121    * Returns the authenticator value.
00122    * 
00123    * @return Returns the authenticator.
00124    */
00125   public JMXAuthenticator getAuthenticator()
00126   {
00127     return authenticator;
00128   }
00129 
00130   /**
00131    * Sets the authenticator value.
00132    * 
00133    * @param authenticator The authenticator to set.
00134    */
00135   public void setAuthenticator(JMXAuthenticator authenticator)
00136   {
00137     this.authenticator = authenticator;
00138   }
00139 
00140   /**
00141    * Returns the port value.
00142    * 
00143    * @return Returns the port.
00144    */
00145   public int getPort()
00146   {
00147     return port;
00148   }
00149 
00150   /**
00151    * Sets the port value.
00152    * 
00153    * @param port The port to set.
00154    */
00155   public void setPort(int port)
00156   {
00157     this.port = port;
00158   }
00159 
00160   /**
00161    * Returns the sslConfig value.
00162    * 
00163    * @return Returns the sslConfig.
00164    */
00165   public SSLConfiguration getSslConfig()
00166   {
00167     return sslConfig;
00168   }
00169 
00170   /**
00171    * Sets the sslConfig value.
00172    * 
00173    * @param sslConfig The sslConfig to set.
00174    */
00175   public void setSslConfig(SSLConfiguration sslConfig)
00176   {
00177     this.sslConfig = sslConfig;
00178   }
00179 
00180   /**
00181    * Returns the connection value.
00182    * 
00183    * @return Returns the connection.
00184    */
00185   public JMXConnectorServer getConnection()
00186   {
00187     return connection;
00188   }
00189 
00190   /**
00191    * start the rmi connector and the rmi naming service
00192    * 
00193    * @throws JmxException an exception
00194    */
00195   public void start() throws JmxException
00196   {
00197     createNamingService();
00198     createJRMPAdaptor();
00199   }
00200 
00201   /**
00202    * stop the rmi connector and the rmi registry
00203    * 
00204    * @throws JmxException an exception
00205    */
00206   public void stop() throws JmxException
00207   {
00208     try
00209     {
00210       if (connection != null)
00211         connection.stop();
00212       if (rmiRegistry != null)
00213         UnicastRemoteObject.unexportObject(rmiRegistry, true);
00214     }
00215     catch (Exception e)
00216     {
00217       throw new JmxException(e);
00218     }
00219     finally
00220     {
00221       connection = null;
00222       rmiRegistry = null;
00223     }
00224   }
00225 
00226   /**
00227    * Create naming service and starts rmi
00228    * 
00229    * @throws JmxException if creation fails
00230    */
00231   private void createNamingService() throws JmxException
00232   {
00233     try
00234     {
00235       // create and start the naming service
00236       logger.info(Translate.get("jmx.create.naming.service", new String[]{""
00237           + port}));
00238       rmiRegistry = LocateRegistry.createRegistry(port);
00239     }
00240     catch (Exception e)
00241     {
00242       throw new JmxException(e);
00243     }
00244   }
00245 
00246   private void createJRMPAdaptor() throws JmxException
00247   {
00248     try
00249     {
00250       // create the JRMP adaptator
00251       logger.info(Translate.get("jmx.create.jrmp.adaptor", "" + port));
00252 
00253       // Set the jndi name with which it will be registered
00254       // JNDI properties
00255       logger.debug(Translate.get("jmx.prepare.jndi"));
00256 
00257       javax.management.remote.JMXServiceURL address = new javax.management.remote.JMXServiceURL(
00258           "rmi", hostName, 0, "/jndi/jrmp");
00259 
00260       java.util.Map environment = new java.util.HashMap();
00261       environment.put(Context.INITIAL_CONTEXT_FACTORY,
00262           "com.sun.jndi.rmi.registry.RegistryContextFactory");
00263       environment.put(Context.PROVIDER_URL, "rmi://" + hostName + ":" + port);
00264 
00265       if (authenticator == null)
00266       {
00267         authenticator = PasswordAuthenticator.NO_AUTHENICATION;
00268       }
00269 
00270       if (authenticator != null)
00271       {
00272         environment.put(JMXConnectorServer.AUTHENTICATOR, authenticator);
00273       }
00274 
00275       // ssl enabled ?
00276       if (sslConfig != null)
00277       {
00278         logger.info(Translate.get("jmx.create.jrmp.ssl.enabled"));
00279 
00280         RMISSLClientSocketFactory csf = new RMISSLClientSocketFactory();
00281         RMISSLServerSocketFactory ssf = new RMISSLServerSocketFactory(
00282             SocketFactoryFactory.createServerFactory(sslConfig));
00283         environment.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE,
00284             csf);
00285         environment.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE,
00286             ssf);
00287       }
00288 
00289       connection = javax.management.remote.JMXConnectorServerFactory
00290           .newJMXConnectorServer(address, environment, MBeanServerManager
00291               .getInstance());
00292 
00293       connection.start();
00294     }
00295     catch (Exception e)
00296     {
00297       throw new JmxException(e);
00298     }
00299   }
00300 
00301   /**
00302    * Returns a list of rmiConnectors .
00303    * 
00304    * @return Returns list of RmiConnector.
00305    */
00306   public static List getRmiConnectors()
00307   {
00308     return rmiConnectors;
00309   }
00310 
00311   /**
00312    * Adds an rmiConnector to the list.
00313    * 
00314    * @param pRmiConnector The rmiConnector to add.
00315    */
00316   private static synchronized void addRmiConnector(RmiConnector pRmiConnector)
00317   {
00318     rmiConnectors.add(pRmiConnector);
00319   }
00320 
00321   /**
00322    * @return Returns the controllerName.
00323    */
00324   public String getControllerName()
00325   {
00326     return controllerName;
00327   }
00328 
00329   /**
00330    * @return Returns the hostName.
00331    */
00332   public String getHostName()
00333   {
00334     return hostName;
00335   }
00336 
00337   private Date            myDate;
00338   private long            time;
00339   private JmxNotification cjdbcNotification;
00340   private Notification    notification;
00341   private static long     sequence = 0;
00342 
00343   /**
00344    * This method sends notification to all client registered to an instance of
00345    * the <code>RmiConnector</code> class. The <code>JmxNotification</code>
00346    * class is used here to create an object with all the information gathered in
00347    * parameters, and then is serialized in xml for interaction on the client
00348    * side.
00349    * 
00350    * @see JmxNotification
00351    * @param mbean the mbean that is generating the notification
00352    * @param type the type as seen in <code>CjdbcNotificationList</code>
00353    * @param priority notification level as seen in
00354    *          <code>CjdbcNotificationList</code>
00355    * @param description a string description of the notification
00356    * @param data a hashtable of data that can be used to give more information
00357    *          on the notification
00358    */
00359   public synchronized void sendNotification(AbstractStandardMBean mbean,
00360       String type, String priority, String description, Hashtable data)
00361   {
00362 
00363     myDate = new Date();
00364     time = myDate.getTime();
00365 
00366     cjdbcNotification = new JmxNotification(priority, "" + sequence, type,
00367         description, "" + time, controllerName, mbean.getClass().getName(),
00368         "mbeanName", hostName, "" + port, data);
00369     notification = new Notification(type, mbean, sequence, myDate.getTime(),
00370         description);
00371     notification.setUserData(cjdbcNotification.toString());
00372     mbean.sendNotification(notification);
00373   }
00374 
00375   /**
00376    * Broadcast a jmx notification to any client connected to any RmiConnector
00377    * registered in the static list. The method is static because it is sending
00378    * notifications to all rmi connectors.
00379    * 
00380    * @param mbean the mbean that is generating the notification
00381    * @param type the type as seen in <code>CjdbcNotificationList</code>
00382    * @param priority notification level as seen in
00383    *          <code>CjdbcNotificationList</code>
00384    * @param description a string description of the notification
00385    * @param data a hashtable of data that can be used to give more information
00386    *          on the notification
00387    */
00388   public static void broadcastNotification(AbstractStandardMBean mbean,
00389       String type, String priority, String description, Hashtable data)
00390   {
00391     sequence++;
00392     logger.info("Sending notification:" + description + "(Message No:"
00393         + sequence + ")");
00394     Iterator iter = rmiConnectors.iterator();
00395     RmiConnector rmi;
00396     while (iter.hasNext())
00397     {
00398       rmi = ((RmiConnector) iter.next());
00399       rmi.sendNotification(mbean, type, priority, description, data);
00400     }
00401   }
00402 }

Generated on Mon Apr 11 22:01:34 2005 for C-JDBC by  doxygen 1.3.9.1