KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > admin > jmx > remote > UrlConnector


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  * $Header: /cvs/glassfish/jmx-remote/rjmx-impl/src/java/com/sun/enterprise/admin/jmx/remote/UrlConnector.java,v 1.4 2005/12/25 04:26:30 tcfujii Exp $
26  * $Revision: 1.4 $
27  * $Date: 2005/12/25 04:26:30 $
28  */

29 package com.sun.enterprise.admin.jmx.remote;
30
31 import java.util.Collections JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.Iterator JavaDoc;
34 import java.net.URL JavaDoc;
35 import java.net.MalformedURLException JavaDoc;
36 import java.io.IOException JavaDoc;
37 import javax.security.auth.Subject JavaDoc;
38 import java.util.logging.Logger JavaDoc;
39
40 import javax.management.NotificationBroadcasterSupport JavaDoc;
41 import javax.management.NotificationListener JavaDoc;
42 import javax.management.NotificationFilter JavaDoc;
43 import javax.management.MBeanServerConnection JavaDoc;
44 import javax.management.ListenerNotFoundException JavaDoc;
45
46 import javax.management.remote.JMXServiceURL JavaDoc;
47 import javax.management.remote.JMXConnector JavaDoc;
48
49 import com.sun.enterprise.admin.jmx.remote.DefaultConfiguration;
50 import com.sun.enterprise.admin.jmx.remote.internal.RemoteMBeanServerConnection;
51 import com.sun.enterprise.admin.jmx.remote.notification.ClientNotificationManager;
52
53
54 /** Abstract class that implements the JMXConnector connected to a URL.
55  * It maintains a state and the state transitions are defined. It is important to know that
56  * it handles a specific protocol which is based on <a HREF="http://java.sun.com/j2se/1.4.2/docs/guide/serialization/index.html">
57  * Java Serialization </a>. Both clients and servers are exchanging following:
58  * <ul>
59  * <li> Instances of MBeanServerRequestMessage {@link javax.management.remote.message.MBeanServerRequestMessage}.
60  * This object encapsulates all the objects that clients send. </li>
61  * <li> Instance of MBeanServerResponseMessage {@link javax.management.remote.message.MBeanServerRequestMessage}.
62  * This object returns the response from MBeanServer invocation. </li>
63  * </ul>
64  * serialVersionUIDs are defined in both these classes.
65  * Both client and server sides have to agree on the same versions of classes whose objects are transmitted.
66  * Note that a concrete implementation of this class has to provide the actual wire transport, e.g. Http.
67  * @author Kedar Mhaswade
68  * @since S1AS8.0
69  * @version 1.0
70  */

