activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jbert...@apache.org
Subject [1/2] activemq-artemis git commit: ARTEMIS-2169 allow config of JMX RMI registry port
Date Fri, 09 Nov 2018 16:05:46 GMT
Repository: activemq-artemis
Updated Branches:
  refs/heads/master b3e767cae -> 366005e44


ARTEMIS-2169 allow config of JMX RMI registry port

Previously the port was always random. This caused problems with
remote JMX connections that needed to overcome firewalls. As of
this patch it's possible to make the RMI port static and whitelist
it in the firewall settings.


Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/6d0641b4
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/6d0641b4
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/6d0641b4

Branch: refs/heads/master
Commit: 6d0641b4385d2189e27eaab43c955239f949567d
Parents: b3e767c
Author: Å mucr Jan <jan.smucr@aimtec.cz>
Authored: Wed Nov 7 14:49:23 2018 +0100
Committer: Justin Bertram <jbertram@apache.org>
Committed: Fri Nov 9 10:04:13 2018 -0600

----------------------------------------------------------------------
 .../cli/factory/jmx/ManagementFactory.java      |   3 +
 .../activemq/artemis/dto/JMXConnectorDTO.java   |   7 +
 docs/user-manual/en/management.md               |   8 +-
 .../integration/jmx/JmxConnectionTest.java      | 162 +++++++++++++++++++
 .../src/test/resources/jmx-test-management.xml  |  49 ++++++
 5 files changed, 228 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6d0641b4/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/jmx/ManagementFactory.java
