aboutsummaryrefslogtreecommitdiff
path: root/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java')
-rw-r--r--src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java230
1 files changed, 3 insertions, 227 deletions
diff --git a/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java b/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java
index da85fc6d4..6862066d2 100644
--- a/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java
+++ b/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java
@@ -25,22 +25,15 @@
package com.sun.jmx.namespace;
import com.sun.jmx.defaults.JmxProperties;
-import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
-import java.util.Set;
-import java.util.UUID;
import java.util.logging.Logger;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.MBeanServer;
-import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
-import javax.management.QueryExp;
-import javax.management.namespace.JMXNamespaces;
import javax.management.namespace.JMXNamespace;
import javax.management.namespace.JMXNamespacePermission;
@@ -54,12 +47,6 @@ import javax.management.namespace.JMXNamespacePermission;
*/
public class NamespaceInterceptor extends HandlerInterceptor<JMXNamespace> {
- /**
- * A logger for this class.
- **/
- private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
- private static final Logger PROBE_LOG = Logger.getLogger(
- JmxProperties.NAMESPACE_LOGGER+".probe");
// The target name space in which the NamepsaceHandler is mounted.
private final String targetNs;
@@ -69,21 +56,6 @@ public class NamespaceInterceptor extends HandlerInterceptor<JMXNamespace> {
private final ObjectNameRouter proc;
/**
- * Internal hack. The JMXRemoteNamespace can be closed and reconnected.
- * Each time the JMXRemoteNamespace connects, a probe should be sent
- * to detect cycle. The MBeanServer exposed by JMXRemoteNamespace thus
- * implements the DynamicProbe interface, which makes it possible for
- * this handler to know that it should send a new probe.
- *
- * XXX: TODO this probe thing is way too complex and fragile.
- * This *must* go away or be replaced by something simpler.
- * ideas are welcomed.
- **/
- public static interface DynamicProbe {
- public boolean isProbeRequested();
- }
-
- /**
* Creates a new instance of NamespaceInterceptor
*/
public NamespaceInterceptor(
@@ -104,164 +76,6 @@ public class NamespaceInterceptor extends HandlerInterceptor<JMXNamespace> {
", namespace="+this.targetNs+")";
}
- /*
- * XXX: TODO this probe thing is way too complex and fragile.
- * This *must* go away or be replaced by something simpler.
- * ideas are welcomed.
- */
- private volatile boolean probed = false;
- private volatile ObjectName probe;
-
- // Query Pattern that we will send through the source server in order
- // to detect self-linking namespaces.
- //
- // XXX: TODO this probe thing is way too complex and fragile.
- // This *must* go away or be replaced by something simpler.
- // ideas are welcomed.
- final ObjectName makeProbePattern(ObjectName probe)
- throws MalformedObjectNameException {
-
- // we could probably link the probe pattern with the probe - e.g.
- // using the UUID as key in the pattern - but is it worth it? it
- // also has some side effects on the context namespace - because
- // such a probe may get rejected by the jmx.context// namespace.
- //
- // The trick here is to devise a pattern that is not likely to
- // be blocked by intermediate levels. Querying for all namespace
- // handlers in the source (or source namespace) is more likely to
- // achieve this goal.
- //
- return ObjectName.getInstance("*" +
- JMXNamespaces.NAMESPACE_SEPARATOR + ":" +
- JMXNamespace.TYPE_ASSIGNMENT);
- }
-
- // tell whether the name pattern corresponds to what might have been
- // sent as a probe.
- // XXX: TODO this probe thing is way too complex and fragile.
- // This *must* go away or be replaced by something simpler.
- // ideas are welcomed.
- final boolean isProbePattern(ObjectName name) {
- final ObjectName p = probe;
- if (p == null) return false;
- try {
- return String.valueOf(name).endsWith(targetNs+
- JMXNamespaces.NAMESPACE_SEPARATOR + "*" +
- JMXNamespaces.NAMESPACE_SEPARATOR + ":" +
- JMXNamespace.TYPE_ASSIGNMENT);
- } catch (RuntimeException x) {
- // should not happen.
- PROBE_LOG.finest("Ignoring unexpected exception in self link detection: "+
- x);
- return false;
- }
- }
-
- // The first time a request reaches this NamespaceInterceptor, the
- // interceptor will send a probe to detect whether the underlying
- // JMXNamespace links to itslef.
- //
- // One way to create such self-linking namespace would be for instance
- // to create a JMXNamespace whose getSourceServer() method would return:
- // JMXNamespaces.narrowToNamespace(getMBeanServer(),
- // getObjectName().getDomain())
- //
- // If such an MBeanServer is returned, then any call to that MBeanServer
- // will trigger an infinite loop.
- // There can be even trickier configurations if remote connections are
- // involved.
- //
- // In order to prevent this from happening, the NamespaceInterceptor will
- // send a probe, in an attempt to detect whether it will receive it at
- // the other end. If the probe is received, an exception will be thrown
- // in order to break the recursion. The probe is only sent once - when
- // the first request to the namespace occurs. The DynamicProbe interface
- // can also be used by a Sun JMXNamespace implementation to request the
- // emission of a probe at any time (see JMXRemoteNamespace
- // implementation).
- //
- // Probes work this way: the NamespaceInterceptor sets a flag and sends
- // a queryNames() request. If a queryNames() request comes in when the flag
- // is on, then it deduces that there is a self-linking loop - and instead
- // of calling queryNames() on the source MBeanServer of the JMXNamespace
- // handler (which would cause the loop to go on) it breaks the recursion
- // by returning the probe ObjectName.
- // If the NamespaceInterceptor receives the probe ObjectName as result of
- // its original sendProbe() request it knows that it has been looping
- // back on itslef and throws an IOException...
- //
- //
- // XXX: TODO this probe thing is way too complex and fragile.
- // This *must* go away or be replaced by something simpler.
- // ideas are welcomed.
- //
- final void sendProbe(MBeanServerConnection msc)
- throws IOException {
- try {
- PROBE_LOG.fine("Sending probe");
-
- // This is just to prevent any other thread to modify
- // the probe while the detection cycle is in progress.
- //
- final ObjectName probePattern;
- // we don't want to synchronize on this - we use targetNs
- // because it's non null and final.
- synchronized (targetNs) {
- probed = false;
- if (probe != null) {
- throw new IOException("concurent connection in progress");
- }
- final String uuid = UUID.randomUUID().toString();
- final String endprobe =
- JMXNamespaces.NAMESPACE_SEPARATOR + uuid +
- ":type=Probe,key="+uuid;
- final ObjectName newprobe =
- ObjectName.getInstance(endprobe);
- probePattern = makeProbePattern(newprobe);
- probe = newprobe;
- }
-
- try {
- PROBE_LOG.finer("Probe query: "+probePattern+" expecting: "+probe);
- final Set<ObjectName> res = msc.queryNames(probePattern, null);
- final ObjectName expected = probe;
- PROBE_LOG.finer("Probe res: "+res);
- if (res.contains(expected)) {
- throw new IOException("namespace " +
- targetNs + " is linking to itself: " +
- "cycle detected by probe");
- }
- } catch (SecurityException x) {
- PROBE_LOG.finer("Can't check for cycles: " + x);
- // can't do anything....
- } catch (RuntimeException x) {
- PROBE_LOG.finer("Exception raised by queryNames: " + x);
- throw x;
- } finally {
- probe = null;
- }
- } catch (MalformedObjectNameException x) {
- final IOException io =
- new IOException("invalid name space: probe failed");
- io.initCause(x);
- throw io;
- }
- PROBE_LOG.fine("Probe returned - no cycles");
- probed = true;
- }
-
- // allows a Sun implementation JMX Namespace, such as the
- // JMXRemoteNamespace, to control when a probe should be sent.
- //
- // XXX: TODO this probe thing is way too complex and fragile.
- // This *must* go away or be replaced by something simpler.
- // ideas are welcomed.
- private boolean isProbeRequested(Object o) {
- if (o instanceof DynamicProbe)
- return ((DynamicProbe)o).isProbeRequested();
- return false;
- }
-
/**
* This method will send a probe to detect self-linking name spaces.
* A self linking namespace is a namespace that links back directly
@@ -281,29 +95,9 @@ public class NamespaceInterceptor extends HandlerInterceptor<JMXNamespace> {
* (see JMXRemoteNamespace implementation).
*/
private MBeanServer connection() {
- try {
- final MBeanServer c = super.source();
- if (probe != null) // should not happen
- throw new RuntimeException("connection is being probed");
-
- if (probed == false || isProbeRequested(c)) {
- try {
- // Should not happen if class well behaved.
- // Never probed. Force it.
- //System.err.println("sending probe for " +
- // "target="+targetNs+", source="+srcNs);
- sendProbe(c);
- } catch (IOException io) {
- throw new RuntimeException(io.getMessage(), io);
- }
- }
-
- if (c != null) {
- return c;
- }
- } catch (RuntimeException x) {
- throw x;
- }
+ final MBeanServer c = super.source();
+ if (c != null) return c;
+ // should not come here
throw new NullPointerException("getMBeanServerConnection");
}
@@ -319,24 +113,6 @@ public class NamespaceInterceptor extends HandlerInterceptor<JMXNamespace> {
return super.source();
}
- /**
- * Calls {@link MBeanServerConnection#queryNames queryNames}
- * on the underlying
- * {@link #getMBeanServerConnection MBeanServerConnection}.
- **/
- @Override
- public final Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
- // XXX: TODO this probe thing is way too complex and fragile.
- // This *must* go away or be replaced by something simpler.
- // ideas are welcomed.
- PROBE_LOG.finer("probe is: "+probe+" pattern is: "+name);
- if (probe != null && isProbePattern(name)) {
- PROBE_LOG.finer("Return probe: "+probe);
- return Collections.singleton(probe);
- }
- return super.queryNames(name, query);
- }
-
@Override
protected ObjectName toSource(ObjectName targetName)
throws MalformedObjectNameException {