You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by co...@apache.org on 2020/03/19 13:05:37 UTC

[camel] 01/01: CAMEL-14742 - Prevent JMX rebinding

This is an automated email from the ASF dual-hosted git repository.

coheigea pushed a commit to branch CAMEL-14742
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 0e58de11d804930d4b7d734b9cc7671c5e982fad
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Thu Mar 19 13:04:57 2020 +0000

    CAMEL-14742 - Prevent JMX rebinding
---
 .../camel/management/DefaultManagementAgent.java   | 67 ++++++++++++++++++++--
 1 file changed, 63 insertions(+), 4 deletions(-)

diff --git a/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementAgent.java b/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementAgent.java
index 2a165cf..317c75c 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementAgent.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementAgent.java
@@ -20,7 +20,11 @@ import java.io.IOException;
 import java.lang.management.ManagementFactory;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.rmi.AccessException;
+import java.rmi.AlreadyBoundException;
 import java.rmi.NoSuchObjectException;
+import java.rmi.NotBoundException;
+import java.rmi.Remote;
 import java.rmi.RemoteException;
 import java.rmi.registry.LocateRegistry;
 import java.rmi.registry.Registry;
@@ -41,6 +45,8 @@ import javax.management.ObjectName;
 import javax.management.remote.JMXConnectorServer;
 import javax.management.remote.JMXConnectorServerFactory;
 import javax.management.remote.JMXServiceURL;
+import javax.management.remote.rmi.RMIConnectorServer;
+import javax.management.remote.rmi.RMIJRMPServerImpl;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
@@ -66,7 +72,7 @@ public class DefaultManagementAgent extends ServiceSupport implements Management
     public static final String DEFAULT_DOMAIN = "org.apache.camel";
     public static final String DEFAULT_HOST = "localhost";
     public static final int DEFAULT_REGISTRY_PORT = 1099;
-    public static final int DEFAULT_CONNECTION_PORT = -1;
+    public static final int DEFAULT_CONNECTION_PORT = 0;
     public static final String DEFAULT_SERVICE_URL_PATH = "/jmxrmi/camel";
     private static final Logger LOG = LoggerFactory.getLogger(DefaultManagementAgent.class);
 
@@ -77,6 +83,8 @@ public class DefaultManagementAgent extends ServiceSupport implements Management
     // need a name -> actual name mapping as some servers changes the names (such as WebSphere)
     private final ConcurrentMap<ObjectName, ObjectName> mbeansRegistered = new ConcurrentHashMap<>();
     private JMXConnectorServer cs;
+    private Remote remoteServerStub;
+    private RMIJRMPServerImpl rmiServer;
     private Registry registry;
 
     private Integer registryPort = DEFAULT_REGISTRY_PORT;
@@ -96,6 +104,7 @@ public class DefaultManagementAgent extends ServiceSupport implements Management
     private Boolean useHostIPAddress = false;
     private String managementNamePattern = "#name#";
     private ManagementStatisticsLevel statisticsLevel = ManagementStatisticsLevel.Default;
+    private Map<String, ?> environment;
 
     public DefaultManagementAgent() {
     }
@@ -564,7 +573,7 @@ public class DefaultManagementAgent extends ServiceSupport implements Management
             LOG.warn("Could not create and start JMX connector.", ioe);
         }
     }
-    
+
     protected MBeanServer findOrCreateMBeanServer() {
 
         // return platform mbean server if the option is specified.
@@ -592,7 +601,8 @@ public class DefaultManagementAgent extends ServiceSupport implements Management
         ObjectHelper.notNull(registryPort, "registryPort");
 
         try {
-            registry = LocateRegistry.createRegistry(registryPort);
+            String bindingName = serviceUrlPath.startsWith("/") ? serviceUrlPath.substring(1) : serviceUrlPath;
+            registry = new JmxRegistry(registryPort, bindingName);
             LOG.debug("Created JMXConnector RMI registry on port {}", registryPort);
         } catch (RemoteException ex) {
             // The registry may had been created, we could get the registry instead
@@ -609,7 +619,10 @@ public class DefaultManagementAgent extends ServiceSupport implements Management
             url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + host + ":" + registryPort + path);
         }
 
-        cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server);
+        rmiServer = new RMIJRMPServerImpl(connectorPort, null, null, environment);
+
+        // Create the connector server now.
+        cs = new RMIConnectorServer(url, environment, rmiServer, server);
 
         // use async thread for starting the JMX Connector
         // (no need to use a thread pool or enlist in JMX as this thread is terminated when the JMX connector has been started)
@@ -618,6 +631,7 @@ public class DefaultManagementAgent extends ServiceSupport implements Management
             try {
                 LOG.debug("Staring JMX Connector thread to listen at: {}", url);
                 cs.start();
+                remoteServerStub = rmiServer.toStub();
                 LOG.info("JMX Connector thread started and listening at: {}", url);
             } catch (IOException ioe) {
                 LOG.warn("Could not start JMXConnector thread at: " + url + ". JMX Connector not in use.", ioe);
@@ -626,4 +640,49 @@ public class DefaultManagementAgent extends ServiceSupport implements Management
         thread.start();
     }
 
+    public Map<String, ?> getEnvironment() {
+        return environment;
+    }
+
+    /**
+     * Set the environment attributes to control the new Connector Server
+     */
+    public void setEnvironment(Map<String, ?> environment) {
+        this.environment = environment;
+    }
+
+    /*
+     * Better to use the internal API than re-invent the wheel.
+     */
+    @SuppressWarnings("restriction")
+    private class JmxRegistry extends sun.rmi.registry.RegistryImpl {
+        private final String lookupName;
+
+        JmxRegistry(final int port, final String lookupName) throws RemoteException {
+            super(port);
+            this.lookupName = lookupName;
+        }
+
+        @Override
+        public Remote lookup(String s) throws RemoteException, NotBoundException {
+            return lookupName.equals(s) ? remoteServerStub : null;
+        }
+
+        @Override
+        public void bind(String s, Remote remote) throws RemoteException, AlreadyBoundException, AccessException {
+        }
+
+        @Override
+        public void unbind(String s) throws RemoteException, NotBoundException, AccessException {
+        }
+
+        @Override
+        public void rebind(String s, Remote remote) throws RemoteException, AccessException {
+        }
+
+        @Override
+        public String[] list() throws RemoteException {
+            return new String[] {lookupName};
+        }
+    }
 }