Add the jmx user name / password authentication and the ability to use the local mbean server instead of a remote one

git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@666793 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Guillaume Nodet 2008-06-11 19:15:43 +00:00
parent 9d12bdd73c
commit 0dec0b6b0c
15 changed files with 203 additions and 192 deletions

View File

@ -88,6 +88,8 @@ public abstract class AbstractCommand implements Command {
* @throws Exception
*/
protected void handleOption(String token, List<String> tokens) throws Exception {
isPrintHelp = false;
isPrintVersion = false;
// If token is a help option
if (token.equals("-h") || token.equals("-?") || token.equals("--help")) {
isPrintHelp = true;

View File

@ -19,16 +19,24 @@ package org.apache.activemq.console.command;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.lang.management.ManagementFactory;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.management.MBeanServerConnection;
public abstract class AbstractJmxCommand extends AbstractCommand {
public static final String DEFAULT_JMX_URL = "service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi";
private JMXServiceURL jmxServiceUrl;
private JMXConnector jmxConnector;
private String jmxUser;
private String jmxPassword;
private boolean jmxUseLocal;
private JMXConnector jmxConnector;
private MBeanServerConnection jmxConnection;
/**
* Get the current specified JMX service url.
@ -68,13 +76,61 @@ public abstract class AbstractJmxCommand extends AbstractCommand {
setJmxServiceUrl(new JMXServiceURL(jmxServiceUrl));
}
/**
* Get the JMX user name to be used when authenticating.
* @return the JMX user name
*/
public String getJmxUser() {
return jmxUser;
}
/**
* Sets the JMS user name to use
* @param jmxUser - the jmx
*/
public void setJmxUser(String jmxUser) {
this.jmxUser = jmxUser;
}
/**
* Get the password used when authenticating
* @return the password used for JMX authentication
*/
public String getJmxPassword() {
return jmxPassword;
}
/**
* Sets the password to use when authenticating
* @param jmxPassword - the password used for JMX authentication
*/
public void setJmxPassword(String jmxPassword) {
this.jmxPassword = jmxPassword;
}
/**
* Get whether the default mbean server for this JVM should be used instead of the jmx url
* @return <code>true</code> if the mbean server from this JVM should be used, <code>false<code> if the jmx url should be used
*/
public boolean isJmxUseLocal() {
return jmxUseLocal;
}
/**
* Sets whether the the default mbean server for this JVM should be used instead of the jmx url
* @param jmxUseLocal - <code>true</code> if the mbean server from this JVM should be used, <code>false<code> if the jmx url should be used
*/
public void setJmxUseLocal(boolean jmxUseLocal) {
this.jmxUseLocal = jmxUseLocal;
}
/**
* Create a JMX connector using the current specified JMX service url. If there is an existing connection,
* it tries to reuse this connection.
* @return created JMX connector
* @throws IOException
*/
protected JMXConnector createJmxConnector() throws IOException {
private JMXConnector createJmxConnector() throws IOException {
// Reuse the previous connection
if (jmxConnector != null) {
jmxConnector.connect();
@ -82,14 +138,20 @@ public abstract class AbstractJmxCommand extends AbstractCommand {
}
// Create a new JMX connector
jmxConnector = JMXConnectorFactory.connect(useJmxServiceUrl());
if (jmxUser != null && jmxPassword != null) {
Map<String,Object> props = new HashMap<String,Object>();
props.put(JMXConnector.CREDENTIALS, new String[] { jmxUser, jmxPassword });
jmxConnector = JMXConnectorFactory.connect(useJmxServiceUrl(), props);
} else {
jmxConnector = JMXConnectorFactory.connect(useJmxServiceUrl());
}
return jmxConnector;
}
/**
* Close the current JMX connector
*/
protected void closeJmxConnector() {
protected void closeJmxConnection() {
try {
if (jmxConnector != null) {
jmxConnector.close();
@ -99,6 +161,17 @@ public abstract class AbstractJmxCommand extends AbstractCommand {
}
}
protected MBeanServerConnection createJmxConnection() throws IOException {
if (jmxConnection == null) {
if (isJmxUseLocal()) {
jmxConnection = ManagementFactory.getPlatformMBeanServer();
} else {
jmxConnection = createJmxConnector().getMBeanServerConnection();
}
}
return jmxConnection;
}
/**
* Handle the --jmxurl option.
* @param token - option token to handle
@ -126,9 +199,31 @@ public abstract class AbstractJmxCommand extends AbstractCommand {
context.printException(e);
tokens.clear();
}
} else if (token.equals("--jmxuser")) {
// If no jmx user specified, or next token is a new option
if (tokens.isEmpty() || ((String)tokens.get(0)).startsWith("-")) {
context.printException(new IllegalArgumentException("JMX user not specified."));
}
this.setJmxUser((String) tokens.remove(0));
} else if (token.equals("--jmxpassword")) {
// If no jmx password specified, or next token is a new option
if (tokens.isEmpty() || ((String)tokens.get(0)).startsWith("-")) {
context.printException(new IllegalArgumentException("JMX password not specified."));
}
this.setJmxPassword((String) tokens.remove(0));
} else if (token.equals("--jmxlocal")) {
this.setJmxUseLocal(true);
} else {
// Let the super class handle the option
super.handleOption(token, tokens);
}
}
public void execute(List<String> tokens) throws Exception {
try {
super.execute(tokens);
} finally {
closeJmxConnection();
}
}
}

View File

@ -47,7 +47,10 @@ public class BrowseCommand extends AbstractJmxCommand {
" message header, or the message body.",
" --view <attr1>,<attr2>,... Select the specific attribute of the message to view.",
" --jmxurl <url> Set the JMX URL to connect to.",
" --version Display the version information.",
" --jmxuser <user> Set the JMX user used for authenticating.",
" --jmxpassword <password> Set the JMX password used for authenticating.",
" --jmxlocal Use the local JMX server instead of a remote one.",
" --version Display the version information.",
" -h,-?,--help Display the browse broker help information.",
"",
"Examples:",
@ -89,11 +92,11 @@ public class BrowseCommand extends AbstractJmxCommand {
// Iterate through the queue names
for (Iterator<String> i = tokens.iterator(); i.hasNext();) {
List queueList = JmxMBeansUtil.queryMBeans(useJmxServiceUrl(), "Type=Queue,Destination=" + i.next() + ",*");
List queueList = JmxMBeansUtil.queryMBeans(createJmxConnection(), "Type=Queue,Destination=" + i.next() + ",*");
// Iterate through the queue result
for (Iterator j = queueList.iterator(); j.hasNext();) {
List messages = JmxMBeansUtil.createMessageQueryFilter(useJmxServiceUrl(), ((ObjectInstance)j.next()).getObjectName()).query(queryAddObjects);
List messages = JmxMBeansUtil.createMessageQueryFilter(createJmxConnection(), ((ObjectInstance)j.next()).getObjectName()).query(queryAddObjects);
context.printMessage(JmxMBeansUtil.filterMessagesView(messages, groupViews, queryViews));
}
}

View File

@ -29,6 +29,9 @@ public class BstatCommand extends QueryCommand {
"",
"Bstat Options:",
" --jmxurl <url> Set the JMX URL to connect to.",
" --jmxuser <user> Set the JMX user used for authenticating.",
" --jmxpassword <password> Set the JMX password used for authenticating.",
" --jmxlocal Use the local JMX server instead of a remote one.",
" --version Display the version information.",
" -h,-?,--help Display the query broker help information.",
"",

View File

@ -29,9 +29,12 @@ public class ListCommand extends AbstractJmxCommand {
"Description: Lists all available broker in the specified JMX context.",
"",
"List Options:",
" --jmxurl <url> Set the JMX URL to connect to.",
" --version Display the version information.",
" -h,-?,--help Display the stop broker help information.",
" --jmxurl <url> Set the JMX URL to connect to.",
" --jmxuser <user> Set the JMX user used for authenticating.",
" --jmxpassword <password> Set the JMX password used for authenticating.",
" --jmxlocal Use the local JMX server instead of a remote one.",
" --version Display the version information.",
" -h,-?,--help Display the stop broker help information.",
""
};
@ -44,7 +47,7 @@ public class ListCommand extends AbstractJmxCommand {
try {
Set<String> propsView = new HashSet<String>();
propsView.add("BrokerName");
context.printMBean(JmxMBeansUtil.filterMBeansView(JmxMBeansUtil.getAllBrokers(useJmxServiceUrl()), propsView));
context.printMBean(JmxMBeansUtil.filterMBeansView(JmxMBeansUtil.getAllBrokers(createJmxConnection()), propsView));
} catch (Exception e) {
context.printException(new RuntimeException("Failed to execute list task. Reason: " + e));
throw new Exception(e);

View File

@ -39,6 +39,9 @@ public class PurgeCommand extends AbstractJmxCommand {
" --msgsel <msgsel1,msglsel2> Add to the search list messages matched by the query similar to",
" the messages selector format.",
" --jmxurl <url> Set the JMX URL to connect to.",
" --jmxuser <user> Set the JMX user used for authenticating.",
" --jmxpassword <password> Set the JMX password used for authenticating.",
" --jmxlocal Use the local JMX server instead of a remote one.",
" --version Display the version information.",
" -h,-?,--help Display the browse broker help information.",
"",
@ -73,14 +76,14 @@ public class PurgeCommand extends AbstractJmxCommand {
// Iterate through the queue names
for (Iterator<String> i = tokens.iterator(); i.hasNext();) {
List queueList = JmxMBeansUtil.queryMBeans(useJmxServiceUrl(), "Type=Queue,Destination=" + i.next() + ",*");
List queueList = JmxMBeansUtil.queryMBeans(createJmxConnection(), "Type=Queue,Destination=" + i.next() + ",*");
for (Iterator j = queueList.iterator(); j.hasNext();) {
ObjectName queueName = ((ObjectInstance)j.next()).getObjectName();
if (queryAddObjects.isEmpty()) {
purgeQueue(queueName);
} else {
List messages = JmxMBeansUtil.createMessageQueryFilter(useJmxServiceUrl(), queueName).query(queryAddObjects);
List messages = JmxMBeansUtil.createMessageQueryFilter(createJmxConnection(), queueName).query(queryAddObjects);
purgeMessages(queueName, messages);
}
}
@ -98,11 +101,8 @@ public class PurgeCommand extends AbstractJmxCommand {
* @throws Exception
*/
public void purgeQueue(ObjectName queue) throws Exception {
JMXConnector conn = createJmxConnector();
MBeanServerConnection server = conn.getMBeanServerConnection();
context.printInfo("Purging all messages in queue: " + queue.getKeyProperty("Destination"));
server.invoke(queue, "purge", new Object[] {}, new String[] {});
conn.close();
createJmxConnection().invoke(queue, "purge", new Object[] {}, new String[] {});
}
/**
@ -113,20 +113,15 @@ public class PurgeCommand extends AbstractJmxCommand {
* @throws Exception
*/
public void purgeMessages(ObjectName queue, List messages) throws Exception {
JMXConnector conn = createJmxConnector();
MBeanServerConnection server = conn.getMBeanServerConnection();
Object[] param = new Object[1];
for (Iterator i = messages.iterator(); i.hasNext();) {
CompositeData msg = (CompositeData)i.next();
param[0] = "" + msg.get("JMSMessageID");
context.printInfo("Removing message: " + param[0] + " from queue: " + queue.getKeyProperty("Destination"));
server.invoke(queue, "removeMessage", param, new String[] {
createJmxConnection().invoke(queue, "removeMessage", param, new String[] {
"java.lang.String"
});
}
conn.close();
}
/**

View File

@ -55,6 +55,9 @@ public class QueryCommand extends AbstractJmxCommand {
" --view <attr1>,<attr2>,... Select the specific attribute of the object to view.",
" By default all attributes will be displayed.",
" --jmxurl <url> Set the JMX URL to connect to.",
" --jmxuser <user> Set the JMX user used for authenticating.",
" --jmxpassword <password> Set the JMX password used for authenticating.",
" --jmxlocal Use the local JMX server instead of a remote one.",
" --version Display the version information.",
" -h,-?,--help Display the query broker help information.",
"", "Examples:",
@ -103,11 +106,11 @@ public class QueryCommand extends AbstractJmxCommand {
protected void runTask(List<String> tokens) throws Exception {
try {
// Query for the mbeans to add
List addMBeans = JmxMBeansUtil.queryMBeans(useJmxServiceUrl(), queryAddObjects, queryViews);
List addMBeans = JmxMBeansUtil.queryMBeans(createJmxConnection(), queryAddObjects, queryViews);
// Query for the mbeans to sub
if (querySubObjects.size() > 0) {
List subMBeans = JmxMBeansUtil.queryMBeans(useJmxServiceUrl(), querySubObjects, queryViews);
List subMBeans = JmxMBeansUtil.queryMBeans(createJmxConnection(), querySubObjects, queryViews);
addMBeans.removeAll(subMBeans);
}

View File

@ -24,7 +24,6 @@ import java.util.List;
import javax.management.MBeanServerConnection;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.remote.JMXServiceURL;
import org.apache.activemq.console.util.JmxMBeansUtil;
@ -35,10 +34,13 @@ public class ShutdownCommand extends AbstractJmxCommand {
"Description: Stops a running broker.",
"",
"Stop Options:",
" --jmxurl <url> Set the JMX URL to connect to.",
" --all Stop all brokers.",
" --version Display the version information.",
" -h,-?,--help Display the stop broker help information.",
" --jmxurl <url> Set the JMX URL to connect to.",
" --jmxuser <user> Set the JMX user used for authenticating.",
" --jmxpassword <password> Set the JMX password used for authenticating.",
" --jmxlocal Use the local JMX server instead of a remote one.",
" --all Stop all brokers.",
" --version Display the version information.",
" -h,-?,--help Display the stop broker help information.",
"",
"Broker Names:",
" Name of the brokers that will be stopped.",
@ -61,11 +63,11 @@ public class ShutdownCommand extends AbstractJmxCommand {
// Stop all brokers
if (isStopAllBrokers) {
mbeans = JmxMBeansUtil.getAllBrokers(useJmxServiceUrl());
mbeans = JmxMBeansUtil.getAllBrokers(createJmxConnection());
brokerNames.clear();
} else if (brokerNames.isEmpty()) {
// Stop the default broker
mbeans = JmxMBeansUtil.getAllBrokers(useJmxServiceUrl());
mbeans = JmxMBeansUtil.getAllBrokers(createJmxConnection());
// If there is no broker to stop
if (mbeans.isEmpty()) {
@ -89,7 +91,7 @@ public class ShutdownCommand extends AbstractJmxCommand {
mbeans = new HashSet();
while (!brokerNames.isEmpty()) {
brokerName = (String)brokerNames.remove(0);
Collection matchedBrokers = JmxMBeansUtil.getBrokersByName(useJmxServiceUrl(), brokerName);
Collection matchedBrokers = JmxMBeansUtil.getBrokersByName(createJmxConnection(), brokerName);
if (matchedBrokers.isEmpty()) {
context.printInfo(brokerName + " did not match any running brokers.");
} else {
@ -99,7 +101,7 @@ public class ShutdownCommand extends AbstractJmxCommand {
}
// Stop all brokers in set
stopBrokers(useJmxServiceUrl(), mbeans);
stopBrokers(createJmxConnection(), mbeans);
} catch (Exception e) {
context.printException(new RuntimeException("Failed to execute stop task. Reason: " + e));
throw new Exception(e);
@ -109,13 +111,10 @@ public class ShutdownCommand extends AbstractJmxCommand {
/**
* Stops the list of brokers.
*
* @param jmxServiceUrl - JMX service url to connect to
* @param brokerBeans - broker mbeans to stop
* @throws Exception
* @param jmxConnection - connection to the mbean server
* @param brokerBeans - broker mbeans to stop @throws Exception
*/
protected void stopBrokers(JMXServiceURL jmxServiceUrl, Collection brokerBeans) throws Exception {
MBeanServerConnection server = createJmxConnector().getMBeanServerConnection();
protected void stopBrokers(MBeanServerConnection jmxConnection, Collection brokerBeans) throws Exception {
ObjectName brokerObjName;
for (Iterator i = brokerBeans.iterator(); i.hasNext();) {
brokerObjName = ((ObjectInstance)i.next()).getObjectName();
@ -124,7 +123,7 @@ public class ShutdownCommand extends AbstractJmxCommand {
context.print("Stopping broker: " + brokerName);
try {
server.invoke(brokerObjName, "terminateJVM", new Object[] {
jmxConnection.invoke(brokerObjName, "terminateJVM", new Object[] {
Integer.valueOf(0)
}, new String[] {
"int"
@ -137,7 +136,7 @@ public class ShutdownCommand extends AbstractJmxCommand {
}
}
closeJmxConnector();
closeJmxConnection();
}
/**

View File

@ -42,4 +42,5 @@ public abstract class AbstractQueryFilter implements QueryFilter {
StringTokenizer tokens = new StringTokenizer(query, QUERY_DELIMETER);
return query(Collections.list(tokens));
}
}

View File

@ -39,20 +39,20 @@ import javax.management.remote.JMXServiceURL;
public class MBeansAttributeQueryFilter extends AbstractQueryFilter {
public static final String KEY_OBJECT_NAME_ATTRIBUTE = "Attribute:ObjectName:";
private JMXServiceURL jmxServiceUrl;
private MBeanServerConnection jmxConnection;
private Set attribView;
/**
* Create an mbean attributes query filter that is able to select specific
* mbean attributes based on the object name to get.
*
* @param jmxServiceUrl - JMX service url to connect to.
* @param jmxConnection - JMX connection to use.
* @param attribView - the attributes to extract
* @param next - the next query filter
*/
public MBeansAttributeQueryFilter(JMXServiceURL jmxServiceUrl, Set attribView, MBeansObjectNameQueryFilter next) {
public MBeansAttributeQueryFilter(MBeanServerConnection jmxConnection, Set attribView, MBeansObjectNameQueryFilter next) {
super(next);
this.jmxServiceUrl = jmxServiceUrl;
this.jmxConnection = jmxConnection;
this.attribView = attribView;
}
@ -121,13 +121,10 @@ public class MBeansAttributeQueryFilter extends AbstractQueryFilter {
* @throws InstanceNotFoundException
*/
protected AttributeList getMBeanAttributes(ObjectName objName, Set attrView) throws IOException, ReflectionException, InstanceNotFoundException, IntrospectionException {
JMXConnector jmxConnector = JMXConnectorFactory.connect(jmxServiceUrl);
MBeanServerConnection server = jmxConnector.getMBeanServerConnection();
// If no attribute view specified, get all attributes
String[] attribs;
if (attrView == null || attrView.isEmpty()) {
MBeanAttributeInfo[] infos = server.getMBeanInfo(objName).getAttributes();
MBeanAttributeInfo[] infos = jmxConnection.getMBeanInfo(objName).getAttributes();
attribs = new String[infos.length];
for (int i = 0; i < infos.length; i++) {
@ -146,9 +143,7 @@ public class MBeansAttributeQueryFilter extends AbstractQueryFilter {
}
}
AttributeList attribList = server.getAttributes(objName, attribs);
jmxConnector.close();
AttributeList attribList = jmxConnection.getAttributes(objName, attribs);
attribList.add(0, new Attribute(KEY_OBJECT_NAME_ATTRIBUTE, objName));

View File

@ -17,7 +17,6 @@
package org.apache.activemq.console.filter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@ -26,37 +25,23 @@ import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.QueryExp;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
public class MBeansObjectNameQueryFilter extends AbstractQueryFilter {
public static final String DEFAULT_JMX_DOMAIN = "org.apache.activemq";
public static final String QUERY_EXP_PREFIX = "MBeans.QueryExp.";
private JMXServiceURL jmxServiceUrl;
private MBeanServerConnection jmxConnection;
/**
* Creates an mbeans object name query filter that will query on the given
* JMX Service URL
* JMX connection
*
* @param jmxUrl - JMX service URL to connect to
* @throws MalformedURLException
* @param jmxConnection - JMX connection to use
*/
public MBeansObjectNameQueryFilter(String jmxUrl) throws MalformedURLException {
this(new JMXServiceURL(jmxUrl));
}
/**
* Creates an mbeans objecet name query filter that will query on the given
* JMX Service URL
*
* @param jmxUrl - JMX service URL to connect to
*/
public MBeansObjectNameQueryFilter(JMXServiceURL jmxUrl) {
public MBeansObjectNameQueryFilter(MBeanServerConnection jmxConnection) {
super(null);
this.jmxServiceUrl = jmxUrl;
this.jmxConnection = jmxConnection;
}
/**
@ -70,7 +55,6 @@ public class MBeansObjectNameQueryFilter extends AbstractQueryFilter {
* @throws IOException - if there is a problem querying the JMX context
*/
public List query(List queries) throws MalformedObjectNameException, IOException {
// Query all mbeans
if (queries == null || queries.isEmpty()) {
return queryMBeans(new ObjectName(DEFAULT_JMX_DOMAIN + ":*"), null);
@ -111,57 +95,15 @@ public class MBeansObjectNameQueryFilter extends AbstractQueryFilter {
* @throws IOException - if there is a problem querying the JMX context
*/
protected List queryMBeans(ObjectName objName, String queryExpStr) throws IOException {
JMXConnector jmxConn = createJmxConnector();
MBeanServerConnection server = jmxConn.getMBeanServerConnection();
QueryExp queryExp = createQueryExp(queryExpStr);
// Convert mbeans set to list to make it standard throughout the query
// filter
List mbeans = new ArrayList(server.queryMBeans(objName, queryExp));
jmxConn.close();
List mbeans = new ArrayList(jmxConnection.queryMBeans(objName, queryExp));
return mbeans;
}
/**
* Get the JMX service URL the query is connecting to.
*
* @return JMX service URL
*/
public JMXServiceURL getJmxServiceUrl() {
return jmxServiceUrl;
}
/**
* Sets the JMX service URL the query is going to connect to.
*
* @param jmxServiceUrl - new JMX service URL
*/
public void setJmxServiceUrl(JMXServiceURL jmxServiceUrl) {
this.jmxServiceUrl = jmxServiceUrl;
}
/**
* Sets the JMX service URL the query is going to connect to.
*
* @param jmxServiceUrl - new JMX service URL
*/
public void setJmxServiceUrl(String jmxServiceUrl) throws MalformedURLException {
setJmxServiceUrl(new JMXServiceURL(jmxServiceUrl));
}
/**
* Creates a JMX connector
*
* @return JMX connector
* @throws IOException
*/
protected JMXConnector createJmxConnector() throws IOException {
return JMXConnectorFactory.connect(getJmxServiceUrl());
}
/**
* Creates a query expression based on the query expression string Note:
* currently unsupported

View File

@ -22,6 +22,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Arrays;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
@ -97,7 +98,7 @@ public class MapTransformFilter extends ResultTransformFilter {
Object key = i.next();
Object val = objProps.get(key);
if (val != null) {
props.setProperty(key.toString(), val.toString());
props.setProperty(key.toString(), getDisplayString(val));
}
}
@ -120,7 +121,7 @@ public class MapTransformFilter extends ResultTransformFilter {
props.putAll(transformToMap((ObjectName)attrib.getValue()));
} else {
if (attrib.getValue() != null) {
props.setProperty(attrib.getName(), attrib.getValue().toString());
props.setProperty(attrib.getName(), getDisplayString(attrib.getValue()));
}
}
}
@ -186,7 +187,7 @@ public class MapTransformFilter extends ResultTransformFilter {
if (msg.getObject() != null) {
// Just add the class name and toString value of the object
props.setProperty(AmqMessagesUtil.JMS_MESSAGE_BODY_PREFIX + "JMSObjectClass", msg.getObject().getClass().getName());
props.setProperty(AmqMessagesUtil.JMS_MESSAGE_BODY_PREFIX + "JMSObjectString", msg.getObject().toString());
props.setProperty(AmqMessagesUtil.JMS_MESSAGE_BODY_PREFIX + "JMSObjectString", getDisplayString(msg.getObject()));
}
return props;
}
@ -209,7 +210,7 @@ public class MapTransformFilter extends ResultTransformFilter {
String key = (String)e.nextElement();
Object val = msg.getObject(key);
if (val != null) {
props.setProperty(AmqMessagesUtil.JMS_MESSAGE_BODY_PREFIX + key, val.toString());
props.setProperty(AmqMessagesUtil.JMS_MESSAGE_BODY_PREFIX + key, getDisplayString(val));
}
}
@ -229,7 +230,7 @@ public class MapTransformFilter extends ResultTransformFilter {
props.putAll(transformToMap((ActiveMQMessage)msg));
// Just set the toString of the message as the body of the stream
// message
props.setProperty(AmqMessagesUtil.JMS_MESSAGE_BODY_PREFIX + "JMSStreamMessage", msg.toString());
props.setProperty(AmqMessagesUtil.JMS_MESSAGE_BODY_PREFIX + "JMSStreamMessage", getDisplayString(msg));
return props;
}
@ -269,7 +270,7 @@ public class MapTransformFilter extends ResultTransformFilter {
while (e.hasMoreElements()) {
String name = (String)e.nextElement();
if (msg.getObjectProperty(name) != null) {
props.put(AmqMessagesUtil.JMS_MESSAGE_CUSTOM_PREFIX + name, msg.getObjectProperty(name).toString());
props.put(AmqMessagesUtil.JMS_MESSAGE_CUSTOM_PREFIX + name, getDisplayString(msg.getObjectProperty(name)));
}
}
@ -329,4 +330,11 @@ public class MapTransformFilter extends ResultTransformFilter {
return props;
}
protected String getDisplayString(Object obj) {
if (obj != null && obj.getClass().isArray()) {
obj = Arrays.asList((Object[]) obj);
}
return obj.toString();
}
}

View File

@ -31,18 +31,18 @@ import javax.management.remote.JMXServiceURL;
public class MessagesQueryFilter extends AbstractQueryFilter {
private JMXServiceURL jmxServiceUrl;
private MBeanServerConnection jmxConnection;
private ObjectName destName;
/**
* Create a JMS message query filter
*
* @param jmxServiceUrl - JMX service URL to connect to
* @param jmxConnection - JMX connection to use
* @param destName - object name query to retrieve the destination
*/
public MessagesQueryFilter(JMXServiceURL jmxServiceUrl, ObjectName destName) {
public MessagesQueryFilter(MBeanServerConnection jmxConnection, ObjectName destName) {
super(null);
this.jmxServiceUrl = jmxServiceUrl;
this.jmxConnection = jmxConnection;
this.destName = destName;
}
@ -77,48 +77,8 @@ public class MessagesQueryFilter extends AbstractQueryFilter {
* @throws Exception
*/
protected List queryMessages(String selector) throws Exception {
JMXConnector connector = createJmxConnector();
MBeanServerConnection server = connector.getMBeanServerConnection();
CompositeData[] messages = (CompositeData[])server.invoke(destName, "browse", new Object[] {}, new String[] {});
connector.close();
CompositeData[] messages = (CompositeData[]) jmxConnection.invoke(destName, "browse", new Object[] {}, new String[] {});
return Arrays.asList(messages);
}
/**
* Get the JMX service URL the query is connecting to.
*
* @return JMX service URL
*/
public JMXServiceURL getJmxServiceUrl() {
return jmxServiceUrl;
}
/**
* Sets the JMX service URL the query is going to connect to.
*
* @param jmxServiceUrl - new JMX service URL
*/
public void setJmxServiceUrl(JMXServiceURL jmxServiceUrl) {
this.jmxServiceUrl = jmxServiceUrl;
}
/**
* Sets the JMX service URL the query is going to connect to.
*
* @param jmxServiceUrl - new JMX service URL
*/
public void setJmxServiceUrl(String jmxServiceUrl) throws MalformedURLException {
setJmxServiceUrl(new JMXServiceURL(jmxServiceUrl));
}
/**
* Creates a JMX connector
*
* @return JMX connector
* @throws java.io.IOException
*/
protected JMXConnector createJmxConnector() throws IOException {
return JMXConnectorFactory.connect(getJmxServiceUrl());
}
}

View File

@ -21,6 +21,7 @@ import java.io.PrintStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Arrays;
import javax.jms.Message;
import javax.management.Attribute;

View File

@ -21,6 +21,7 @@ import java.util.List;
import java.util.Set;
import javax.management.ObjectName;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXServiceURL;
import org.apache.activemq.console.filter.GroupPropertiesViewFilter;
@ -40,50 +41,50 @@ public final class JmxMBeansUtil {
private JmxMBeansUtil() {
}
public static List getAllBrokers(JMXServiceURL jmxUrl) throws Exception {
return (new MBeansObjectNameQueryFilter(jmxUrl)).query("Type=Broker");
public static List getAllBrokers(MBeanServerConnection jmxConnection) throws Exception {
return (new MBeansObjectNameQueryFilter(jmxConnection)).query("Type=Broker");
}
public static List getBrokersByName(JMXServiceURL jmxUrl, String brokerName) throws Exception {
return (new MBeansObjectNameQueryFilter(jmxUrl)).query("Type=Broker,BrokerName=" + brokerName);
public static List getBrokersByName(MBeanServerConnection jmxConnection, String brokerName) throws Exception {
return (new MBeansObjectNameQueryFilter(jmxConnection)).query("Type=Broker,BrokerName=" + brokerName);
}
public static List getAllBrokers(JMXServiceURL jmxUrl, Set attributes) throws Exception {
return (new MBeansAttributeQueryFilter(jmxUrl, attributes, new MBeansObjectNameQueryFilter(jmxUrl))).query("Type=Broker");
public static List getAllBrokers(MBeanServerConnection jmxConnection, Set attributes) throws Exception {
return (new MBeansAttributeQueryFilter(jmxConnection, attributes, new MBeansObjectNameQueryFilter(jmxConnection))).query("Type=Broker");
}
public static List getBrokersByName(JMXServiceURL jmxUrl, String brokerName, Set attributes) throws Exception {
return (new MBeansAttributeQueryFilter(jmxUrl, attributes, new MBeansObjectNameQueryFilter(jmxUrl))).query("Type=Broker,BrokerName=" + brokerName);
public static List getBrokersByName(MBeanServerConnection jmxConnection, String brokerName, Set attributes) throws Exception {
return (new MBeansAttributeQueryFilter(jmxConnection, attributes, new MBeansObjectNameQueryFilter(jmxConnection))).query("Type=Broker,BrokerName=" + brokerName);
}
public static List queryMBeans(JMXServiceURL jmxUrl, List queryList) throws Exception {
public static List queryMBeans(MBeanServerConnection jmxConnection, List queryList) throws Exception {
// If there is no query defined get all mbeans
if (queryList == null || queryList.size() == 0) {
return createMBeansObjectNameQuery(jmxUrl).query("");
return createMBeansObjectNameQuery(jmxConnection).query("");
// Parse through all the query strings
} else {
return createMBeansObjectNameQuery(jmxUrl).query(queryList);
return createMBeansObjectNameQuery(jmxConnection).query(queryList);
}
}
public static List queryMBeans(JMXServiceURL jmxUrl, List queryList, Set attributes) throws Exception {
public static List queryMBeans(MBeanServerConnection jmxConnection, List queryList, Set attributes) throws Exception {
// If there is no query defined get all mbeans
if (queryList == null || queryList.size() == 0) {
return createMBeansAttributeQuery(jmxUrl, attributes).query("");
return createMBeansAttributeQuery(jmxConnection, attributes).query("");
// Parse through all the query strings
} else {
return createMBeansAttributeQuery(jmxUrl, attributes).query(queryList);
return createMBeansAttributeQuery(jmxConnection, attributes).query(queryList);
}
}
public static List queryMBeans(JMXServiceURL jmxUrl, String queryString) throws Exception {
return createMBeansObjectNameQuery(jmxUrl).query(queryString);
public static List queryMBeans(MBeanServerConnection jmxConnection, String queryString) throws Exception {
return createMBeansObjectNameQuery(jmxConnection).query(queryString);
}
public static List queryMBeans(JMXServiceURL jmxUrl, String queryString, Set attributes) throws Exception {
return createMBeansAttributeQuery(jmxUrl, attributes).query(queryString);
public static List queryMBeans(MBeanServerConnection jmxConnection, String queryString, Set attributes) throws Exception {
return createMBeansAttributeQuery(jmxConnection, attributes).query(queryString);
}
public static List filterMBeansView(List mbeans, Set viewFilter) throws Exception {
@ -104,23 +105,23 @@ public final class JmxMBeansUtil {
return output;
}
public static QueryFilter createMBeansObjectNameQuery(JMXServiceURL jmxUrl) {
public static QueryFilter createMBeansObjectNameQuery(MBeanServerConnection jmxConnection) {
// Let us be able to accept wildcard queries
// Use regular expressions to filter the query results
// Let us retrieve the mbeans object name specified by the query
return new WildcardToRegExTransformFilter(new MBeansRegExQueryFilter(new MBeansObjectNameQueryFilter(jmxUrl)));
return new WildcardToRegExTransformFilter(new MBeansRegExQueryFilter(new MBeansObjectNameQueryFilter(jmxConnection)));
}
public static QueryFilter createMBeansAttributeQuery(JMXServiceURL jmxUrl, Set attributes) {
public static QueryFilter createMBeansAttributeQuery(MBeanServerConnection jmxConnection, Set attributes) {
// Let use be able to accept wildcard queries
// Use regular expressions to filter the query result
// Retrieve the attributes needed
// Retrieve the mbeans object name specified by the query
return new WildcardToRegExTransformFilter(new MBeansRegExQueryFilter(new MBeansAttributeQueryFilter(jmxUrl, attributes, new MBeansObjectNameQueryFilter(jmxUrl))));
return new WildcardToRegExTransformFilter(new MBeansRegExQueryFilter(new MBeansAttributeQueryFilter(jmxConnection, attributes, new MBeansObjectNameQueryFilter(jmxConnection))));
}
public static QueryFilter createMessageQueryFilter(JMXServiceURL jmxUrl, ObjectName destName) {
return new WildcardToMsgSelectorTransformFilter(new MessagesQueryFilter(jmxUrl, destName));
public static QueryFilter createMessageQueryFilter(MBeanServerConnection jmxConnection, ObjectName destName) {
return new WildcardToMsgSelectorTransformFilter(new MessagesQueryFilter(jmxConnection, destName));
}
public static List filterMessagesView(List messages, Set groupViews, Set attributeViews) throws Exception {