----------------------------------------------------------------------
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/jmx/ManagementFactory.java
b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/jmx/ManagementFactory.java
index 79e241e..7baa0f5 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/jmx/ManagementFactory.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/factory/jmx/ManagementFactory.java
@@ -96,6 +96,9 @@ public class ManagementFactory {
          if (jmxConnector.getConnectorHost() != null) {
             jmxConnectorConfiguration.setConnectorHost(jmxConnector.getConnectorHost());
          }
+         if (jmxConnector.getRmiRegistryPort() != null) {
+            jmxConnectorConfiguration.setRmiRegistryPort(jmxConnector.getRmiRegistryPort());
+         }
          if (jmxConnector.getJmxRealm() != null) {
             jmxConnectorConfiguration.setJmxRealm(jmxConnector.getJmxRealm());
          }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6d0641b4/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/JMXConnectorDTO.java
----------------------------------------------------------------------
diff --git a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/JMXConnectorDTO.java
b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/JMXConnectorDTO.java
index bd78481..965de93 100644
--- a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/JMXConnectorDTO.java
+++ b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/JMXConnectorDTO.java
@@ -34,6 +34,9 @@ public class JMXConnectorDTO {
    @XmlAttribute  (name = "connector-port", required = true)
    Integer connectorPort;
 
+   @XmlAttribute  (name = "rmi-registry-port")
+   Integer rmiRegistryPort;
+
    @XmlAttribute  (name = "jmx-realm")
    String jmxRealm;
 
@@ -75,6 +78,10 @@ public class JMXConnectorDTO {
       return connectorPort;
    }
 
+   public Integer getRmiRegistryPort() {
+      return rmiRegistryPort;
+   }
+
    public String getJmxRealm() {
       return jmxRealm;
    }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6d0641b4/docs/user-manual/en/management.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/management.md b/docs/user-manual/en/management.md
index f7c8352..60ef2a1 100644
--- a/docs/user-manual/en/management.md
+++ b/docs/user-manual/en/management.md
@@ -423,7 +423,13 @@ You can also configure the connector using the following:
 - `connector-port`
    
   The port to expose the agent on.
-   
+
+- `rmi-registry-port`
+
+  The port that the RMI registry binds to. If not set, the port is
+  always random. Set to avoid problems with remote JMX connections
+  tunnelled through firewall.
+
 - `jmx-realm`
    
   The jmx realm to use for authentication, defaults to `activemq` to match the

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6d0641b4/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jmx/JmxConnectionTest.java
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jmx/JmxConnectionTest.java
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jmx/JmxConnectionTest.java
new file mode 100644
index 0000000..9fd2c3a
--- /dev/null
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jmx/JmxConnectionTest.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * <br>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <br>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.activemq.artemis.tests.integration.jmx;
+
+import com.sun.jmx.remote.internal.ProxyRef;
+import org.apache.activemq.artemis.cli.Artemis;
+import org.apache.activemq.artemis.cli.commands.Run;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import sun.rmi.server.UnicastRef;
+import sun.rmi.transport.LiveRef;
+
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.rmi.RMIConnection;
+import javax.management.remote.rmi.RMIConnector;
+import java.io.File;
+import java.lang.reflect.Field;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.rmi.server.RemoteObject;
+import java.rmi.server.RemoteRef;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This test checks JMX connection to Artemis with both necessary ports set up so that it's
easier to tunnel through
+ * firewalls.
+ */
+public class JmxConnectionTest extends ActiveMQTestBase {
+
+   private static final String MANAGEMENT_XML = "/jmx-test-management.xml";
+
+   // Make sure these values are always the same as in the MANAGEMENT_XML configuration file
+   private static final String JMX_SERVER_HOSTNAME = "127.0.0.1";
+   private static final int JMX_SERVER_PORT = 10099;
+   private static final int RMI_REGISTRY_PORT = 10098;
+
+   @Override
+   @Before
+   public void setUp() throws Exception {
+
+      super.setUp();
+
+      /* This needs to be disabled because otherwise there would be a lot of complains about
Artemis' own running threads
+       * and I suppose that this kind of leaks is most likely tested somewhere else.
+       */
+      disableCheckThread();
+
+      // Artemis instance dir
+      File instanceDir = new File(temporaryFolder.getRoot(), "instance");
+
+      // Create new Artemis instance
+      Run.setEmbedded(true);
+      Artemis.main("create", instanceDir.getAbsolutePath(), "--silent", "--no-fsync", "--no-autotune",
+              "--no-web", "--no-amqp-acceptor", "--no-mqtt-acceptor", "--no-stomp-acceptor",
"--no-hornetq-acceptor");
+
+      // Configure (this is THE subject of testing)
+      File managementConfigFile = new File(instanceDir, "etc/management.xml");
+      Files.copy(getClass().getResourceAsStream(MANAGEMENT_XML), managementConfigFile.toPath(),
+              StandardCopyOption.REPLACE_EXISTING);
+
+      // Point the server to the instance directory
+      System.setProperty("artemis.instance", instanceDir.getAbsolutePath());
+
+      // Without this, the RMI server would bind to the default interface IP (the user's
local IP mostly)
+      System.setProperty("java.rmi.server.hostname", JMX_SERVER_HOSTNAME);
+
+      // Enable guest login module (dunno why this isn't automatic)
+      System.setProperty("java.security.auth.login.config", instanceDir.getAbsolutePath()
+ "/etc/login.config");
+
+      // Run Artemis server
+      Artemis.internalExecute("run");
+   }
+
+   @Test
+   public void testJmxConnection() throws Exception {
+
+      // I don't specify both ports here manually on purpose. See actual RMI registry connection
port extraction below.
+      String urlString = "service:jmx:rmi:///jndi/rmi://" + JMX_SERVER_HOSTNAME + ":" + JMX_SERVER_PORT
+ "/jmxrmi";
+
+      JMXServiceURL url = new JMXServiceURL(urlString);
+      JMXConnector jmxConnector;
+
+      try {
+         jmxConnector = JMXConnectorFactory.connect(url);
+         logAndSystemOut("Successfully connected to: " + urlString);
+      } catch (Exception e) {
+         logAndSystemOut("JMX connection failed: " + urlString, e);
+         Assert.fail();
+         return;
+      }
+
+      try {
+
+         /* Now I need to extract the RMI registry port to make sure it's equal to the configured
one. It's gonna be
+          * messy because I have to use reflection to reach the information.
+          */
+
+         Assert.assertTrue(jmxConnector instanceof RMIConnector);
+
+         // 1. RMIConnector::connection is expected to be RMIConnectionImpl_Stub
+         Field connectionField = RMIConnector.class.getDeclaredField("connection");
+         connectionField.setAccessible(true);
+         RMIConnection rmiConnection = (RMIConnection) connectionField.get(jmxConnector);
+
+         // 2. RMIConnectionImpl_Stub extends RemoteStub which extends RemoteObject
+         Assert.assertTrue(rmiConnection instanceof RemoteObject);
+         RemoteObject remoteObject = (RemoteObject) rmiConnection;
+
+         // 3. RemoteObject::getRef is hereby expected to return ProxyRef
+         RemoteRef remoteRef = remoteObject.getRef();
+         Assert.assertTrue(remoteRef instanceof ProxyRef);
+         ProxyRef proxyRef = (ProxyRef) remoteRef;
+
+         // 4. ProxyRef::ref is expected to contain UnicastRef (UnicastRef2 resp.)
+         Field refField = ProxyRef.class.getDeclaredField("ref");
+         refField.setAccessible(true);
+         remoteRef = (RemoteRef) refField.get(proxyRef);
+         Assert.assertTrue(remoteRef instanceof UnicastRef);
+
+         // 5. UnicastRef::getLiveRef returns LiveRef
+         LiveRef liveRef = ((UnicastRef) remoteRef).getLiveRef();
+
+         // 6. LiveRef::getPort is expected to be the same as the RMI registry port configured
via management.xml
+         /* Accidentally, it can happen that even with the RMI registry port unconfigured
the randomly selected port
+          * will be the same as expected by the test which will make it succeed. But it's
highly unlikely.
+          */
+         Assert.assertEquals(RMI_REGISTRY_PORT, liveRef.getPort());
+
+      } finally {
+         jmxConnector.close();
+      }
+   }
+
+   @After
+   @Override
+   public void tearDown() throws Exception {
+      Artemis.internalExecute("stop");
+      Run.latchRunning.await(5, TimeUnit.SECONDS);
+      super.tearDown();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/6d0641b4/tests/integration-tests/src/test/resources/jmx-test-management.xml
----------------------------------------------------------------------
diff --git a/tests/integration-tests/src/test/resources/jmx-test-management.xml b/tests/integration-tests/src/test/resources/jmx-test-management.xml
new file mode 100644
index 0000000..ac5ba6d
--- /dev/null
+++ b/tests/integration-tests/src/test/resources/jmx-test-management.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements. See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License. You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<management-context xmlns="http://activemq.org/schema">
+   <connector connector-port="10099" connector-host="127.0.0.1" rmi-registry-port="10098"
/>
+   <authorisation>
+      <whitelist>
+         <entry domain="hawtio"/>
+      </whitelist>
+      <default-access>
+         <access method="list*" roles="${role}"/>
+         <access method="get*" roles="${role}"/>
+         <access method="is*" roles="${role}"/>
+         <access method="set*" roles="${role}"/>
+         <access method="*" roles="${role}"/>
+      </default-access>
+      <role-access>
+         <match domain="org.apache.activemq.artemis">
+            <access method="list*" roles="${role}"/>
+            <access method="get*" roles="${role}"/>
+            <access method="is*" roles="${role}"/>
+            <access method="set*" roles="${role}"/>
+            <access method="*" roles="${role}"/>
+         </match>
+         <!--example of how to configure a specific object-->
+         <!--<match domain="org.apache.activemq.artemis" key="subcomponent=queues">
+            <access method="list*" roles="view,update,amq"/>
+            <access method="get*" roles="view,update,amq"/>
+            <access method="is*" roles="view,update,amq"/>
+            <access method="set*" roles="update,amq"/>
+            <access method="*" roles="amq"/>
+         </match>-->
+      </role-access>
+   </authorisation>
+</management-context>
\ No newline at end of file


Mime
View raw message