/* | |
* Copyright 2005 The Apache Software Foundation | |
* | |
* 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.apache.felix.jmxintrospector; | |
import java.lang.management.ManagementFactory; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.Set; | |
import java.util.logging.Logger; | |
import javax.management.MBeanServerConnection; | |
import javax.management.NotificationBroadcaster; | |
import javax.management.ObjectName; | |
import javax.management.remote.JMXConnectorFactory; | |
import javax.management.remote.JMXServiceURL; | |
/** | |
* This class is the main entry point to the jmxintrospector library. | |
* It uses the {@link MBeanProxyFactory#newProxyInstance(String)} to create | |
* proxies for the mbeans found in the mbean servers. | |
* MBean servers can be added through the addXXServer methods. Some helper methods | |
* for browsing through the MBeans are also provided. | |
* | |
*/ | |
public class MBeanProxyManager { | |
//FIXME: mixing up Server and MBeanServerConnections is dirty and error-prone | |
/* | |
*Currently, we wrap the MBeanProxy Server with a Server in order to add identification | |
*this is quite dirty. | |
*/ | |
private List<Server> servers = new ArrayList<Server>(); | |
private List<Object> objects = new ArrayList<Object>(); | |
private Logger logger = Logger.getLogger(this.getClass().getName()); | |
/** | |
* Adds a remote MBean server that has a RMI connector at host:1099/path | |
* Same as {@link MBeanProxyManager}{@link #addRMIServer(host, path, 1099)} | |
* @param host | |
* @param path | |
* @throws Exception | |
*/ | |
public void addRMIServer(String host, String path) throws Exception { | |
addRMIServer(host, path, 1099); | |
} | |
/** | |
* Adds a remote MBean server that has a RMI connector running at | |
* {@literal service:jmx:rmi:///jndi/rmi://host:port/path} | |
* Same as {@link MBeanProxyManager#addRemoteServer(service:jmx:rmi:///jndi/rmi://host:port/path)} | |
* @param host | |
* @param path | |
* @param port | |
* @throws Exception | |
*/ | |
public void addRMIServer(String host, String path, int port) | |
throws Exception { | |
addRemoteServer("service:jmx:rmi:///jndi/rmi://" + host + ":" + port +"/" +path); | |
} | |
public void addRemoteServer(String url) throws Exception { | |
JMXServiceURL u = new JMXServiceURL(url); | |
MBeanServerConnection s = JMXConnectorFactory.connect(u) | |
.getMBeanServerConnection(); | |
add(url, s); | |
} | |
/** | |
* The same for the local server. Note that this will make an MBeanServer if it was not already available. | |
* @throws Exception | |
*/ | |
public void addLocalServer() throws Exception { | |
MBeanServerConnection s=ManagementFactory.getPlatformMBeanServer(); | |
add(s.getDefaultDomain(), s); | |
} | |
private void add(String id, MBeanServerConnection s) throws Exception { | |
Server server=new Server(s,id); | |
servers.add(server); | |
Set onames = s.queryNames(ObjectName.getInstance("*:*"), null); | |
MBeanProxyFactory introspector = new MBeanProxyFactory(server); | |
for (Object o : onames) { | |
try { | |
ObjectName name=(ObjectName) o; | |
objects.add(introspector.newProxyInstance(name | |
.toString())); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
logger.warning("ERROR: "+e); | |
continue; | |
} | |
} | |
} | |
/** | |
* it removes the specified server | |
* @param server | |
*/ | |
public void removeServer(Server server) { | |
servers.remove(server); | |
for (Object o : objects) { | |
if (((MBean)o).getMBeanServer().equals(server)) objects.remove(o); | |
} | |
} | |
/////////// | |
//Finders// | |
/////////// | |
/** | |
* Returns all the created proxies. | |
* Remember that each proxy object can implement up to 3 interfaces: | |
* <ol> | |
* <li>{@link MBean}. Always implemented</li> | |
* <li>The implicit interface (dynamically generated) of the remote MBean. This can only be called through reflection | |
* or using a dynamic language on top of Java</li> | |
* <li>{@link NotificationBroadcaster} if the underlying mbean broadcasts notifications. | |
* </li> | |
* </ol> | |
*/ | |
public List<Object> getObjects() { | |
return objects; | |
} | |
public Object findFirst(String substring){ | |
return findFirst(substring, null); | |
} | |
public Object findFirst(String substring, Server server){ | |
for (Object o :objects){ | |
MBean bean=(MBean)o; | |
if (isTheServer(bean, server)&&bean.getObjectName().contains(substring)){ | |
return o; | |
} | |
} | |
return null; | |
} | |
private boolean isTheServer(MBean bean, MBeanServerConnection server){ | |
return server==null?true:bean.getMBeanServer().equals(server); | |
} | |
public List<Object> findAll(String substring){ | |
return findAll(substring, null); | |
} | |
public List<Object> findAll(String substring, MBeanServerConnection server){ | |
List<Object> matches=new ArrayList<Object>(); | |
for (Object o :objects){ | |
MBean bean=(MBean)o; | |
if (isTheServer(bean, server)&&bean.getObjectName().contains(substring)){ | |
matches.add(o); | |
} | |
} | |
return matches; | |
} | |
public List<Object> findMatches(String regex){ | |
List<Object> matches=new ArrayList<Object>(); | |
for (Object o :objects){ | |
if (((MBean)o).getObjectName().matches(regex)){ | |
matches.add(o); | |
} | |
} | |
return matches; | |
} | |
public List<Server> getServers() { | |
return servers; | |
} | |
} |