1 23 24 package com.sun.enterprise.admin.jmx.remote.server.notification; 25 26 import java.io.IOException ; 27 import java.io.OutputStream ; 28 29 import java.util.logging.Logger ; 30 import java.util.ArrayList ; 31 import java.util.HashMap ; 32 import java.util.Iterator ; 33 34 import javax.servlet.*; 35 import javax.servlet.http.*; 36 37 import javax.management.*; 38 39 import com.sun.enterprise.admin.jmx.remote.DefaultConfiguration; 40 import com.sun.enterprise.admin.jmx.remote.notification.NotificationWrapper; 41 import com.sun.enterprise.admin.jmx.remote.notification.ListenerInfo; 42 43 44 50 public class ServerNotificationManager implements Runnable { 51 private HashMap connections = null; 52 private HashMap listenerMap = null; 53 private boolean exiting = false; 54 private Thread keepAliveThr = null; 55 private MBeanServerConnection mbsc = null; 56 private int bufsiz = DefaultConfiguration.NOTIF_MAX_BUFSIZ; 57 58 private static final Logger logger = Logger.getLogger( 59 DefaultConfiguration.JMXCONNECTOR_LOGGER); 61 62 public ServerNotificationManager(MBeanServerConnection mbsc) { 63 this.mbsc = mbsc; 64 connections = new HashMap (); 65 listenerMap = new HashMap (); 66 keepAliveThr = new Thread (this); 67 keepAliveThr.start(); 68 } 69 70 75 public void setBufSiz(ServletConfig cfg) { 76 String bsiz = cfg.getInitParameter(DefaultConfiguration.NOTIF_BUFSIZ_PROPERTY_NAME); 77 if (bsiz == null || bsiz.trim().length() == 0) 78 bsiz = System.getProperty("com.sun.web.jmx.connector.notification.bufsiz"); 79 try { 80 bufsiz = Integer.parseInt(bsiz); 81 } catch (NumberFormatException nume) { 82 bufsiz = DefaultConfiguration.NOTIF_MAX_BUFSIZ; 83 } 84 if (bufsiz <= DefaultConfiguration.NOTIF_MIN_BUFSIZ) 85 bufsiz = DefaultConfiguration.NOTIF_MAX_BUFSIZ; 86 } 87 88 private void closeConnection(String id, boolean unregisterNotifications) { 89 NotificationConnection conn = 90 (NotificationConnection) connections.get(id); 91 if (conn != null) { 92 if (unregisterNotifications) { 93 unregisterNotifications(id); 94 } 95 connections.remove(id); 96 conn.close(); 97 synchronized (conn) { 98 conn.notify(); 99 } 100 } 101 } 102 103 private void unregisterNotifications(String id) { 104 synchronized (listenerMap) { 105 Iterator itr = listenerMap.keySet().iterator(); 106 while (itr.hasNext()) { 107 ObjectName mbean = (ObjectName) itr.next(); 108 ArrayList list = (ArrayList ) listenerMap.get(mbean); 109 for (int i=0, len=list.size(); i < len; i++) { 110 ListenerInfo info = (ListenerInfo) list.get(i); 111 if (info.proxy != null && 112 ((NotificationListenerProxy)info.proxy).getId() == id) { 113 list.remove(i); 114 try { 115 mbsc.removeNotificationListener( 116 mbean, ((NotificationListener)info.proxy)); 117 } catch (Exception ex) { 118 } 120 } 121 } 122 listenerMap.put(mbean, list); 123 } 124 } 125 } 126 127 136 public void getNotifications(HttpServletRequest req, HttpServletResponse res) { 137 String id = req.getParameter(DefaultConfiguration.NOTIF_ID_PARAM); 138 String cmd = req.getParameter(DefaultConfiguration.NOTIF_CMD_PARAM); 139 res.setStatus(res.SC_OK); 140 res.setHeader("Content-Type", "application/octet-stream"); 141 res.setHeader("Connection", "Keep-Alive"); 142 if (cmd != null && cmd.trim().equals(DefaultConfiguration.NOTIF_CMD_CLOSE)) { 143 synchronized (connections) { 144 closeConnection(id, true); 145 } 146 return; 147 } 148 NotificationConnection connection = null; 149 try { 150 OutputStream out = res.getOutputStream(); 151 synchronized (connections) { 152 connection = (NotificationConnection) connections.get(id); 153 if (connection == null) { 154 connection = new NotificationConnection(out, bufsiz); 155 connections.put(id, connection); 156 } else { 157 connection.reinit(out); 158 } 159 } 160 out.flush(); 161 } catch (IOException ioex) { 162 try { 164 res.sendError(res.SC_SERVICE_UNAVAILABLE, "Unable to send notifications, since OutputStream could not be opened"); 165 } catch (IOException ioe) { 166 } 168 return; 169 } 170 synchronized (connection) { 171 while (!connection.hasIOExceptionOccurred()) { 172 try { 173 connection.wait(); 174 break; } catch (InterruptedException intre) { 176 } 178 } 179 } 180 } 181 182 185 public void close() { 186 exiting = true; 187 while (true) { 188 try { 189 keepAliveThr.join(); 190 break; 191 } catch (InterruptedException intr) { 192 } 193 } 194 NotificationConnection conn = null; 195 synchronized (connections) { 196 HashMap conns = (HashMap ) connections.clone(); 197 Iterator itr = conns.keySet().iterator(); 198 while (itr.hasNext()) { 199 String id = (String ) itr.next(); 200 closeConnection(id, false); 201 } 202 } 203 } 204 205 public boolean isExiting() { 206 return exiting; 207 } 208 209 212 public void run() { 213 while (!isExiting()) { 214 try { 215 Thread.sleep(DefaultConfiguration.NOTIF_WAIT_INTERVAL); 216 } catch (InterruptedException intrEx) { 217 } 219 if (isExiting()) 220 break; 221 Iterator itr = getConnectionsIterator(); 222 NotificationConnection conn = null; 223 synchronized (connections) { 224 while (itr.hasNext() && !isExiting()) { 225 String id = (String ) itr.next(); 226 conn = (NotificationConnection) connections.get(id); 227 conn.fireWaitNotif(); 228 } 229 } 230 } 231 } 232 233 private Iterator getConnectionsIterator() { 234 Iterator itr = null; 235 synchronized (connections) { 236 itr = connections.keySet().iterator(); 237 } 238 return itr; 239 } 240 241 245 public void fireNotification(NotificationListenerProxy proxy) { 246 String id = proxy.getId(); 247 if (id == null || id.trim().length() == 0) 248 return; NotificationConnection conn = null; 250 synchronized (connections) { 251 conn = (NotificationConnection) connections.get(id); 252 } 253 if (conn == null) 254 return; 256 conn.fireNotification(proxy.getNotificationWrapper()); 257 } 258 259 private synchronized void addListenerInfo(ObjectName mbean, 260 ListenerInfo info) { 261 ArrayList list = (ArrayList ) listenerMap.get(mbean); 262 if (list == null) 263 list = new ArrayList (); 264 list.add(info); 265 listenerMap.put(mbean, list); 266 } 267 268 276 public String addObjNameNotificationListener(ObjectName mbean, 277 NotificationFilter filter, 278 Object handback, 279 String id) { 280 ListenerInfo info = new ListenerInfo(); 281 info.filter = filter; 282 info.handback = handback; 283 info.id = id; 284 addListenerInfo(mbean, info); 285 return info.id; 286 } 287 288 296 public String addNotificationListener(ObjectName mbean, 297 String id, 298 Object proxy) { 299 ListenerInfo info = new ListenerInfo(); 300 info.id = id; 301 info.proxy = proxy; 302 addListenerInfo(mbean, info); 303 304 return info.id; 305 } 306 307 private synchronized Object removeListenerInfo( 308 ObjectName mbean, String id, boolean getProxy) { 309 ArrayList list = (ArrayList ) listenerMap.get(mbean); 310 Iterator itr = null; 311 if (list == null) 312 return null; 313 itr = list.iterator(); 314 while (itr.hasNext()) { 315 ListenerInfo info = (ListenerInfo) itr.next(); 316 if (info.id.equals(id)) { 317 list.remove(list.indexOf(info)); 318 Object retObj = null; 319 if (getProxy) 320 retObj = info.proxy; 321 else 322 retObj = info; 323 return retObj; 324 } 325 } 326 327 return null; 328 } 329 330 334 public ListenerInfo removeObjNameNotificationListener(ObjectName mbean, 335 String id) { 336 return (ListenerInfo) removeListenerInfo(mbean, id, false); 337 } 338 339 343 public Object removeNotificationListener( ObjectName mbean, 344 String id) { 345 return removeListenerInfo(mbean, id, true); 346 } 347 } 348 349 | Popular Tags |