JAL-3851 start a listener with -testlistener and suggest a port with -testlistener_po...
authorBen Soares <b.soares@dundee.ac.uk>
Tue, 3 Aug 2021 20:10:16 +0000 (21:10 +0100)
committerBen Soares <b.soares@dundee.ac.uk>
Tue, 3 Aug 2021 20:10:16 +0000 (21:10 +0100)
src/jalview/bin/Jalview.java
src/jalview/gbtest/TestListener.java [new file with mode: 0644]
src/jalview/httpserver/HttpServer.java

index 4c21624..76ed17e 100755 (executable)
@@ -27,6 +27,7 @@ import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
+import java.net.BindException;
 import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -51,9 +52,11 @@ import com.threerings.getdown.util.LaunchUtil;
 import groovy.lang.Binding;
 import groovy.util.GroovyScriptEngine;
 import jalview.ext.so.SequenceOntology;
+import jalview.gbtest.TestListener;
 import jalview.gui.AlignFrame;
 import jalview.gui.Desktop;
 import jalview.gui.PromptUserConfig;
+import jalview.httpserver.HttpServer;
 import jalview.io.AppletFormatAdapter;
 import jalview.io.BioJsHTMLOutput;
 import jalview.io.DataSourceType;
@@ -475,6 +478,38 @@ public class Jalview
       }
     }
 
+    // Start a TestListener
+    boolean startTestListener = aparser.contains("testlistener");
+    if (startTestListener)
+    {
+      String sPort = aparser.getValue("testlistener_port");
+      int port = 0;
+      if (sPort != null)
+      {
+        try
+        {
+          port = Integer.parseInt(sPort);
+        } catch (NumberFormatException e)
+        {
+          Cache.warn("testlistener_port '" + sPort
+                  + "' not parseable as Integer");
+        }
+      }
+      try
+      {
+        HttpServer.setSuggestedPort(port);
+        TestListener testListener = new TestListener();
+        Cache.info("TestListener started at "
+                + HttpServer.getInstance().getUri().toString());
+      } catch (BindException e)
+      {
+        Cache.warn("Could not open TestListener");
+        e.printStackTrace();
+      }
+      System.out
+              .println("TestListener set to PORT=" + HttpServer.getPort());
+    }
+
     // Move any new getdown-launcher-new.jar into place over old
     // getdown-launcher.jar
     String appdirString = System.getProperty("getdownappdir");
diff --git a/src/jalview/gbtest/TestListener.java b/src/jalview/gbtest/TestListener.java
new file mode 100644 (file)
index 0000000..8ba80db
--- /dev/null
@@ -0,0 +1,82 @@
+package jalview.gbtest;
+
+import java.io.IOException;
+import java.net.BindException;
+import java.net.URI;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import jalview.bin.Cache;
+import jalview.gui.Desktop;
+import jalview.gui.SequenceFetcher;
+import jalview.httpserver.AbstractRequestHandler;
+import jalview.structure.SelectionSource;
+import jalview.util.DBRefUtils;
+
+public class TestListener extends AbstractRequestHandler
+        implements SelectionSource
+{
+
+  private String MY_PATH = "TEST";
+
+  /**
+   * Constructor that registers this as an Http request handler on path
+   * /chimeraN, where N is incremented for each instance. Call getUri to get the
+   * resulting URI for this handler.
+   * 
+   * @param chimeraBinding
+   * @throws BindException
+   *           if no free port can be assigned
+   */
+  public TestListener() throws BindException
+  {
+    setPath(MY_PATH);
+    registerHandler();
+  }
+
+  @Override
+  protected void processRequest(HttpServletRequest request,
+          HttpServletResponse response) throws IOException
+  {
+    dumpRequest(request);
+
+    URI reqUri = URI.create(request.getRequestURI());
+
+    Cache.warn("*** request.getRequestURI()=" + request.getRequestURI());
+    Cache.warn("*** reqUri=" + reqUri.toASCIIString());
+    Cache.warn("*** request.getContextPath()=" + request.getContextPath());
+    Cache.warn("*** request.getPathInfo()=" + request.getPathInfo());
+
+    String pathInfo = request.getPathInfo();
+    Cache.warn("*** pathInfo=" + pathInfo);
+    String viewgene = "viewgene";
+    if (pathInfo.startsWith("/" + viewgene + "/"))
+    {
+
+      String temp = pathInfo.substring(viewgene.length() + 2);
+      String ensemblId = temp.indexOf("/") > -1
+              ? temp.substring(0, temp.indexOf("/"))
+              : temp;
+      Cache.warn("*** temp=" + temp);
+      Cache.warn("*** ensemblId=" + ensemblId);
+
+      String db = DBRefUtils.getCanonicalName("ensembl");
+      Desktop desktop = Desktop.instance;
+      SequenceFetcher sf = new SequenceFetcher(desktop, db, ensemblId);
+      sf.ok_actionPerformed();
+
+    }
+
+  }
+
+  /**
+   * Returns a display name for this service
+   */
+  @Override
+  public String getName()
+  {
+    return "TestListener";
+  }
+
+}
index a18d38d..397f1a8 100644 (file)
@@ -20,8 +20,6 @@
  */
 package jalview.httpserver;
 
