75 import javax.management.RuntimeOperationsException; |
75 import javax.management.RuntimeOperationsException; |
76 import javax.management.event.EventClientDelegate; |
76 import javax.management.event.EventClientDelegate; |
77 import javax.management.event.EventClientDelegateMBean; |
77 import javax.management.event.EventClientDelegateMBean; |
78 import javax.management.event.EventClientNotFoundException; |
78 import javax.management.event.EventClientNotFoundException; |
79 import javax.management.event.FetchingEventForwarder; |
79 import javax.management.event.FetchingEventForwarder; |
|
80 import javax.management.namespace.JMXNamespaces; |
80 import javax.management.remote.JMXServerErrorException; |
81 import javax.management.remote.JMXServerErrorException; |
81 import javax.management.remote.NotificationResult; |
82 import javax.management.remote.NotificationResult; |
82 import javax.management.remote.TargetedNotification; |
83 import javax.management.remote.TargetedNotification; |
83 import javax.security.auth.Subject; |
84 import javax.security.auth.Subject; |
84 |
85 |
1290 } |
1291 } |
1291 |
1292 |
1292 public void removeNotificationListener(ObjectName name, Integer id) |
1293 public void removeNotificationListener(ObjectName name, Integer id) |
1293 throws InstanceNotFoundException, ListenerNotFoundException, |
1294 throws InstanceNotFoundException, ListenerNotFoundException, |
1294 IOException { |
1295 IOException { |
|
1296 if (!JMXNamespaces.getContainingNamespace(name).equals("")) { |
|
1297 logger.debug("removeNotificationListener", |
|
1298 "This connector server is not configured to support " + |
|
1299 "forwarding of notification subscriptions to name spaces"); |
|
1300 throw new RuntimeOperationsException( |
|
1301 new UnsupportedOperationException( |
|
1302 "removeNotificationListener on name space MBeans. ")); |
|
1303 } |
1295 forwarder.removeNotificationListener(name,id); |
1304 forwarder.removeNotificationListener(name,id); |
1296 } |
1305 } |
1297 |
1306 |
1298 public void removeNotificationListener(ObjectName name, Integer[] ids) |
1307 public void removeNotificationListener(ObjectName name, Integer[] ids) |
1299 throws Exception { |
1308 throws Exception { |
|
1309 if (!JMXNamespaces.getContainingNamespace(name).equals("")) { |
|
1310 logger.debug("removeNotificationListener", |
|
1311 "This connector server is not configured to support " + |
|
1312 "forwarding of notification subscriptions to name spaces"); |
|
1313 throw new RuntimeOperationsException( |
|
1314 new UnsupportedOperationException( |
|
1315 "removeNotificationListener on name space MBeans. ")); |
|
1316 } |
1300 forwarder.removeNotificationListener(name,ids); |
1317 forwarder.removeNotificationListener(name,ids); |
1301 } |
1318 } |
1302 |
1319 |
1303 public NotificationResult fetchNotifications(long csn, long timeout, int maxcount) { |
1320 public NotificationResult fetchNotifications(long csn, long timeout, int maxcount) { |
1304 return forwarder.fetchNotifs(csn,timeout,maxcount); |
1321 return forwarder.fetchNotifs(csn,timeout,maxcount); |
1305 } |
1322 } |
1306 |
1323 |
1307 public Integer addNotificationListener(ObjectName name, |
1324 public Integer addNotificationListener(ObjectName name, |
1308 NotificationFilter filter) |
1325 NotificationFilter filter) |
1309 throws InstanceNotFoundException, IOException { |
1326 throws InstanceNotFoundException, IOException { |
|
1327 if (!JMXNamespaces.getContainingNamespace(name).equals("")) { |
|
1328 logger.debug("addNotificationListener", |
|
1329 "This connector server is not configured to support " + |
|
1330 "forwarding of notification subscriptions to name spaces"); |
|
1331 throw new RuntimeOperationsException( |
|
1332 new UnsupportedOperationException( |
|
1333 "addNotificationListener on name space MBeans. ")); |
|
1334 } |
1310 return forwarder.addNotificationListener(name,filter); |
1335 return forwarder.addNotificationListener(name,filter); |
1311 } |
1336 } |
1312 |
1337 |
1313 public void terminate() { |
1338 public void terminate() { |
1314 forwarder.terminate(); |
1339 forwarder.terminate(); |
1324 private final EventClientDelegateMBean delegate; |
1349 private final EventClientDelegateMBean delegate; |
1325 private final NotificationAccessController notifAC; |
1350 private final NotificationAccessController notifAC; |
1326 private final boolean checkNotificationEmission; |
1351 private final boolean checkNotificationEmission; |
1327 private final String clientId; |
1352 private final String clientId; |
1328 private final String connectionId; |
1353 private final String connectionId; |
|
1354 private volatile String mbeanServerName; |
1329 |
1355 |
1330 EventSubscriptionManager( |
1356 EventSubscriptionManager( |
1331 MBeanServer mbeanServer, |
1357 MBeanServer mbeanServer, |
1332 EventClientDelegateMBean delegate, |
1358 EventClientDelegateMBean delegate, |
1333 Map<String, ?> env, |
1359 Map<String, ?> env, |
1341 env, "jmx.remote.x.check.notification.emission", false); |
1367 env, "jmx.remote.x.check.notification.emission", false); |
1342 this.clientId = clientId; |
1368 this.clientId = clientId; |
1343 this.connectionId = connectionId; |
1369 this.connectionId = connectionId; |
1344 } |
1370 } |
1345 |
1371 |
|
1372 private String mbeanServerName() { |
|
1373 if (mbeanServerName != null) return mbeanServerName; |
|
1374 else return (mbeanServerName = getMBeanServerName(mbeanServer)); |
|
1375 } |
|
1376 |
1346 @SuppressWarnings("serial") // no serialVersionUID |
1377 @SuppressWarnings("serial") // no serialVersionUID |
1347 private class AccessControlFilter implements NotificationFilter { |
1378 private class AccessControlFilter implements NotificationFilter { |
1348 private final NotificationFilter wrapped; |
1379 private final NotificationFilter wrapped; |
1349 private final ObjectName name; |
1380 private final ObjectName name; |
1350 |
1381 |
1355 |
1386 |
1356 public boolean isNotificationEnabled(Notification notification) { |
1387 public boolean isNotificationEnabled(Notification notification) { |
1357 try { |
1388 try { |
1358 if (checkNotificationEmission) { |
1389 if (checkNotificationEmission) { |
1359 ServerNotifForwarder.checkMBeanPermission( |
1390 ServerNotifForwarder.checkMBeanPermission( |
1360 mbeanServer, name, "addNotificationListener"); |
1391 mbeanServerName(), mbeanServer, name, |
|
1392 "addNotificationListener"); |
1361 } |
1393 } |
1362 notifAC.fetchNotification( |
1394 notifAC.fetchNotification( |
1363 connectionId, name, notification, getSubject()); |
1395 connectionId, name, notification, getSubject()); |
1364 return (wrapped == null) ? true : |
1396 return (wrapped == null) ? true : |
1365 wrapped.isNotificationEnabled(notification); |
1397 wrapped.isNotificationEnabled(notification); |
1390 throws InstanceNotFoundException, ListenerNotFoundException, |
1422 throws InstanceNotFoundException, ListenerNotFoundException, |
1391 IOException { |
1423 IOException { |
1392 if (notifAC != null) |
1424 if (notifAC != null) |
1393 notifAC.removeNotificationListener(connectionId, name, getSubject()); |
1425 notifAC.removeNotificationListener(connectionId, name, getSubject()); |
1394 try { |
1426 try { |
1395 delegate.removeListenerOrSubscriber(clientId,id); |
1427 delegate.removeListenerOrSubscriber(clientId, id); |
1396 } catch (EventClientNotFoundException x) { |
1428 } catch (EventClientNotFoundException x) { |
1397 throw new IOException("Unknown clientId: "+clientId,x); |
1429 throw new IOException("Unknown clientId: "+clientId,x); |
1398 } |
1430 } |
1399 } |
1431 } |
1400 |
1432 |
1403 IOException { |
1435 IOException { |
1404 if (notifAC != null) |
1436 if (notifAC != null) |
1405 notifAC.removeNotificationListener(connectionId, name, getSubject()); |
1437 notifAC.removeNotificationListener(connectionId, name, getSubject()); |
1406 try { |
1438 try { |
1407 for (Integer id : ids) |
1439 for (Integer id : ids) |
1408 delegate.removeListenerOrSubscriber(clientId,id); |
1440 delegate.removeListenerOrSubscriber(clientId, id); |
1409 } catch (EventClientNotFoundException x) { |
1441 } catch (EventClientNotFoundException x) { |
1410 throw new IOException("Unknown clientId: "+clientId,x); |
1442 throw new IOException("Unknown clientId: "+clientId,x); |
1411 } |
1443 } |
1412 } |
1444 } |
1413 |
1445 |
1865 e = ((PrivilegedActionException)e).getException(); |
1897 e = ((PrivilegedActionException)e).getException(); |
1866 } |
1898 } |
1867 return e; |
1899 return e; |
1868 } |
1900 } |
1869 |
1901 |
|
1902 private static String getMBeanServerName(final MBeanServer server) { |
|
1903 final PrivilegedAction<String> action = new PrivilegedAction<String>() { |
|
1904 public String run() { |
|
1905 return Util.getMBeanServerSecurityName(server); |
|
1906 } |
|
1907 }; |
|
1908 return AccessController.doPrivileged(action); |
|
1909 } |
|
1910 |
1870 private static final Object[] NO_OBJECTS = new Object[0]; |
1911 private static final Object[] NO_OBJECTS = new Object[0]; |
1871 private static final String[] NO_STRINGS = new String[0]; |
1912 private static final String[] NO_STRINGS = new String[0]; |
1872 |
1913 |
1873 /* |
1914 /* |
1874 * The JMX spec doesn't explicitly say that a null Object[] or |
1915 * The JMX spec doesn't explicitly say that a null Object[] or |