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());
+ }
}