You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ro...@apache.org on 2022/03/04 14:01:33 UTC

[activemq-artemis] branch main updated: ARTEMIS-3699 expose actual port on NettyAcceptor

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

robbie pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git


The following commit(s) were added to refs/heads/main by this push:
     new c376503  ARTEMIS-3699 expose actual port on NettyAcceptor
     new e0ca92d  This closes #3969
c376503 is described below

commit c376503f35cf26901088e11d7c0a9cdf35fb1967
Author: Justin Bertram <jb...@apache.org>
AuthorDate: Mon Feb 28 13:45:02 2022 -0600

    ARTEMIS-3699 expose actual port on NettyAcceptor
    
    It sometimes makes sense to set an acceptor's port to 0 to allow the JVM
    to select an ephemeral port (e.g. in embedded integration tests). This
    commit adds a new getter on NettyAcceptor so tests can programmtically
    determine the actual port used by the acceptor.
    
    This commit also changes the ACCEPTOR_STARTED notification and the
    related logging to clarify the actual port value where clients can
    connect.
---
 .../core/remoting/impl/netty/NettyAcceptor.java     | 18 ++++++++++++++++--
 .../artemis/spi/core/remoting/Acceptor.java         | 11 +++++++++++
 .../management/ActiveMQServerControlTest.java       |  4 ++--
 .../core/remoting/impl/netty/NettyAcceptorTest.java | 21 +++++++++++++++++++++
 4 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
