/* * Copyright 2008 the original author or authors. * Copyright 2005 Sun Microsystems, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.rioproject.impl.watch; import org.rioproject.servicebean.ServiceBeanContext; import org.rioproject.impl.jmx.JMXUtil; import org.rioproject.impl.jmx.MBeanServerFactory; import org.rioproject.impl.sla.SLAPolicyHandler; import org.rioproject.system.SystemWatchID; import org.rioproject.watch.WatchDataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.management.*; import java.rmi.NoSuchObjectException; import java.util.*; /** * An implementation of a {@link WatchRegistry} */ public class WatchDataSourceRegistry implements WatchRegistry { /** Collection of Watch instances that have been registered */ protected final List<Watch> watchRegistry = new ArrayList<Watch>(); /** Table of ThresholdWatch classnames and ThresholdListener objects */ protected final Map<String, Collection<ThresholdListener>> thresholdListenerTable = new Hashtable<String, Collection<ThresholdListener>>(); /** The ServiceBeanContext */ private ServiceBeanContext context; /** A Logger */ private static Logger logger = LoggerFactory.getLogger(WatchDataSourceRegistry.class); /** * @see WatchRegistry#deregister */ public void deregister(Watch... watches) { if (watches == null) throw new IllegalArgumentException("Watches cannot be null"); watchRegistry.removeAll(Arrays.asList(watches)); for (Watch watch : watches) { try { if(watch instanceof PeriodicWatch) ((PeriodicWatch)watch).stop(); watch.getWatchDataSource().close(); } catch (NoSuchObjectException e) { if (logger.isTraceEnabled()) logger.trace("Deregistering Watch", e); } catch (Throwable t) { logger.warn("Deregistering Watch", t); } /// unregister ThresholdListeners if(thresholdListenerTable.containsKey(watch.getId())) { thresholdListenerTable.remove(watch.getId()); } //unregister from jmx unregisterJMX(watch); } } private void unregisterJMX(Watch watch) { try { ObjectName objectName = getObjectName(watch); if(MBeanServerFactory.getMBeanServer().isRegistered(objectName)) MBeanServerFactory.getMBeanServer().unregisterMBean(objectName); } catch (MalformedObjectNameException e) { logger.warn(e.toString(), e); } catch (InstanceNotFoundException e) { logger.warn(e.toString(), e); } catch (MBeanRegistrationException e) { logger.warn(e.toString(), e); } } /** * @see WatchRegistry#closeAll() */ public void closeAll() { Watch[] watches = watchRegistry.toArray(new Watch[watchRegistry.size()]); for(Watch w : watches) { unregisterJMX(w); if(w instanceof PeriodicWatch) ((PeriodicWatch)w).stop(); try { WatchDataSource wd = w.getWatchDataSource(); if (wd != null) wd.close(); watchRegistry.remove(w); } catch (Exception e) { logger.warn("Closing WatchDataSource", e); } } } /** * @see WatchRegistry#register */ public void register(Watch... watches) { if(watches == null) throw new IllegalArgumentException("Watches cannot be null"); watchRegistry.addAll(Arrays.asList(watches)); for (Watch watch : watches) { associateThresholdListener(watch); //register jmx registerJMX(watch); } } private void registerJMX(Watch watch) { try { ObjectName objectName = getObjectName(watch); MBeanServer mbeanServer = MBeanServerFactory.getMBeanServer(); if(mbeanServer.isRegistered(objectName)) { mbeanServer.unregisterMBean(objectName); logger.info("Unregistered {}, update Watch [{}] registration with new watch instance", objectName, watch.getId()); } mbeanServer.registerMBean(watch, objectName); } catch (MalformedObjectNameException e) { logger.warn(e.toString(), e); } catch (MBeanRegistrationException e) { logger.warn(e.toString(), e); } catch (InstanceAlreadyExistsException e) { logger.warn(e.toString(), e); } catch (NotCompliantMBeanException e) { logger.warn(e.toString(), e); } catch (InstanceNotFoundException e) { logger.warn(e.toString(), e); } } private ObjectName getObjectName(Watch watch) throws MalformedObjectNameException { String domain = getClass().getPackage().getName(); String objectName = null; if(context != null) { String jmxName = JMXUtil.getJMXName(context, domain); objectName = jmxName+","+ "name=Watch,"+ "id="+watch.getId(); } if(objectName == null) { String id = watch.getId(); if(id.equals("")) id = "<empty-string>"; objectName = domain+":type=Watch,ID="+id; } return (ObjectName.getInstance(objectName)); } /** * @see WatchRegistry#addThresholdListener */ public void addThresholdListener(String id, ThresholdListener thresholdListener) { if(id==null) throw new IllegalArgumentException("id is null"); if(thresholdListener==null) throw new IllegalArgumentException("thresholdListener is null"); Collection<ThresholdListener> collection; if(thresholdListenerTable.containsKey(id)) { collection = thresholdListenerTable.get(id); } else { collection = new ArrayList<ThresholdListener>(); } if(!collection.contains(thresholdListener)) { if(logger.isTraceEnabled()) logger.trace("Add [{}] for watch [{}]", thresholdListener.getClass().getName(), id); collection.add(thresholdListener); thresholdListenerTable.put(id, collection); Watch watch = findWatch(id); if(logger.isTraceEnabled()) logger.trace("Found [{}] previously registered watch [{}]", (watch==null?0:1), id); if(watch!=null) { associateThresholdListener(watch); } } } /** * @see WatchRegistry#removeThresholdListener */ public void removeThresholdListener(String id, ThresholdListener thresholdListener) { if(thresholdListenerTable.containsKey(id)) { Collection<ThresholdListener> collection = thresholdListenerTable.get(id); collection.remove(thresholdListener); } } /** * This method will associate a Watch to a ThresholdListener, iff the Watch * is a ThresholdWatch and the Watch objects classname is found in the table * * @param watch The Watch to associate */ protected void associateThresholdListener(Watch watch) { if(!(watch instanceof ThresholdWatch)) return; ThresholdWatch tWatch = (ThresholdWatch)watch; if(thresholdListenerTable.containsKey(tWatch.getId())) { Collection<ThresholdListener> collection = thresholdListenerTable.get(tWatch.getId()); for (ThresholdListener tListener : collection) { if (logger.isTraceEnabled()) logger.trace("Associate Watch [{}] to [{}]", tWatch.getId(), tListener.getClass().getName()); if (tListener instanceof SLAPolicyHandler) { SLAPolicyHandler slaPolicyHandler = (SLAPolicyHandler)tListener; tWatch.setThresholdValues(slaPolicyHandler.getSLA()); } if(tListener instanceof SettableThresholdListener) { ((SettableThresholdListener)tListener).setThresholdManager(tWatch.getThresholdManager()); } } } } /** * @see WatchRegistry#findWatch(String) */ public Watch findWatch(String id) { if(id == null) throw new IllegalArgumentException("id is null"); Watch watch = null; for(Watch w : watchRegistry) { if(id.equals(w.getId())) { watch = w; break; } } return watch; } /** * @see WatchRegistry#fetch() */ public WatchDataSource[] fetch() { WatchDataSource[] wds = new WatchDataSource[watchRegistry.size()]; int i = 0; for(Watch watch : watchRegistry) { wds[i++] = watch.getWatchDataSource(); } return wds; } /** * @see WatchRegistry#fetch(String) */ public WatchDataSource fetch(String id) { WatchDataSource wds = null; Watch watch = findWatch(id); if(watch != null) { wds = watch.getWatchDataSource(); } else { boolean isSystemWatch = false; for(String s : SystemWatchID.IDs) { if(s.equals(id)) { isSystemWatch = true; break; } } if(isSystemWatch && context!=null) { Watch w = context.getComputeResourceManager().getComputeResource().getMeasurableCapability(id); if(w!=null) wds = w.getWatchDataSource(); } } return wds; } /** * @see WatchRegistry#setServiceBeanContext */ public void setServiceBeanContext(ServiceBeanContext context) { this.context = context; } }