71
72 public abstract class UrlConnector implements JMXConnector JavaDoc {
73     
74     private static final Logger JavaDoc logger = Logger.getLogger(
75         DefaultConfiguration.JMXCONNECTOR_LOGGER);/*,
76         DefaultConfiguration.LOGGER_RESOURCE_BUNDLE_NAME );*/

77     
78     protected final JMXServiceURL JavaDoc serviceUrl;
79     protected final Map JavaDoc environment;
80     protected final URL JavaDoc connectionUrl;
81     
82     private MBeanServerConnection JavaDoc mbsc;
83     private int state;
84     private final Object JavaDoc stateLock = new Object JavaDoc();
85     private final NotificationBroadcasterSupport JavaDoc connectionNotifier;
86     
87     private static final int CREATED = 1;
88     private static final int CONNECTED = 2;
89     private static final int CLOSED = 3;
90     
91     
92     private static final String JavaDoc PROTOCOL_PREFIX = "s1as";
93     
94     /** The only constructor that initialzes the connector for a client to use.
95      * @param serviceUrl specifies the JMXServiceURL which the server exposes.
96      * @param environment specifies the Map containing name-value pairs.
97      * The connector should be in the CREATED state after constructor returns. It has
98      * to be in CONNECTED state before calling any MBeanServerConnection method on
99      * it.
100      */

101     protected UrlConnector(JMXServiceURL JavaDoc serviceUrl, Map JavaDoc environment) {
102         //debuggerHook();
103
logMap(environment);
104         this.serviceUrl = serviceUrl;
105         this.environment = environment;
106         validateJmxServiceUrl();
107         validateEnvironment();
108         this.connectionUrl = serviceUrl2Url(serviceUrl);
109         changeState(CREATED);
110         connectionNotifier = new NotificationBroadcasterSupport JavaDoc();
111         logger.fine("Connector created to the url: " + this.connectionUrl);
112     }
113     
114     private void logMap(Map JavaDoc env) {
115         final Iterator JavaDoc iter = env.keySet().iterator();
116         while (iter.hasNext()) {
117             final String JavaDoc key = (String JavaDoc) iter.next();
118             final String JavaDoc str = (env.get(key) == null)?null:env.get(key).toString();
119             logger.fine(str);
120         }
121     }
122     
123     public void addConnectionNotificationListener(NotificationListener JavaDoc listener,
124     NotificationFilter JavaDoc filter, Object JavaDoc handback) {
125         connectionNotifier.addNotificationListener(listener, filter, handback);
126     }
127     
128     /** Closes the connector and underlying connection to the server, if any.
129      * @throws IOException if there is an error in closing the connection
130      */

131     public void close() throws IOException JavaDoc {
132         final String JavaDoc message = "UrlConnector.close: Requires that connector is CONNECTED";
133         try {
134             assertState(CONNECTED, message);
135             //physicalConnection.close();
136
/* should be actually closed, when I can take care of persistent connections etc.
137              as of now, it is a no-op. */

138         ClientNotificationManager notifMgr =
139                 ((RemoteMBeanServerConnection)mbsc).getNotificationManager();
140             if (notifMgr != null)
141                 notifMgr.close();
142
143         }
144         catch(Exception JavaDoc e) {
145             throw new IOException JavaDoc(e.getMessage());
146         }
147     }
148     
149     /** Connects to the remote server. Since there are no defaults, this method
150      * as of now throws an UnsupportedException.
151      * @throws UnsupportedException
152      * @throws IOException if could not be connected
153      * @see #connect(Map)
154      */

155     public void connect() throws IOException JavaDoc {
156         final String JavaDoc msg = "Environment has to be provided";
157         throw new UnsupportedOperationException JavaDoc(msg);
158     }
159     
160     /** Attempts to connect to the remote server and creates the MBeanServerConnection instance that
161      * is used by clients. Returns immediately (does nothing), if connector is already in CONNECTED state.
162      * Sun ONE implementation requires that provided Map contains documented values.
163      * @param env a Map containing supported environment.
164      * @throws IOException if the connection could not be established.
165      */

166     public void connect(Map JavaDoc env) throws IOException JavaDoc {
167         final String JavaDoc message = "UrlConnector.connect: Requires that connector is not CLOSED";
168         assertStateNot(CLOSED, message);
169         if (connected()) {
170             return;
171         }
172         try {
173             mbsc = MBeanServerConnectionFactory.getRemoteMBeanServerConnection(environment, serviceUrl);
174             changeState(CONNECTED);
175         }
176         catch (Exception JavaDoc e) {
177         e.printStackTrace();
178             throw new IOException JavaDoc(e.getMessage());
179         }
180     }
181     
182     /** Retunrs the connection-id of the connection.
183      */

184     public String JavaDoc getConnectionId() throws IOException JavaDoc {
185         return "TODO";
186         //return (physicalConnection.getConnectionId());
187
}
188     
189     public MBeanServerConnection JavaDoc getMBeanServerConnection() throws IOException JavaDoc {
190         final String JavaDoc message = "Connector should be in CONNECTED state";
191         assertState(CONNECTED, message);
192         return ( mbsc );
193     }
194     
195     public MBeanServerConnection JavaDoc getMBeanServerConnection(Subject JavaDoc delegationSubject)
196     throws IOException JavaDoc {
197         
198         return ( null );
199     }
200     
201     public void removeConnectionNotificationListener(NotificationListener JavaDoc listener)
202     throws ListenerNotFoundException JavaDoc {
203     }
204     
205     public void removeConnectionNotificationListener(NotificationListener JavaDoc l,
206     NotificationFilter JavaDoc f, Object JavaDoc handback) throws ListenerNotFoundException JavaDoc {
207     }
208     
209     protected void validateEnvironment() throws RuntimeException JavaDoc {
210         final boolean userPresent = environment.containsKey(DefaultConfiguration.ADMIN_USER_ENV_PROPERTY_NAME);
211         final boolean pwdPresent = environment.containsKey(DefaultConfiguration.ADMIN_PASSWORD_ENV_PROPERTY_NAME);
212         logger.fine("USERPRESENT: " + userPresent);
213         logger.fine("PWDPRESENT: " + pwdPresent);
214         if (! (userPresent && pwdPresent) ) {
215             throw new IllegalArgumentException JavaDoc("User and Password has to be there in the map");
216         }
217         final String JavaDoc adminUser = (String JavaDoc)
218         environment.get(DefaultConfiguration.ADMIN_USER_ENV_PROPERTY_NAME);
219         final String JavaDoc adminPassword = (String JavaDoc)
220         environment.get(DefaultConfiguration.ADMIN_PASSWORD_ENV_PROPERTY_NAME);
221         //validateString(adminUser);
222
//validateString(adminPassword);
223
}
224     
225     protected abstract void validateJmxServiceUrl() throws RuntimeException JavaDoc;
226     
227     private void validateString(String JavaDoc str) throws RuntimeException JavaDoc {
228         //This may not be required -- username/password could be empty strings.
229
if (str == null || str.length() == 0) {
230             throw new RuntimeException JavaDoc(NULL_STR_MESSAGE);
231         }
232     }
233     /** Utility method. If the passed serviceUrl is valid, it should always
234      * create a valid URL.
235      */

236     protected URL JavaDoc serviceUrl2Url(JMXServiceURL JavaDoc serviceUrl) throws RuntimeException JavaDoc {
237         try {
238             final String JavaDoc transportProtocol = getTransport(serviceUrl.getProtocol());
239             final String JavaDoc host = serviceUrl.getHost();
240             final int port = serviceUrl.getPort();
241             
242 /* BEGIN -- S1WS_MOD */
243             String JavaDoc remainder = serviceUrl.getURLPath();
244             if (remainder == null || remainder.trim().length() == 0)
245                 remainder = DefaultConfiguration.DEFAULT_SERVLET_CONTEXT_ROOT;
246 /* END -- S1WS_MOD */
247             return ( new URL JavaDoc(transportProtocol, host, port, remainder) );
248         }
249         catch (MalformedURLException JavaDoc mu) {
250             throw new RuntimeException JavaDoc(mu.getMessage());
251         }
252     }
253     
254     private String JavaDoc getTransport(String JavaDoc proprietoryProtocolString) {
255         return proprietoryProtocolString.substring(PROTOCOL_PREFIX.length());
256     }
257     
258     private void assertState(int legalState, String JavaDoc message) throws IllegalStateException JavaDoc {
259         synchronized(stateLock) {
260             if (state != legalState) {
261                 throw new IllegalStateException JavaDoc(message);
262             }
263         }
264     }
265     private void assertStateNot(int illegalState, String JavaDoc message) throws IllegalStateException JavaDoc {
266         synchronized(stateLock) {
267             if (state == illegalState) {
268                 throw new IllegalStateException JavaDoc(message);
269             }
270         }
271     }
272     
273     private void changeState(int toState) {
274                                 /* Since states are not directly changeable by the end-user, it needs
275                                    to be asserted if there is any program error */

276         assert (toState == CREATED || toState == CONNECTED || toState == CLOSED):
277             ("This is illegal state transition, to: " + toState);
278             synchronized(stateLock) {
279                 state = toState;
280             }
281     }
282     
283     private boolean connected() {
284         synchronized(stateLock) {
285             return ( state == CONNECTED );
286         }
287     }
288     //Localization
289
private final String JavaDoc NULL_STR_MESSAGE = "String is null";
290     
291     private void debuggerHook() {
292         try {
293             // DO NOT l10n
294
System.out.println("Attached the debugger? Provide an integer to go ahead...");
295             final int r = System.in.read();
296         }
297         catch(Exception JavaDoc e) {}
298     }
299 }
300
Popular Tags