KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > admin > jmx > remote > notification > NotificationReceiver


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 package com.sun.enterprise.admin.jmx.remote.notification;
25
26 import java.io.IOException JavaDoc;
27 import java.io.EOFException JavaDoc;
28 import java.io.InputStream JavaDoc;
29 import java.io.BufferedInputStream JavaDoc;
30 import java.io.ObjectInputStream JavaDoc;
31 import java.io.InputStreamReader JavaDoc;
32 import java.io.BufferedReader JavaDoc;
33 import java.nio.channels.ClosedChannelException JavaDoc;
34 import java.net.SocketException JavaDoc;
35 import java.net.SocketTimeoutException JavaDoc;
36 import java.rmi.ConnectException JavaDoc;
37 import java.rmi.ConnectIOException JavaDoc;
38 import java.net.URLConnection JavaDoc;
39 import java.net.HttpURLConnection JavaDoc;
40 import java.util.logging.Logger JavaDoc;
41
42 import com.sun.enterprise.admin.jmx.remote.notification.NotificationWrapper;
43 import com.sun.enterprise.admin.jmx.remote.comm.HttpConnectorAddress;
44 import com.sun.enterprise.admin.jmx.remote.DefaultConfiguration;
45
46 /**
47  * This is the notification receiver thread.
48  * This thread makes the connection to the server-side and starts to receive
49  * the notifications.
50  * During a JMXConnector.close call, this thread would send a close message to the
51  * server-side and would exit.
52  */

