/** * Helios, OpenSource Monitoring * Brought to you by the Helios Development Group * * Copyright 2007, Helios Development Group and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. * */ package org.helios.apmrouter.jmx.mbeanserver.proxy; import org.helios.apmrouter.jmx.JMXHelper; import javax.management.*; import javax.management.remote.JMXConnectionNotification; import javax.management.remote.JMXConnector; import java.io.IOException; import java.util.Set; /** * <p>Title: MBeanServerConnectionProxy</p> * <p>Description: A {@link MBeanServerConnection} implementation that serves as a proxy within the APMRouter server</p> * <p>Company: Helios Development Group LLC</p> * @author Whitehead (nwhitehead AT heliosdev DOT org) * <p><code>org.helios.apmrouter.jmx.mbeanserver.proxy.MBeanServerConnectionProxy</code></p> */ public class MBeanServerConnectionProxy extends NotificationBroadcasterSupport implements MBeanServerConnectionProxyMBean { /** The delegate {@link MBeanServerConnection} */ protected final MBeanServerConnection mbeanServerConnection; /** The {@link JMXConnector} to attach to the target MBeanServer */ protected final JMXConnector jmxConnector; /** The agent host name */ protected final String host; /** The agent name */ protected final String agent; /** The underlying protocol name used to communicate with the agent */ protected final String protocol; /** The default domain of the target MBeanServer */ protected final String domain; /** The JMX object name for this bean */ protected final ObjectName objectName; /** * Creates a new MBeanServerConnectionProxy * @param jmxConnector The {@link JMXConnector} to attach to the target MBeanServer * @param host The agent host name * @param agent The agent name * @param protocol The underlying protocol name used to communicate with the agent * @param domain The default domain of the target MBeanServer * @throws IOException Thrown if the {@link MBeanServerConnection} cannot be established */ public MBeanServerConnectionProxy(JMXConnector jmxConnector, String host, String agent, String protocol, String domain) throws IOException { this.host = host; this.agent = agent; this.protocol = protocol; this.jmxConnector = jmxConnector; this.domain = domain; objectName = JMXHelper.objectName(new StringBuilder("org.helios.apmrouter.jmxproxy:protocol=") .append(protocol) .append(",host=").append(host) .append(",agent=").append(agent) .append(",domain=").append(domain) .toString() ); try { if(JMXHelper.getHeliosMBeanServer().isRegistered(objectName)) { JMXHelper.getHeliosMBeanServer().unregisterMBean(objectName); } JMXHelper.getHeliosMBeanServer().registerMBean(this, objectName); jmxConnector.connect(); mbeanServerConnection = jmxConnector.getMBeanServerConnection(); this.jmxConnector.addConnectionNotificationListener(new NotificationListener(){ @Override public void handleNotification(Notification notification, Object handback) { try { JMXHelper.getHeliosMBeanServer().unregisterMBean(objectName); } catch (Exception ex) {/* No Op */} } }, new NotificationFilter(){ /** */ private static final long serialVersionUID = -7392322124255404480L; @Override public boolean isNotificationEnabled(Notification notification) { return ((notification instanceof JMXConnectionNotification) && JMXConnectionNotification.CLOSED.equals(notification.getType())); } }, null); } catch (Exception ex) { throw new RuntimeException("Failed to register MBean for [" + objectName + "]", ex); } } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#createMBean(java.lang.String, javax.management.ObjectName) */ @Override public ObjectInstance createMBean(String className, ObjectName name) throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException, IOException { return mbeanServerConnection.createMBean(className, name); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#createMBean(java.lang.String, javax.management.ObjectName, javax.management.ObjectName) */ @Override public ObjectInstance createMBean(String className, ObjectName name, ObjectName loaderName) throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException, InstanceNotFoundException, IOException { return mbeanServerConnection.createMBean(className, name, loaderName); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#createMBean(java.lang.String, javax.management.ObjectName, java.lang.Object[], java.lang.String[]) */ @Override public ObjectInstance createMBean(String className, ObjectName name, Object[] params, String[] signature) throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException, IOException { return mbeanServerConnection.createMBean(className, name, params, signature); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#createMBean(java.lang.String, javax.management.ObjectName, javax.management.ObjectName, java.lang.Object[], java.lang.String[]) */ @Override public ObjectInstance createMBean(String className, ObjectName name, ObjectName loaderName, Object[] params, String[] signature) throws ReflectionException, InstanceAlreadyExistsException, MBeanRegistrationException, MBeanException, NotCompliantMBeanException, InstanceNotFoundException, IOException { return mbeanServerConnection.createMBean(className, name, loaderName, params, signature); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#unregisterMBean(javax.management.ObjectName) */ @Override public void unregisterMBean(ObjectName name) throws InstanceNotFoundException, MBeanRegistrationException, IOException { mbeanServerConnection.unregisterMBean(name); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#getObjectInstance(javax.management.ObjectName) */ @Override public ObjectInstance getObjectInstance(ObjectName name) throws InstanceNotFoundException, IOException { return mbeanServerConnection.getObjectInstance(name); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#queryMBeans(javax.management.ObjectName, javax.management.QueryExp) */ @Override public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) throws IOException { return mbeanServerConnection.queryMBeans(name, query); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#queryNames(javax.management.ObjectName, javax.management.QueryExp) */ @Override public Set<ObjectName> queryNames(ObjectName name, QueryExp query) throws IOException { return mbeanServerConnection.queryNames(name, query); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#isRegistered(javax.management.ObjectName) */ @Override public boolean isRegistered(ObjectName name) throws IOException { return mbeanServerConnection.isRegistered(name); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#getMBeanCount() */ @Override public Integer getMBeanCount() throws IOException { return mbeanServerConnection.getMBeanCount(); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#getAttribute(javax.management.ObjectName, java.lang.String) */ @Override public Object getAttribute(ObjectName name, String attribute) throws MBeanException, AttributeNotFoundException, InstanceNotFoundException, ReflectionException, IOException { return mbeanServerConnection.getAttribute(name, attribute); } /** * Returns this {@link MBeanServerConnection} instance * @return this {@link MBeanServerConnection} instance */ public MBeanServerConnection getInstance() { return this; } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#getAttributes(javax.management.ObjectName, java.lang.String[]) */ @Override public AttributeList getAttributes(ObjectName name, String[] attributes) throws InstanceNotFoundException, ReflectionException, IOException { return mbeanServerConnection.getAttributes(name, attributes); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#setAttribute(javax.management.ObjectName, javax.management.Attribute) */ @Override public void setAttribute(ObjectName name, Attribute attribute) throws InstanceNotFoundException, AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException, IOException { mbeanServerConnection.setAttribute(name, attribute); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#setAttributes(javax.management.ObjectName, javax.management.AttributeList) */ @Override public AttributeList setAttributes(ObjectName name, AttributeList attributes) throws InstanceNotFoundException, ReflectionException, IOException { return mbeanServerConnection.setAttributes(name, attributes); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#invoke(javax.management.ObjectName, java.lang.String, java.lang.Object[], java.lang.String[]) */ @Override public Object invoke(ObjectName name, String operationName, Object[] params, String[] signature) throws InstanceNotFoundException, MBeanException, ReflectionException, IOException { return mbeanServerConnection.invoke(name, operationName, params, signature); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#getDefaultDomain() */ @Override public String getDefaultDomain() throws IOException { return mbeanServerConnection.getDefaultDomain(); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#getDomains() */ @Override public String[] getDomains() throws IOException { return mbeanServerConnection.getDomains(); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#addNotificationListener(javax.management.ObjectName, javax.management.NotificationListener, javax.management.NotificationFilter, java.lang.Object) */ @Override public void addNotificationListener(ObjectName name, NotificationListener listener, NotificationFilter filter, Object handback) throws InstanceNotFoundException, IOException { mbeanServerConnection.addNotificationListener(name, listener, filter, handback); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#addNotificationListener(javax.management.ObjectName, javax.management.ObjectName, javax.management.NotificationFilter, java.lang.Object) */ @Override public void addNotificationListener(ObjectName name, ObjectName listener, NotificationFilter filter, Object handback) throws InstanceNotFoundException, IOException { mbeanServerConnection.addNotificationListener(name, listener, filter, handback); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#removeNotificationListener(javax.management.ObjectName, javax.management.ObjectName) */ @Override public void removeNotificationListener(ObjectName name, ObjectName listener) throws InstanceNotFoundException, ListenerNotFoundException, IOException { mbeanServerConnection.removeNotificationListener(name, listener); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#removeNotificationListener(javax.management.ObjectName, javax.management.ObjectName, javax.management.NotificationFilter, java.lang.Object) */ @Override public void removeNotificationListener(ObjectName name, ObjectName listener, NotificationFilter filter, Object handback) throws InstanceNotFoundException, ListenerNotFoundException, IOException { mbeanServerConnection.removeNotificationListener(name, listener, filter, handback); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#removeNotificationListener(javax.management.ObjectName, javax.management.NotificationListener) */ @Override public void removeNotificationListener(ObjectName name, NotificationListener listener) throws InstanceNotFoundException, ListenerNotFoundException, IOException { mbeanServerConnection.removeNotificationListener(name, listener); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#removeNotificationListener(javax.management.ObjectName, javax.management.NotificationListener, javax.management.NotificationFilter, java.lang.Object) */ @Override public void removeNotificationListener(ObjectName name, NotificationListener listener, NotificationFilter filter, Object handback) throws InstanceNotFoundException, ListenerNotFoundException, IOException { mbeanServerConnection.removeNotificationListener(name, listener, filter, handback); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#getMBeanInfo(javax.management.ObjectName) */ @Override public MBeanInfo getMBeanInfo(ObjectName name) throws InstanceNotFoundException, IntrospectionException, ReflectionException, IOException { return mbeanServerConnection.getMBeanInfo(name); } /** * {@inheritDoc} * @see javax.management.MBeanServerConnection#isInstanceOf(javax.management.ObjectName, java.lang.String) */ @Override public boolean isInstanceOf(ObjectName name, String className) throws InstanceNotFoundException, IOException { return mbeanServerConnection.isInstanceOf(name, className); } /** * {@inheritDoc} * @see javax.management.NotificationListener#handleNotification(javax.management.Notification, java.lang.Object) */ @Override public void handleNotification(Notification notification, Object handback) { sendNotification(notification); } }