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

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 8f5f59f5dcb8ffa1547afb20cd63bfadaeba365b
Author: Guillaume Nodet <gno...@gmail.com>
AuthorDate: Tue May 28 11:36:30 2019 +0200

    Use custom ports for management tests
---
 .../camel/management/ManagedComponentTest.java     |   3 +-
 .../camel/management/ManagementTestSupport.java    |  19 +++
 .../camel/management/util/AvailablePortFinder.java | 167 +++++++++++++++++++++
 3 files changed, 187 insertions(+), 2 deletions(-)

diff --git 
a/core/camel-management-impl/src/test/java/org/apache/camel/management/ManagedComponentTest.java
 
b/core/camel-management-impl/src/test/java/org/apache/camel/management/ManagedComponentTest.java
index acbea64..b78f6c4 100644
--- 
a/core/camel-management-impl/src/test/java/org/apache/camel/management/ManagedComponentTest.java
+++ 
b/core/camel-management-impl/src/test/java/org/apache/camel/management/ManagedComponentTest.java
@@ -80,8 +80,7 @@ public class ManagedComponentTest extends 
ManagementTestSupport {
             return;
         }
 
-        JMXConnector connector = JMXConnectorFactory.connect(new 
JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi/camel"));
-        MBeanServerConnection mbeanServer = 
connector.getMBeanServerConnection();
+        MBeanServerConnection mbeanServer = getMBeanServer();
 
         ObjectName on = 
ObjectName.getInstance("org.apache.camel:context=camel-1,type=components,name=\"my-verifiable-component\"");
         assertTrue(mbeanServer.isRegistered(on));
diff --git 
a/core/camel-management-impl/src/test/java/org/apache/camel/management/ManagementTestSupport.java
 
b/core/camel-management-impl/src/test/java/org/apache/camel/management/ManagementTestSupport.java
index 2965622..a4057bd 100644
--- 
a/core/camel-management-impl/src/test/java/org/apache/camel/management/ManagementTestSupport.java
+++ 
b/core/camel-management-impl/src/test/java/org/apache/camel/management/ManagementTestSupport.java
@@ -17,6 +17,7 @@
 package org.apache.camel.management;
 
 import java.io.IOException;
+import java.util.Random;
 
 import javax.management.InstanceNotFoundException;
 import javax.management.MBeanException;
@@ -26,17 +27,35 @@ import javax.management.ObjectName;
 import javax.management.ReflectionException;
 
 import org.apache.camel.ContextTestSupport;
+import org.apache.camel.api.management.JmxSystemPropertyKeys;
+import org.apache.camel.management.util.AvailablePortFinder;
+import org.junit.Before;
 
 /**
  * Base class for JMX tests.
  */
 public abstract class ManagementTestSupport extends ContextTestSupport {
 
+    protected int registryPort;
+    protected String url;
+
     @Override
     protected boolean useJmx() {
         return true;
     }
 
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        registryPort = AvailablePortFinder.getNextAvailable();
+        log.info("Using port " + registryPort);
+
+        // need to explicit set it to false to use non-platform mbs
+        System.setProperty(JmxSystemPropertyKeys.CREATE_CONNECTOR, "true");
+        System.setProperty(JmxSystemPropertyKeys.REGISTRY_PORT, "" + 
registryPort);
+        super.setUp();
+    }
+
     protected MBeanServer getMBeanServer() {
         return 
context.getManagementStrategy().getManagementAgent().getMBeanServer();
     }
diff --git 
a/core/camel-management-impl/src/test/java/org/apache/camel/management/util/AvailablePortFinder.java
 
b/core/camel-management-impl/src/test/java/org/apache/camel/management/util/AvailablePortFinder.java
new file mode 100644
index 0000000..04a14b2
--- /dev/null
+++ 
b/core/camel-management-impl/src/test/java/org/apache/camel/management/util/AvailablePortFinder.java
@@ -0,0 +1,167 @@
+/*
+ * 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.
+ */
+package org.apache.camel.management.util;
+
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.ServerSocket;
+import java.util.NoSuchElementException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Finds currently available server ports.
+ */
+public final class AvailablePortFinder {
+
+    /**
+     * The minimum server currentMinPort number for IPv4.
+     * Set at 1100 to avoid returning privileged currentMinPort numbers.
+     */
+    public static final int MIN_PORT_NUMBER = 1100;
+
+    /**
+     * The maximum server currentMinPort number for IPv4.
+     */
+    public static final int MAX_PORT_NUMBER = 65535;
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(AvailablePortFinder.class);
+
+    /**
+     * We'll hold open the lowest port in this process
+     * so parallel processes won't use the same block
+     * of ports.   They'll go up to the next block.
+     */
+    private static final ServerSocket LOCK;
+
+    /**
+     * Incremented to the next lowest available port when getNextAvailable() 
is called.
+     */
+    private static AtomicInteger currentMinPort = new 
AtomicInteger(MIN_PORT_NUMBER);
+
+    /**
+     * Creates a new instance.
+     */
+    private AvailablePortFinder() {
+        // Do nothing
+    }
+    
+    static {
+        int port = MIN_PORT_NUMBER;
+        ServerSocket ss = null;
+
+        while (ss == null) {
+            try {
+                ss = new ServerSocket(port);
+            } catch (Exception e) {
+                ss = null;
+                port += 200;
+            }
+        } 
+        LOCK = ss;
+        Runtime.getRuntime().addShutdownHook(new Thread() {
+            public void run() {
+                try {
+                    LOCK.close();
+                } catch (Exception ex) {
+                    //ignore
+                }
+            }
+        });
+        currentMinPort.set(port + 1);
+    }
+
+    /**
+     * Gets the next available port starting at the lowest number. This is the 
preferred
+     * method to use. The port return is immediately marked in use and doesn't 
rely on the caller actually opening
+     * the port.
+     *
+     * @throws IllegalArgumentException is thrown if the port number is out of 
range
+     * @throws NoSuchElementException if there are no ports available
+     * @return the available port
+     */
+    public static synchronized int getNextAvailable() {
+        int next = getNextAvailable(currentMinPort.get());
+        currentMinPort.set(next + 1);
+        return next;
+    }
+
+    /**
+     * Gets the next available port starting at a given from port.
+     *
+     * @param fromPort the from port to scan for availability
+     * @throws IllegalArgumentException is thrown if the port number is out of 
range
+     * @throws NoSuchElementException if there are no ports available
+     * @return the available port
+     */
+    public static synchronized int getNextAvailable(int fromPort) {
+        if (fromPort < currentMinPort.get() || fromPort > MAX_PORT_NUMBER) {
+            throw new IllegalArgumentException("From port number not in valid 
range: " + fromPort);
+        }
+
+        for (int i = fromPort; i <= MAX_PORT_NUMBER; i++) {
+            if (available(i)) {
+                LOG.info("getNextAvailable({}) -> {}", fromPort, i);
+                return i;
+            }
+        }
+
+        throw new NoSuchElementException("Could not find an available port 
above " + fromPort);
+    }
+
+    /**
+     * Checks to see if a specific port is available.
+     *
+     * @param port the port number to check for availability
+     * @return <tt>true</tt> if the port is available, or <tt>false</tt> if not
+     * @throws IllegalArgumentException is thrown if the port number is out of 
range
+     */
+    public static boolean available(int port) throws IllegalArgumentException {
+        if (port < currentMinPort.get() || port > MAX_PORT_NUMBER) {
+            throw new IllegalArgumentException("Invalid start currentMinPort: 
" + port);
+        }
+
+        ServerSocket ss = null;
+        DatagramSocket ds = null;
+        try {
+            ss = new ServerSocket(port);
+            ss.setReuseAddress(true);
+            ds = new DatagramSocket(port);
+            ds.setReuseAddress(true);
+            return true;
+        } catch (IOException e) {
+            // Do nothing
+        } finally {
+            if (ds != null) {
+                ds.close();
+            }
+
+            if (ss != null) {
+                try {
+                    ss.close();
+                } catch (IOException e) {
+                    /* should not be thrown */
+                }
+            }
+        }
+
+        return false;
+    }
+
+}

Reply via email to