001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.activemq.console.filter;
018    
019    import java.io.IOException;
020    import java.net.MalformedURLException;
021    import java.util.ArrayList;
022    import java.util.Iterator;
023    import java.util.List;
024    
025    import javax.management.MBeanServerConnection;
026    import javax.management.MalformedObjectNameException;
027    import javax.management.ObjectName;
028    import javax.management.QueryExp;
029    import javax.management.remote.JMXConnector;
030    import javax.management.remote.JMXConnectorFactory;
031    import javax.management.remote.JMXServiceURL;
032    
033    public class MBeansObjectNameQueryFilter extends AbstractQueryFilter {
034    
035        public static final String DEFAULT_JMX_DOMAIN = "org.apache.activemq";
036        public static final String QUERY_EXP_PREFIX = "MBeans.QueryExp.";
037    
038        private JMXServiceURL jmxServiceUrl;
039    
040        /**
041         * Creates an mbeans object name query filter that will query on the given
042         * JMX Service URL
043         * 
044         * @param jmxUrl - JMX service URL to connect to
045         * @throws MalformedURLException
046         */
047        public MBeansObjectNameQueryFilter(String jmxUrl) throws MalformedURLException {
048            this(new JMXServiceURL(jmxUrl));
049        }
050    
051        /**
052         * Creates an mbeans objecet name query filter that will query on the given
053         * JMX Service URL
054         * 
055         * @param jmxUrl - JMX service URL to connect to
056         */
057        public MBeansObjectNameQueryFilter(JMXServiceURL jmxUrl) {
058            super(null);
059            this.jmxServiceUrl = jmxUrl;
060        }
061    
062        /**
063         * Queries the JMX service using a mapping of keys and values to construct
064         * the object name
065         * 
066         * @param queries - mapping of keys and values
067         * @return collection of ObjectInstance that matches the query
068         * @throws MalformedObjectNameException - if the given string is an invalid
069         *                 object name
070         * @throws IOException - if there is a problem querying the JMX context
071         */
072        public List query(List queries) throws MalformedObjectNameException, IOException {
073    
074            // Query all mbeans
075            if (queries == null || queries.isEmpty()) {
076                return queryMBeans(new ObjectName(DEFAULT_JMX_DOMAIN + ":*"), null);
077            }
078    
079            // Constructs object name query
080            String objNameQuery = "";
081            String queryExp = "";
082            for (Iterator i = queries.iterator(); i.hasNext();) {
083                String key = (String)i.next();
084                String val = "";
085                int pos = key.indexOf("=");
086                if (pos >= 0) {
087                    val = key.substring(pos + 1);
088                    key = key.substring(0, pos);
089                }
090    
091                if (val.startsWith(QUERY_EXP_PREFIX)) {
092                    // do nothing as of the moment
093                } else if (!key.equals("") && !val.equals("")) {
094                    objNameQuery = objNameQuery + key + "=" + val + ",";
095                }
096            }
097    
098            // Append * to object name
099            objNameQuery = objNameQuery + "*";
100    
101            return queryMBeans(new ObjectName(DEFAULT_JMX_DOMAIN + ":" + objNameQuery), queryExp);
102        }
103    
104        /**
105         * Advance query that enables you to specify both the object name and the
106         * query expression to use. Note: Query expression is currently unsupported.
107         * 
108         * @param objName - object name to use for query
109         * @param queryExpStr - query expression string
110         * @return set of mbeans that matches the query
111         * @throws IOException - if there is a problem querying the JMX context
112         */
113        protected List queryMBeans(ObjectName objName, String queryExpStr) throws IOException {
114            JMXConnector jmxConn = createJmxConnector();
115            MBeanServerConnection server = jmxConn.getMBeanServerConnection();
116    
117            QueryExp queryExp = createQueryExp(queryExpStr);
118    
119            // Convert mbeans set to list to make it standard throughout the query
120            // filter
121            List mbeans = new ArrayList(server.queryMBeans(objName, queryExp));
122    
123            jmxConn.close();
124    
125            return mbeans;
126        }
127    
128        /**
129         * Get the JMX service URL the query is connecting to.
130         * 
131         * @return JMX service URL
132         */
133        public JMXServiceURL getJmxServiceUrl() {
134            return jmxServiceUrl;
135        }
136    
137        /**
138         * Sets the JMX service URL the query is going to connect to.
139         * 
140         * @param jmxServiceUrl - new JMX service URL
141         */
142        public void setJmxServiceUrl(JMXServiceURL jmxServiceUrl) {
143            this.jmxServiceUrl = jmxServiceUrl;
144        }
145    
146        /**
147         * Sets the JMX service URL the query is going to connect to.
148         * 
149         * @param jmxServiceUrl - new JMX service URL
150         */
151        public void setJmxServiceUrl(String jmxServiceUrl) throws MalformedURLException {
152            setJmxServiceUrl(new JMXServiceURL(jmxServiceUrl));
153        }
154    
155        /**
156         * Creates a JMX connector
157         * 
158         * @return JMX connector
159         * @throws IOException
160         */
161        protected JMXConnector createJmxConnector() throws IOException {
162            return JMXConnectorFactory.connect(getJmxServiceUrl());
163        }
164    
165        /**
166         * Creates a query expression based on the query expression string Note:
167         * currently unsupported
168         * 
169         * @param queryExpStr - query expression string
170         * @return the created query expression
171         */
172        protected QueryExp createQueryExp(String queryExpStr) {
173            // Currently unsupported
174            return null;
175        }
176    }