KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > admin > jmx > remote > server > rmi > JmxConnectorServerDriver


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * JmxConnectorServerDriver.java
26  * Indentation Information:
27  * 0. Please (try to) preserve these settings.
28  * 1. No tabs are used, all spaces.
29  * 2. In vi/vim -
30  * :set tabstop=4 :set shiftwidth=4 :set softtabstop=4
31  * 3. In S1 Studio -
32  * 1. Tools->Options->Editor Settings->Java Editor->Tab Size = 4
33  * 2. Tools->Options->Indentation Engines->Java Indentation Engine->Expand Tabs to Spaces = True.
34  * 3. Tools->Options->Indentation Engines->Java Indentation Engine->Number of Spaces per Tab = 4.
35  * Unit Testing Information:
36  * 0. Is Standard Unit Test Written (y/n):
37  * 1. Unit Test Location: (The instructions should be in the Unit Test Class itself).
38  */

39
40 package com.sun.enterprise.admin.jmx.remote.server.rmi;
41
42 import java.io.IOException JavaDoc;
43 import java.net.ServerSocket JavaDoc;
44 import java.util.Map JavaDoc;
45 import java.util.HashMap JavaDoc;
46 import java.rmi.RemoteException JavaDoc;
47 import java.rmi.server.RMIServerSocketFactory JavaDoc;
48 import java.rmi.server.RMIClientSocketFactory JavaDoc;
49 import java.util.logging.Logger JavaDoc;
50 import java.util.logging.Level JavaDoc;
51 import javax.management.MBeanServer JavaDoc;
52 import javax.management.remote.JMXServiceURL JavaDoc;
53 import javax.management.remote.JMXConnectorServer JavaDoc;
54 import javax.management.remote.JMXConnectorServerFactory JavaDoc;
55 import javax.management.remote.JMXAuthenticator JavaDoc;
56 import javax.management.remote.rmi.RMIConnectorServer JavaDoc;
57 import javax.rmi.ssl.SslRMIClientSocketFactory JavaDoc;
58
59 import com.sun.enterprise.admin.jmx.remote.IStringManager;
60 import com.sun.enterprise.admin.jmx.remote.StringManagerFactory;
61 import com.sun.enterprise.admin.jmx.remote.server.rmi.RemoteJmxProtocol;
62 import com.sun.enterprise.admin.jmx.remote.server.rmi.JmxServiceUrlFactory;
63
64 /** A Class to initialize the JMX Connector Servers in the system. It has its own
65  * configuration that determines the characteristics of the connector server end
66  * that will be started. It is important to note the various configurable
67  * parameters provided by this class.
68  * Implementation Note: This class is <code> not </code> thread safe. Callers
69  * have to take care of serialization of calls when necessary.
70  * @author kedar
71  * @since Sun Java System Application Server 8.1
72  */

