From 853963f833bb132c78c60fa115f9ec03c46b81ae Mon Sep 17 00:00:00 2001 From: Amnon Heiman Date: Thu, 5 May 2016 14:20:26 +0300 Subject: [PATCH] APIMBeanServer: overload the queryName implementation The mx4j implementation of queryName does not handle correctly pattern matching. This patch identify that a name contains a patern and do the patern matching as it should have been done by the mx4j MBeanServer. Fixes #28 Message-Id: <1462447227-8367-1-git-send-email-amnon@scylladb.com> --- .../scylladb/jmx/utils/APIMBeanServer.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/main/java/com/scylladb/jmx/utils/APIMBeanServer.java b/src/main/java/com/scylladb/jmx/utils/APIMBeanServer.java index 920b863..e3ef0a7 100644 --- a/src/main/java/com/scylladb/jmx/utils/APIMBeanServer.java +++ b/src/main/java/com/scylladb/jmx/utils/APIMBeanServer.java @@ -20,6 +20,12 @@ package com.scylladb.jmx.utils; * along with Scylla. If not, see . */ import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; import java.util.Set; import javax.management.MBeanServer; @@ -29,6 +35,8 @@ import org.apache.cassandra.db.ColumnFamilyStore; import org.apache.cassandra.metrics.StreamingMetrics; import mx4j.server.ChainedMBeanServer; +import mx4j.server.MX4JMBeanServer; +import mx4j.util.Utils; public class APIMBeanServer extends ChainedMBeanServer { private static final java.util.logging.Logger logger = java.util.logging.Logger @@ -52,8 +60,26 @@ public class APIMBeanServer extends ChainedMBeanServer { super.setMBeanServer(server); } + public ObjectName apiNormalizeObjectName(ObjectName name) { + try { + Class[] cArg = new Class[1]; + cArg[0] = ObjectName.class; + Method met = MX4JMBeanServer.class + .getDeclaredMethod("normalizeObjectName", cArg); + met.setAccessible(true); + return (ObjectName) met.invoke((MX4JMBeanServer) getMBeanServer(), + name); + } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + // TODO Auto-generated catch block + return null; + } + } + @Override public Set queryNames(ObjectName name, QueryExp query) { + if (name == null) { + return super.queryNames(name, query); + } if (name.getCanonicalKeyPropertyListString() .contains("ColumnFamilies")) { ColumnFamilyStore.checkRegistration(); @@ -61,6 +87,46 @@ public class APIMBeanServer extends ChainedMBeanServer { .contains("Stream")) { StreamingMetrics.checkRegistration(); } + ObjectName no = apiNormalizeObjectName(name); + Hashtable patternProps = no.getKeyPropertyList(); + boolean paternFound = false; + for (Iterator j = patternProps.entrySet().iterator(); j.hasNext();) { + Map.Entry entry = (Map.Entry) j.next(); + String patternValue = (String) entry.getValue(); + if (patternValue.contains("*")) { + paternFound = true; + break; + } + } + if (paternFound) { + Set res = new HashSet(); + for (ObjectName q : (Set) super.queryNames(null,query)) { + if (Utils.wildcardMatch(name.getDomain(), q.getDomain())) { + Hashtable props = q.getKeyPropertyList(); + boolean found = true; + for (Iterator j = patternProps.entrySet().iterator(); j + .hasNext();) { + Map.Entry entry = (Map.Entry) j.next(); + String patternKey = (String) entry.getKey(); + String patternValue = (String) entry.getValue(); + if (props.containsKey(patternKey)) { + if (!Utils.wildcardMatch(patternValue, + props.get(patternKey).toString())) { + found = false; + break; + } + } else { + found = false; + break; + } + } + if (found) { + res.add(q); + } + } + } + return res; + } return super.queryNames(name, query); } } \ No newline at end of file