Repository: incubator-reef
Updated Branches:
  refs/heads/master c2e791628 -> 1ea4d64b1


[REEF-591] Use TcpPortProvider in HttpServerImpl

This adds `TcpPortProvider` usage in `HttpServerImpl`.

JIRA:
  [REEF-591](https://issues.apache.org/jira/browse/REEF-591)

Pull Request:
  Thos closes #373


Project: http://git-wip-us.apache.org/repos/asf/incubator-reef/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-reef/commit/1ea4d64b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-reef/tree/1ea4d64b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-reef/diff/1ea4d64b

Branch: refs/heads/master
Commit: 1ea4d64b14260db063cf22a3d791795b1af5bc97
Parents: c2e7916
Author: Beysim Sezgin <[email protected]>
Authored: Fri Aug 14 16:44:23 2015 -0700
Committer: Markus Weimer <[email protected]>
Committed: Tue Aug 18 08:40:19 2015 -0700

----------------------------------------------------------------------
 .../apache/reef/webserver/HttpServerImpl.java   | 51 +++++++++++-----
 .../apache/reef/webserver/MaxPortNumber.java    |  2 +
 .../apache/reef/webserver/MaxRetryAttempts.java |  2 +
 .../apache/reef/webserver/MinPortNumber.java    |  2 +
 .../org/apache/reef/webserver/PortNumber.java   |  8 ++-
 .../apache/reef/webserver/TestHttpServer.java   | 62 +++++++++++++++++++-
 6 files changed, 108 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/1ea4d64b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/HttpServerImpl.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/HttpServerImpl.java
 
b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/HttpServerImpl.java
index 8935ff0..b76ea77 100644
--- 
a/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/HttpServerImpl.java
+++ 
b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/HttpServerImpl.java
@@ -21,10 +21,12 @@ package org.apache.reef.webserver;
 import org.apache.reef.tang.annotations.Parameter;
 import org.apache.reef.util.logging.LoggingScope;
 import org.apache.reef.util.logging.LoggingScopeFactory;
+import org.apache.reef.wake.remote.ports.TcpPortProvider;
 import org.mortbay.jetty.Server;
 
 import javax.inject.Inject;
 import java.net.BindException;
+import java.util.Iterator;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -70,39 +72,56 @@ public final class HttpServerImpl implements HttpServer {
                  @Parameter(MaxPortNumber.class) final int maxPortNumber,
                  @Parameter(MinPortNumber.class) final int minPortNumber,
                  @Parameter(MaxRetryAttempts.class) final int maxRetryAttempts,
+                 final TcpPortProvider tcpPortProvider,
                  final LoggingScopeFactory loggingScopeFactory) throws 
Exception {
 
     this.loggingScopeFactory = loggingScopeFactory;
+    this.jettyHandler = jettyHandler;
+    int availablePort = portNumber;
+    Server srv = null;
+
     try (final LoggingScope ls = this.loggingScopeFactory.httpServer()) {
-      this.jettyHandler = jettyHandler;
-      int availablePort = portNumber;
-      Server srv = null;
-      boolean found = false;
-      for (int attempt = 0; attempt < maxRetryAttempts; ++attempt) {
-        if (attempt > 0) {
-          availablePort = getNextPort(maxPortNumber, minPortNumber);
+      if (portNumber != Integer.parseInt(PortNumber.DEFAULT_VALUE)) {
+        // legacy path to be removed
+        for (int attempt = 0; attempt < maxRetryAttempts && srv  == null; 
++attempt) {
+          if (attempt > 0) {
+            // first attempt should be portNumber passed in
+            availablePort = getNextPort(maxPortNumber, minPortNumber);
+          }
+          srv = tryPort(availablePort);
         }
-        srv = new Server(availablePort);
-        try {
-          srv.start();
-          found = true;
-          break;
-        } catch (final BindException ex) {
-          LOG.log(Level.FINEST, "Cannot use port: {0}. Will try another", 
availablePort);
+      } else {
+        // new TcpPortProvider path
+        final Iterator<Integer> ports = tcpPortProvider.iterator();
+        while (ports.hasNext() && srv  == null) {
+          availablePort = ports.next();
+          srv = tryPort(availablePort);
         }
       }
 
-      if (found) {
+      if (srv  != null) {
         this.server = srv;
         this.port = availablePort;
         this.server.setHandler(jettyHandler);
         LOG.log(Level.INFO, "Jetty Server started with port: {0}", 
availablePort);
       } else {
-        throw new RuntimeException("Could not find available port in " + 
maxRetryAttempts + " attempts");
+        throw new RuntimeException("Could not find available port for http");
       }
     }
   }
 
+  private Server tryPort(final int portNumber) throws Exception {
+    Server srv = new Server(portNumber);
+    try {
+      srv.start();
+      LOG.log(Level.INFO, "Jetty Server started with port: {0}", portNumber);
+    } catch (final BindException ex) {
+      srv = null;
+      LOG.log(Level.FINEST, "Cannot use port: {0}. Will try another", 
portNumber);
+    }
+    return srv;
+  }
+
   /**
    * get a random port number in min and max range.
    *

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/1ea4d64b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/MaxPortNumber.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/MaxPortNumber.java
 
b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/MaxPortNumber.java
index 51a2952..2c05c76 100644
--- 
a/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/MaxPortNumber.java
+++ 
b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/MaxPortNumber.java
@@ -23,7 +23,9 @@ import org.apache.reef.tang.annotations.NamedParameter;
 
 /**
  * max port number range when generating a port number for the Http Server.
+ * @deprecated in 0.13, use TcpPortRangeCount and TcpPortProvider instead.
  */
 @NamedParameter(doc = "Max port number for Jetty Server", default_value = 
"49151")
+@Deprecated
 public class MaxPortNumber implements Name<Integer> {
 }

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/1ea4d64b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/MaxRetryAttempts.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/MaxRetryAttempts.java
 
b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/MaxRetryAttempts.java
index 390e0f5..c523187 100644
--- 
a/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/MaxRetryAttempts.java
+++ 
b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/MaxRetryAttempts.java
@@ -23,7 +23,9 @@ import org.apache.reef.tang.annotations.NamedParameter;
 
 /**
  * Max retry times when generating a port number for the Http Server.
+ * @deprecated in 0.13, use TcpPortRangeTryCount and TcpPortProvider instead.
  */
 @NamedParameter(doc = "Maximum retry attempts for port number of Jetty 
Server", default_value = "100")
+@Deprecated
 public class MaxRetryAttempts implements Name<Integer> {
 }

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/1ea4d64b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/MinPortNumber.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/MinPortNumber.java
 
b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/MinPortNumber.java
index 62c1486..ecc76bb 100644
--- 
a/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/MinPortNumber.java
+++ 
b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/MinPortNumber.java
@@ -23,7 +23,9 @@ import org.apache.reef.tang.annotations.NamedParameter;
 
 /**
  * minimum port number range when generating a port number for the Http Server.
+ * @deprecated in 0.13, use TcpPortRangeStart and TcpPortProvider instead.
  */
 @NamedParameter(doc = "Minimum port number for Jetty Server", default_value = 
"1024")
+@Deprecated
 public class MinPortNumber implements Name<Integer> {
 }

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/1ea4d64b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/PortNumber.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/PortNumber.java
 
b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/PortNumber.java
index d22647d..92bad3b 100644
--- 
a/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/PortNumber.java
+++ 
b/lang/java/reef-webserver/src/main/java/org/apache/reef/webserver/PortNumber.java
@@ -25,7 +25,11 @@ import org.apache.reef.tang.annotations.NamedParameter;
  * port number for the Http Server
  * Clients can set a preferred port number. However, Reef will detect if the 
given port number has been used
  * in the machine. If yes, it will generate another available port number.
+ * @deprecated in 0.13, use TcpPortRangeStart and TcpPortProvider instead.
  */
-@NamedParameter(doc = "Port number for Jetty Server", default_value = "8080")
-public class PortNumber implements Name<Integer> {
+@NamedParameter(doc = "Port number for Jetty Server", default_value = 
PortNumber.DEFAULT_VALUE)
+@Deprecated
+public final class PortNumber implements Name<Integer> {
+  private PortNumber(){}
+  public static final String DEFAULT_VALUE = "8080";
 }

http://git-wip-us.apache.org/repos/asf/incubator-reef/blob/1ea4d64b/lang/java/reef-webserver/src/test/java/org/apache/reef/webserver/TestHttpServer.java
----------------------------------------------------------------------
diff --git 
a/lang/java/reef-webserver/src/test/java/org/apache/reef/webserver/TestHttpServer.java
 
b/lang/java/reef-webserver/src/test/java/org/apache/reef/webserver/TestHttpServer.java
index a331052..cf05e6f 100644
--- 
a/lang/java/reef-webserver/src/test/java/org/apache/reef/webserver/TestHttpServer.java
+++ 
b/lang/java/reef-webserver/src/test/java/org/apache/reef/webserver/TestHttpServer.java
@@ -26,6 +26,9 @@ import org.apache.reef.tang.Injector;
 import org.apache.reef.tang.Tang;
 import org.apache.reef.tang.exceptions.InjectionException;
 import org.apache.reef.wake.remote.RemoteConfiguration;
+import org.apache.reef.wake.remote.ports.parameters.TcpPortRangeBegin;
+import org.apache.reef.wake.remote.ports.parameters.TcpPortRangeCount;
+import org.apache.reef.wake.remote.ports.parameters.TcpPortRangeTryCount;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -110,6 +113,62 @@ public class TestHttpServer {
   }
 
   @Test
+  public void httpServerPortRangeTestWithTcpPortProvider() throws Exception {
+    final Configuration httpRuntimeConfiguration = 
HttpRuntimeConfiguration.CONF.build();
+
+    final Configuration httpServerConfiguration = 
Tang.Factory.getTang().newConfigurationBuilder()
+        .bindNamedParameter(TcpPortRangeCount.class, "8900")
+        .bindNamedParameter(TcpPortRangeBegin.class, "1000")
+        .bindNamedParameter(TcpPortRangeTryCount.class, "3")
+        .build();
+
+    final Configuration configuration =
+        Configurations.merge(httpRuntimeConfiguration, 
httpServerConfiguration);
+
+    final Injector injector1 = 
Tang.Factory.getTang().newInjector(configuration);
+    final HttpServer httpServer1 = injector1.getInstance(HttpServer.class);
+
+    final Injector injector2 = 
Tang.Factory.getTang().newInjector(configuration);
+    final HttpServer httpServer2 = injector2.getInstance(HttpServer.class);
+
+    Assert.assertTrue("port number is out of specified range",
+        httpServer2.getPort() >= 1000 && httpServer2.getPort() <= 9900);
+
+    httpServer1.stop();
+    httpServer2.stop();
+  }
+
+
+  @Test
+  public void httpServerPortRetryTestWithTcpPortProvider() throws Exception {
+
+    final Configuration httpRuntimeConfiguration = 
HttpRuntimeConfiguration.CONF.build();
+    final Injector injector1 = 
Tang.Factory.getTang().newInjector(httpRuntimeConfiguration);
+    final HttpServer httpServer1 = injector1.getInstance(HttpServer.class);
+    final String portUsed = "" + httpServer1.getPort();
+
+    final Configuration httpServerConfiguration = 
Tang.Factory.getTang().newConfigurationBuilder()
+        .bindNamedParameter(TcpPortRangeCount.class, "1")
+        .bindNamedParameter(TcpPortRangeBegin.class, portUsed)
+        .bindNamedParameter(TcpPortRangeTryCount.class, "3")
+        .build();
+
+    final Configuration configuration =
+        Configurations.merge(httpRuntimeConfiguration, 
httpServerConfiguration);
+
+    final Injector injector2 = 
Tang.Factory.getTang().newInjector(configuration);
+
+    try {
+      injector2.getInstance(HttpServer.class);
+      Assert.fail("Created two web servers on the same port: " + portUsed);
+    } catch (final InjectionException ex) {
+      Assert.assertEquals("Could not find available port for http", 
ex.getCause().getMessage());
+    }
+
+    httpServer1.stop();
+  }
+
+  @Test
   public void httpServerPortRetryTest() throws Exception {
 
     final Configuration httpRuntimeConfiguration = 
HttpRuntimeConfiguration.CONF.build();
@@ -133,12 +192,13 @@ public class TestHttpServer {
       injector2.getInstance(HttpServer.class);
       Assert.fail("Created two web servers on the same port: " + portUsed);
     } catch (final InjectionException ex) {
-      Assert.assertEquals("Could not find available port in 3 attempts", 
ex.getCause().getMessage());
+      Assert.assertEquals("Could not find available port for http", 
ex.getCause().getMessage());
     }
 
     httpServer1.stop();
   }
 
+
   @Test
   public void httpServerAddHandlerTest() throws Exception {
 

Reply via email to