73
74 public class JmxConnectorServerDriver {
75     private static IStringManager sm = StringManagerFactory.getServerStringManager( JmxConnectorServerDriver.class );
76     private final Map JavaDoc env;
77     private JMXServiceURL JavaDoc url;
78     private JMXServiceURL JavaDoc jconsoleurl;
79     private int port;
80     private RemoteJmxProtocol protocol;
81     private boolean secureRegistry;
82     private boolean ssl;
83     private RMIServerSocketFactory JavaDoc rmissf;
84     private RMIClientSocketFactory JavaDoc rmicsf;
85     private boolean auth;
86     private JMXAuthenticator JavaDoc authenticator;
87     private Logger JavaDoc logger;
88     private MBeanServer JavaDoc mbs;
89     
90     /** Creates a JMXConnectorServerDriver instance with default values for
91      * the various parameters. The protocol defaults to "rmi/jrmp". The rmi
92      registry is not secure by default. An available port is selected. The
93      authentication is turned off by default. */

94     
95     public JmxConnectorServerDriver() {
96         this.env = new HashMap JavaDoc();
97         this.protocol = RemoteJmxProtocol.RMIJRMP;
98         this.secureRegistry = false;
99         this.port = getFreePort();
100         this.ssl = false;
101         this.auth = false;
102         this.authenticator = null;
103         logger = Logger.getLogger(this.getClass().getName());
104     }
105     
106     /** Sets the protocol to one of the values in RemoteJmxProtocol.
107      * @see RemoteJmxProtocol
108      */

109     public void setProtocol(final RemoteJmxProtocol protocol) {
110         this.protocol = protocol;
111     }
112     /** Sets the port to the given value.
113      * Note that NO checks whatsoever made for the validity of port
114      */

115     public void setPort(final int port) {
116         // not going to check for port validity
117
this.port = port;
118     }
119     /** Sets if Transport Layer Security is on. Additional configuration is needed when ssl is on.
120      */

121     public void setSsl(final boolean ssl) {
122         this.ssl = ssl;
123     }
124     
125     /** Sets the RMIServerSocketFactory. This is the custom server socket factory that
126      * RMI Connector Server would use. Really useful only if ssl is set to true by
127      * using setSsl(true). If ssl is false, this value is not passed on to the
128      * environmental map of connector server. If ssl is true then this value can not be null.
129      */

130     public void setRmiServerSocketFactory(final RMIServerSocketFactory JavaDoc f) {
131         if (ssl && f == null)
132             throw new IllegalArgumentException JavaDoc("Internal: null server socket factory passed with ssl ON");
133         this.rmissf = f;
134     }
135     /** Sets the RMIClientSocketFactory. This is the custom client socket factory that
136      * RMI Connector Server would use. Really useful only if ssl is set to true by
137      * using setSsl(true). If ssl is false, this value is not passed on to the
138      * environmental map of connector server. If ssl is true this value can not be null.
139      */

140     public void setRmiClientSocketFactory(final RMIClientSocketFactory JavaDoc f) {
141         if (ssl && f == null)
142             throw new IllegalArgumentException JavaDoc("Internal: null client socket factory passed with ssl ON");
143         this.rmicsf = f;
144     }
145     /** Sets Authentication value. If true, then every connection establishment
146      * should be authenticated. This is generally done by implementation of
147      * JMXAuthenticator interface.
148      */

149     public void setAuthentication(final boolean auth) {
150         this.auth = auth;
151     }
152     /** Sets the Logger */
153     public void setLogger (final Logger JavaDoc logger) {
154         if (logger == null)
155             throw new IllegalArgumentException JavaDoc("Internal: null logger");
156         this.logger = logger;
157     }
158     /** Sets the Authenticator Object. This Object is responsible for
159      * authenticating the connection.
160      */

161     public void setAuthenticator(final JMXAuthenticator JavaDoc authenticator) {
162         //TODO
163
//if (authenticator == null)
164
//throw new IllegalArgumentException ("null authenticator");
165
this.authenticator = authenticator;
166     }
167     /** Sets if the rmi registry is secure.
168      */

169     public void setRmiRegistrySecureFlag(final boolean secure) {
170         this.secureRegistry = secure;
171     }
172     /** Sets the MBeanServer that will be associated with the created Connector Server.
173         May not be null.
174      * @throws IllegalArgumentException in case the argument is null.
175      */

176     public void setMBeanServer(final MBeanServer JavaDoc mbs) {
177         if (mbs == null)
178             throw new IllegalArgumentException JavaDoc ("null mbs");
179         this.mbs = mbs;
180     }
181     /** Starts the configured ConnectorServer. Note that the same
182      * connector server is returned. Internally the naming service may be
183      * started if need be. In case of RMI Connector, as of June 2004 the
184      * rmi registry is started.
185      * @throws IOException if the connector server could not be started.
186      */

187     public JMXConnectorServer JavaDoc startConnectorServer() throws IOException JavaDoc {
188         //using the jndi form everywhere as stub-form is not usable.
189
prepare();
190         formJmxServiceUrl();
191         createEnvironment();
192         
193         final JMXConnectorServer JavaDoc cs =
194             JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
195
196         cs.start();
197         logStartup(cs);
198         return ( cs );
199     }
200     
201     public JMXConnectorServer JavaDoc startJconsoleConnectorServer() throws IOException JavaDoc {
202         // This env is ditto with the System JMX Connector Server, except SSL ClientSocketFactory.
203
final RMIClientSocketFactory JavaDoc cf = new SslRMIClientSocketFactory JavaDoc();
204         final Map JavaDoc jconsoleenv = new HashMap JavaDoc(env);
205         if (ssl)
206             jconsoleenv.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, cf);
207         final JMXConnectorServer JavaDoc jconsolecs =
208             JMXConnectorServerFactory.newJMXConnectorServer(jconsoleurl, jconsoleenv, mbs);
209         jconsolecs.start();
210         logJconsoleStartup(jconsolecs);
211         return ( jconsolecs );
212     }
213
214     /** A wrapper to shutdown the passed connector server. This method, in that
215      * regard just behaves like a static method. <code> Note that ref may not
216      * be null. </code>
217      * @param cs instance of JMXConnectorServer that needs to be stopped
218      * @throws IOException in case the stopping process throws any exception
219      */