index 9f9c2c9..f8ad5e3 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java
@@ -241,6 +241,8 @@ public class NettyAcceptor extends AbstractAcceptor {
 
    private volatile Object providerAgnosticSslContext;
 
+   private volatile int actualPort = 0;
+
    public NettyAcceptor(final String name,
                         final ClusterConnection clusterConnection,
                         final Map<String, Object> configuration,
@@ -529,12 +531,12 @@ public class NettyAcceptor extends AbstractAcceptor {
             TypedProperties props = new TypedProperties();
             props.putSimpleStringProperty(new SimpleString("factory"), new SimpleString(NettyAcceptorFactory.class.getName()));
             props.putSimpleStringProperty(new SimpleString("host"), new SimpleString(host));
-            props.putIntProperty(new SimpleString("port"), port);
+            props.putIntProperty(new SimpleString("port"), actualPort);
             Notification notification = new Notification(null, CoreNotificationType.ACCEPTOR_STARTED, props);
             notificationService.sendNotification(notification);
          }
 
-         ActiveMQServerLogger.LOGGER.startedAcceptor(acceptorType, host, port, protocolsString);
+         ActiveMQServerLogger.LOGGER.startedAcceptor(acceptorType, host, actualPort, protocolsString);
       }
 
       if (batchDelay > 0) {
@@ -715,6 +717,13 @@ public class NettyAcceptor extends AbstractAcceptor {
          Channel serverChannel = null;
          try {
             serverChannel = bootstrap.bind(address).syncUninterruptibly().channel();
+
+            // The port may be configured as `0` which means the JVM will select an ephemeral port
+            if (serverChannel.localAddress() instanceof InetSocketAddress) {
+               actualPort = ((InetSocketAddress)serverChannel.localAddress()).getPort();
+            } else {
+               actualPort = port;
+            }
          } catch (Exception e) {
             throw ActiveMQMessageBundle.BUNDLE.failedToBind(getName(), h + ":" + port, e);
          }
@@ -1044,4 +1053,9 @@ public class NettyAcceptor extends AbstractAcceptor {
    public boolean isAutoStart() {
       return autoStart;
    }
+
+   @Override
+   public int getActualPort() {
+      return actualPort;
+   }
 }
diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/remoting/Acceptor.java b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/remoting/Acceptor.java
index f314a04..9b36a47 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/remoting/Acceptor.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/remoting/Acceptor.java
@@ -83,4 +83,15 @@ public interface Acceptor extends ActiveMQComponent {
    default ProtocolHandler getProtocolHandler() {
       return null;
    }
+
+   /**
+    * This is a utility method for Socket-based acceptor implementations to get the actual port used.
+    * This is useful for configurations which specify a port number of 0 which allows the JVM to select
+    * an ephemeral port.
+    *
+    * @return the actual port used if using a Socket-based acceptor implementation; -1 otherwise
+    */
+   default int getActualPort() {
+      return -1;
+   }
 }
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java
index 32e6d5a..78e7649 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java
@@ -22,8 +22,6 @@ import javax.jms.MessageConsumer;
 import javax.jms.MessageProducer;
 import javax.jms.Session;
 import javax.jms.TextMessage;
-import org.apache.activemq.artemis.json.JsonArray;
-import org.apache.activemq.artemis.json.JsonObject;
 import javax.transaction.xa.XAResource;
 import javax.transaction.xa.Xid;
 import java.nio.ByteBuffer;
@@ -88,6 +86,8 @@ import org.apache.activemq.artemis.core.transaction.impl.XidImpl;
 import org.apache.activemq.artemis.jms.client.ActiveMQConnection;
 import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
 import org.apache.activemq.artemis.jms.client.ActiveMQSession;
+import org.apache.activemq.artemis.json.JsonArray;
+import org.apache.activemq.artemis.json.JsonObject;
 import org.apache.activemq.artemis.nativo.jlibaio.LibaioContext;
 import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
 import org.apache.activemq.artemis.spi.core.security.jaas.InVMLoginModule;
diff --git a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/remoting/impl/netty/NettyAcceptorTest.java b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/remoting/impl/netty/NettyAcceptorTest.java
index 7261d3c..b92a175 100644
--- a/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/remoting/impl/netty/NettyAcceptorTest.java
+++ b/tests/unit-tests/src/test/java/org/apache/activemq/artemis/tests/unit/core/remoting/impl/netty/NettyAcceptorTest.java
@@ -34,8 +34,10 @@ import org.apache.activemq.artemis.spi.core.remoting.BufferHandler;
 import org.apache.activemq.artemis.spi.core.remoting.Connection;
 import org.apache.activemq.artemis.spi.core.remoting.ServerConnectionLifeCycleListener;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
+import org.apache.activemq.artemis.tests.util.RandomUtil;
 import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
 import org.apache.activemq.artemis.utils.PortCheckRule;
+import org.apache.activemq.artemis.utils.Wait;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -123,4 +125,23 @@ public class NettyAcceptorTest extends ActiveMQTestBase {
       assertTrue(server.getRemotingService().getAcceptor("start").isStarted());
       assertFalse(server.getRemotingService().getAcceptor("noStart").isStarted());
    }
+
+   @Test
+   public void testActualPort() throws Exception {
+      String firstPort0 = RandomUtil.randomString();
+      String secondPort0 = RandomUtil.randomString();
+      String normal = RandomUtil.randomString();
+      String invm = RandomUtil.randomString();
+      ActiveMQServer server = createServer(false, createDefaultInVMConfig());
+      server.getConfiguration().addAcceptorConfiguration(firstPort0, "tcp://127.0.0.1:0");
+      server.getConfiguration().addAcceptorConfiguration(secondPort0, "tcp://127.0.0.1:0");
+      server.getConfiguration().addAcceptorConfiguration(normal, "tcp://127.0.0.1:61616");
+      server.getConfiguration().addAcceptorConfiguration(invm, "vm://1");
+      server.start();
+      Wait.assertTrue(() -> server.getRemotingService().getAcceptor(firstPort0).getActualPort() > 0);
+      Wait.assertTrue(() -> server.getRemotingService().getAcceptor(secondPort0).getActualPort() > 0);
+      Wait.assertTrue(() -> server.getRemotingService().getAcceptor(firstPort0).getActualPort() != server.getRemotingService().getAcceptor(secondPort0).getActualPort());
+      Wait.assertEquals(61616, () -> server.getRemotingService().getAcceptor(normal).getActualPort());
+      Wait.assertEquals(-1, () -> server.getRemotingService().getAcceptor(invm).getActualPort());
+   }
 }