53 class NotificationReceiver implements Runnable JavaDoc {
54     private ClientNotificationManager mgr = null;
55
56     private String JavaDoc notifMgrUri = null;
57     private HttpConnectorAddress ad = null;
58     private URLConnection JavaDoc mConnection = null;
59     private ObjectInputStream JavaDoc objIn = null;
60     private InputStream JavaDoc in = null;
61     private boolean exit = false;
62     private boolean connected = false;
63     private boolean timedout = false;
64     private int nReconnected= 0;
65     private Thread JavaDoc receiveThr = null;
66
67     private static final Logger JavaDoc logger = Logger.getLogger(
68         DefaultConfiguration.JMXCONNECTOR_LOGGER);/*,
69         DefaultConfiguration.LOGGER_RESOURCE_BUNDLE_NAME );*/

70
71     public NotificationReceiver(HttpConnectorAddress ad, ClientNotificationManager mgr)
72             throws IOException JavaDoc {
73         this.mgr = mgr;
74         this.ad = ad;
75         this.notifMgrUri = getNotifMgrURI();
76         connect();
77         receiveThr = new Thread JavaDoc(this);
78         receiveThr.start();
79     }
80
81     private String JavaDoc getNotifMgrURI() {
82         String JavaDoc uri = ad.getPath();
83         if (uri == null || uri.trim().length() == 0)
84             uri = DefaultConfiguration.DEFAULT_SERVLET_CONTEXT_ROOT;
85         uri = uri +
86               DefaultConfiguration.NOTIF_MGR_PATHINFO +
87               "?" + DefaultConfiguration.NOTIF_ID_PARAM +
88               "=" + mgr.getId();
89         return uri;
90    }
91
92     private void connect() throws IOException JavaDoc {
93         if (connected)
94             return;
95         connect(null, false);
96     }
97
98     private void connect(String JavaDoc cmd, boolean disconnect) throws IOException JavaDoc {
99         try{
100             String JavaDoc uri = notifMgrUri;
101             if (cmd != null)
102                 uri = uri + "&" +
103                       DefaultConfiguration.NOTIF_CMD_PARAM +
104                       "=" + DefaultConfiguration.NOTIF_CMD_CLOSE;
105             System.setProperty("sun.net.client.defaultConnectTimeout",
106                                Integer.toString(DefaultConfiguration.NOTIF_CONNECT_TIMEOUT)); // XXX: For Sun JDK only
107
URLConnection JavaDoc conn = ad.openConnection(uri);
108 // conn.setConnectTimeout(2000); // XXX: For jdk 1.5
109
InputStream JavaDoc inStream = conn.getInputStream();
110             if (!disconnect) {
111                 mConnection = conn;
112                 in = inStream;
113                 connected = true;
114                 nReconnected = 0;
115             } else {
116                 disconnect(conn, inStream);
117             }
118         } catch (IOException JavaDoc ioe){
119         ioe.printStackTrace();
120             throw (ioe);
121         }
122     }
123
124     /**
125      * Reinitialized the connection, if the connection is dropped.
126      * This method is invoked from ClientNotificationManager every time the client
127      * invokes a method on MBeanServerConnection.
128      */

129     public boolean reinit() throws IOException JavaDoc {
130         if (connected)
131             return true;
132
133         timedout = false;
134         try {
135             connect();
136         } catch (IOException JavaDoc ioe) {
137             timedout = true;
138             throw ioe;
139         }
140         nReconnected = 0;
141         receiveThr = new Thread JavaDoc(this);
142         receiveThr.start();
143         return true;
144     }
145
146     /**
147      * Returns if the receiver has timedout while trying to receive
148      * notitifications from the server.
149      * Timedout -- If a socket timeout happens while trying to connect
150      * If the server is not reachable 3 times consequtively during thread loop.
151      * If not able to connect when reinit is called.
152      */

153     public boolean hasTimedout() {
154         return timedout;
155     }
156
157     /**
158      * The notification receiver thread loop.
159      * This loop, if client has not called JMXConnector.close, will
160      * try to read a notification message from the connection and notify
161      * the ClientNotificationManager to dispatch the notification.
162      */

163     public void run() {
164         while (!isExiting()) {
165             try {
166                 connect();
167                 readNotification();
168             } catch (IOException JavaDoc ioe) {
169                 if (isExiting())
170                     break;
171                 ioe.printStackTrace();
172                 if (ioe instanceof SocketTimeoutException JavaDoc) {
173                     timedout = true;
174                     break;
175                 }
176                 if (isDisconnected(ioe)) {
177                     connected = false;
178                     nReconnected++;
179                     if (nReconnected > 3) {
180                         timedout = true;
181                         break;
182                     }
183                     continue;
184                 } else if (isExiting()) {
185                     break;
186                 }
187             }
188         }
189     }
190
191     private boolean isDisconnected(IOException JavaDoc ioe) {
192         if (ioe instanceof ClosedChannelException JavaDoc ||
193             ioe instanceof SocketException JavaDoc ||
194             ioe instanceof ConnectException JavaDoc ||
195             ioe instanceof ConnectIOException JavaDoc ||
196             ioe instanceof EOFException JavaDoc)
197             return true;
198         return false;
199     }
200
201     private void disconnect() throws IOException JavaDoc {
202         disconnect(mConnection, in);
203     }
204
205     private void disconnect(URLConnection JavaDoc conn, InputStream JavaDoc in) throws IOException JavaDoc {
206         if (conn instanceof HttpURLConnection JavaDoc) {
207             ((HttpURLConnection JavaDoc)conn).disconnect();
208         } else
209             in.close();
210     }
211
212     public void exit() throws Exception JavaDoc {
213         exit = true;
214         sendCloseMessage();
215         disconnect();
216         receiveThr.join();
217     }
218
219     private void sendCloseMessage() throws IOException JavaDoc {
220         connect("close", true);
221     }
222
223     private boolean isExiting() {
224         return exit;
225     }
226
227     private void readNotification() throws IOException JavaDoc {
228         Object JavaDoc obj = null;
229         try {
230             objIn = new ObjectInputStream JavaDoc(in);
231             obj = objIn.readObject();
232         } catch (IOException JavaDoc ioe) {
233             String JavaDoc msg = ioe.getMessage();
234             if (msg != null && msg.indexOf("EOF") != -1)
235                 throw (new EOFException JavaDoc(msg));
236             throw ioe;
237         } catch (ClassNotFoundException JavaDoc notfound) {
238             // Ignore; Unknown Object ???
239
return;
240         }
241
242         NotificationWrapper wrapr = (NotificationWrapper) obj;
243         if (wrapr.getType() == NotificationWrapper.WAIT) {
244             return;
245         }
246
247         mgr.raiseEvent(wrapr);
248     }
249 }
250
Popular Tags