220     public void stopConnectorServer(final JMXConnectorServer JavaDoc cs) throws IOException JavaDoc {
221         final String JavaDoc cad = cs.getAddress().toString();
222         if (cs.isActive()) {
223             logger.log(Level.FINE, "rjmx.lc.stopping", cad);
224             cs.stop();
225         }
226         else {
227             final String JavaDoc msg = "JMX Connector Server: " + cad + " is not active";
228             logger.fine(msg);
229         }
230     }
231     /* Private Methods - Start */
232     private void logStartup(final JMXConnectorServer JavaDoc cs) {
233         logger.log(Level.FINE, "rjmx.lc.address", cs.getAddress().toString());
234         logger.log(Level.FINE, "rjmx.lc.status", "" + cs.isActive());
235     }
236     
237     
238     private void logJconsoleStartup(final JMXConnectorServer JavaDoc cs) {
239         logger.log(Level.INFO, "rjmx.std.address", cs.getAddress().toString());
240         logger.log(Level.INFO, "rjmx.std.status", "" + cs.isActive());
241     }
242     
243     private void formJmxServiceUrl() {
244         //Note that the Connector Server can only be started on the host where this method is called
245
if (protocol == RemoteJmxProtocol.RMIJRMP) {
246             this.url = JmxServiceUrlFactory.forRmiWithJndiInAppserver(
247                 JmxServiceUrlFactory.localhost(), this.port);
248             this.jconsoleurl = JmxServiceUrlFactory.forJconsoleOverRmiWithJndiInAppserver(
249                 JmxServiceUrlFactory.localhost(), this.port);
250         }
251     }
252     private void prepare() {
253         if (protocol == RemoteJmxProtocol.RMIJRMP) {
254             new RmiStubRegistryHandler(port, secureRegistry, logger);
255         }
256     }
257     
258     private void createEnvironment() {
259         env.clear();
260         handleSsl();
261         handleAuth();
262     }
263     
264     private void handleSsl () {
265         if (protocol == RemoteJmxProtocol.RMIJRMP)
266             env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, rmissf);
267         if (ssl) env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, rmicsf);
268     }
269     private void handleAuth() {
270         if (protocol == RemoteJmxProtocol.RMIJRMP ||
271             protocol == RemoteJmxProtocol.RMIIIOP) {
272             if (auth) {
273                 if (authenticator == null) {
274                     String JavaDoc msg = "Internal: The authentication is on, but the authenticator is null";
275                     throw new IllegalArgumentException JavaDoc("msg");
276                 }
277                 env.put(JMXConnectorServer.AUTHENTICATOR, authenticator);
278             }
279         }
280     }
281     
282     /**
283         Gets a free port at the time of call to this method.
284         The logic leverages the built in java.net.ServerSocket implementation
285         which binds a server socket to a free port when instantiated with
286         a port <code> 0 </code>.
287         <P> Note that this method guarantees the availability of the port
288         only at the time of call. The method does not bind to this port.
289         <p> Checking for free port can fail for several reasons which may
290         indicate potential problems with the system. This method acknowledges
291         the fact and following is the general contract:
292         <li> Best effort is made to find a port which can be bound to. All
293         the exceptional conditions in the due course are considered SEVERE.
294         <li> If any exceptional condition is experienced, <code> 0 </code>
295         is returned, indicating that the method failed for some reasons and
296         the callers should take the corrective action. (The method need not
297         always throw an exception for this).
298         <li> Method is synchronized on this class.
299         @return integer depicting the free port number available at this time
300         0 otherwise.
301     */

302     public static int getFreePort() {
303         int freePort = 0;
304         boolean portFound = false;
305         ServerSocket JavaDoc serverSocket = null;
306
307         synchronized (JmxConnectorServerDriver.class) {
308             try {
309                 /*following call normally returns the free port,
310                   to which the ServerSocket is bound. */

311                 serverSocket = new ServerSocket JavaDoc(0);
312                 freePort = serverSocket.getLocalPort();
313                 portFound = true;
314             } catch(Exception JavaDoc e) {
315                 //squelch the exception
316
} finally {
317                 if (!portFound) freePort = 0;
318                 try {
319                     if (serverSocket != null) {
320                         serverSocket.close();
321                         if (! serverSocket.isClosed())
322                             throw new Exception JavaDoc("local exception ...");
323                     }
324                 } catch(Exception JavaDoc e) {
325                     //squelch the exception
326
freePort = 0;
327                 }
328             }
329             return freePort;
330         }
331     }
332     
333     /* Private Methods - End */
334 }
335
Popular Tags