-import jalview.rest.RestHandler;
-
 import java.net.BindException;
 import java.net.URI;
 import java.util.Collections;
@@ -31,6 +29,7 @@ import java.util.Map;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.eclipse.jetty.server.Connector;
 import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.Server;
 import org.eclipse.jetty.server.ServerConnector;
@@ -38,6 +37,8 @@ import org.eclipse.jetty.server.handler.ContextHandler;
 import org.eclipse.jetty.server.handler.HandlerCollection;
 import org.eclipse.jetty.util.thread.QueuedThreadPool;
 
+import jalview.rest.RestHandler;
+
 /**
  * An HttpServer built on Jetty. To use it
  * <ul>
@@ -82,6 +83,14 @@ public class HttpServer
    */
   private URI contextRoot;
 
+  /*
+   * The port of the server.  This can be set before starting the instance
+   * as a suggested port to use (it is not guaranteed).
+   * The value will be set to the actual port being used after the instance
+   * is started.
+   */
+  private static int PORT = 0;
+
   /**
    * Returns the singleton instance of this class.
    * 
@@ -126,8 +135,9 @@ public class HttpServer
     try
     {
       /*
-       * Create a server with a small number of threads; jetty will allocate a
-       * free port
+       * Create a server with a small number of threads;
+       * If PORT has been set then jetty will try and use this, otherwise
+       * jetty will allocate a free port
        */
       QueuedThreadPool tp = new QueuedThreadPool(4, 1); // max, min
       server = new Server(tp);
@@ -135,6 +145,10 @@ public class HttpServer
       ServerConnector connector = new ServerConnector(server, 0, 2);
       // restrict to localhost
       connector.setHost("localhost");
+      if (PORT > 0)
+      {
+        connector.setPort(PORT);
+      }
       server.addConnector(connector);
 
       /*
@@ -150,6 +164,15 @@ public class HttpServer
       contextHandlers = new HandlerCollection(true);
       server.setHandler(contextHandlers);
       server.start();
+      Connector[] cs = server.getConnectors();
+      if (cs.length > 0)
+      {
+        if (cs[0] instanceof ServerConnector)
+        {
+          ServerConnector c = (ServerConnector) cs[0];
+          PORT = c.getPort();
+        }
+      }
       // System.out.println(String.format(
       // "HttpServer started with %d threads", server.getThreadPool()
       // .getThreads()));
@@ -297,4 +320,27 @@ public class HttpServer
               + " handler on " + handler.getUri());
     }
   }
+
+  /**
+   * This sets the "suggested" port to use. It can only be called once before
+   * starting the HttpServer instance. After the server has actually started the
+   * port is set to the actual port being used and cannot be changed.
+   * 
+   * @param port
+   * @return successful change
+   */
+  public static boolean setSuggestedPort(int port)
+  {
+    if (port < 1 || PORT > 0)
+    {
+      return false;
+    }
+    PORT = port;
+    return true;
+  }
+
+  public static int getPort()
+  {
+    return PORT;
+  }
 }