[Mulgara-svn] r1479 - in trunk: conf src/jar/server/java/org/mulgara/server src/jar/util/java/org/mulgara/util/functional

pag at mulgara.org pag at mulgara.org
Sat Feb 7 02:21:09 UTC 2009


Author: pag
Date: 2009-02-06 18:21:08 -0800 (Fri, 06 Feb 2009)
New Revision: 1479

Modified:
   trunk/conf/mulgara-config.xml
   trunk/conf/mulgara-embedded.dtd
   trunk/conf/mulgara-embedded.xsd
   trunk/src/jar/server/java/org/mulgara/server/EmbeddedMulgaraOptionParser.java
   trunk/src/jar/server/java/org/mulgara/server/EmbeddedMulgaraServer.java
   trunk/src/jar/server/java/org/mulgara/server/HttpServices.java
   trunk/src/jar/server/java/org/mulgara/server/ServerInfo.java
   trunk/src/jar/util/java/org/mulgara/util/functional/Pair.java
Log:
Added options to start up and configure a public SPARQL endpoint, for read-only access by the public

Modified: trunk/conf/mulgara-config.xml
===================================================================
--- trunk/conf/mulgara-config.xml	2009-02-07 02:19:39 UTC (rev 1478)
+++ trunk/conf/mulgara-config.xml	2009-02-07 02:21:08 UTC (rev 1479)
@@ -28,12 +28,21 @@
   <Jetty>
     <Disabled>false</Disabled>
     <Connector>
+      <Disabled>false</Disabled>
       <!--<Host>localhost</Host>-->
       <Port>8080</Port>
       <Acceptors>5</Acceptors>
       <MaxIdleTimeMs>60000</MaxIdleTimeMs>
       <LowResourceMaxIdleTimeMs>5000</LowResourceMaxIdleTimeMs>
     </Connector>
+    <PublicConnector>
+      <Disabled>false</Disabled>
+      <!--<Host>localhost</Host>-->
+      <Port>8081</Port>
+      <Acceptors>5</Acceptors>
+      <MaxIdleTimeMs>60000</MaxIdleTimeMs>
+      <LowResourceMaxIdleTimeMs>5000</LowResourceMaxIdleTimeMs>
+    </PublicConnector>
   </Jetty>
 
   <!-- The name of the server, used for RMI binding -->

Modified: trunk/conf/mulgara-embedded.dtd
===================================================================
--- trunk/conf/mulgara-embedded.dtd	2009-02-07 02:19:39 UTC (rev 1478)
+++ trunk/conf/mulgara-embedded.dtd	2009-02-07 02:21:08 UTC (rev 1479)
@@ -7,9 +7,10 @@
 
   <!ELEMENT MulgaraHost (#PCDATA)>
 
-  <!ELEMENT Jetty (Connector)>
+  <!ELEMENT Jetty (Connector, PublicConnector)>
 
-    <!ELEMENT Connector (Host?, Port, Acceptors?, MaxIdleTimeMs?, LowResourceMaxIdleTimeMs?)>
+    <!ELEMENT Connector (Disabled?, Host?, Port, Acceptors?, MaxIdleTimeMs?, LowResourceMaxIdleTimeMs?)>
+    <!ELEMENT PublicConnector (Disabled?, Host?, Port, Acceptors?, MaxIdleTimeMs?, LowResourceMaxIdleTimeMs?)>
 
       <!ELEMENT Host (#PCDATA)>
       <!ELEMENT Port (#PCDATA)>

Modified: trunk/conf/mulgara-embedded.xsd
===================================================================
--- trunk/conf/mulgara-embedded.xsd	2009-02-07 02:19:39 UTC (rev 1478)
+++ trunk/conf/mulgara-embedded.xsd	2009-02-07 02:21:08 UTC (rev 1479)
@@ -14,12 +14,14 @@
       <xs:sequence>
         <xs:element name="Disabled" type="xs:boolean" minOccurs="0"/>
         <xs:element ref="Connector" minOccurs="0"/>
+        <xs:element ref="PublicConnector" minOccurs="0"/>
       </xs:sequence>
     </xs:complexType>
   </xs:element>
   <xs:element name="Connector">
     <xs:complexType>
       <xs:sequence>
+        <xs:element name="Disabled" type="xs:boolean" minOccurs="0"/>
         <xs:element ref="Host" minOccurs="0"/>
         <xs:element ref="Port"/>
         <xs:element ref="Acceptors" minOccurs="0"/>
@@ -28,6 +30,18 @@
       </xs:sequence>
     </xs:complexType>
   </xs:element>
+  <xs:element name="PublicConnector">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name="Disabled" type="xs:boolean" minOccurs="0"/>
+        <xs:element ref="Host" minOccurs="0"/>
+        <xs:element ref="Port"/>
+        <xs:element ref="Acceptors" minOccurs="0"/>
+        <xs:element ref="MaxIdleTimeMs" minOccurs="0"/>
+        <xs:element ref="LowResourceMaxIdleTimeMs" minOccurs="0"/>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
   <xs:element name="LowResourceMaxIdleTimeMs" type="xs:int"/>
   <xs:element name="MaxIdleTimeMs" type="xs:int"/>
   <xs:element name="Acceptors" type="xs:int"/>

Modified: trunk/src/jar/server/java/org/mulgara/server/EmbeddedMulgaraOptionParser.java
===================================================================
--- trunk/src/jar/server/java/org/mulgara/server/EmbeddedMulgaraOptionParser.java	2009-02-07 02:19:39 UTC (rev 1478)
+++ trunk/src/jar/server/java/org/mulgara/server/EmbeddedMulgaraOptionParser.java	2009-02-07 02:21:08 UTC (rev 1479)
@@ -75,9 +75,12 @@
   /** option to change to the peer client port for RMI */
   public final static Option RMI_OBJECT_PORT = new IntegerOption('t', "rmiobjectport");
 
-  /** option to change the port the server is bound to */
+  /** option to change the port the http server is bound to */
   public final static Option PORT = new StringOption('p', "port");
 
+  /** option to change the public port the http server is bound to */
+  public final static Option PUBLIC_PORT = new StringOption('u', "publicport");
+
   /** option to change the name of the server */
   public final static Option SERVER_NAME = new StringOption('s', "servername");
 
@@ -118,6 +121,7 @@
     addOption(NO_HTTP);
     addOption(SERVER_HOST);
     addOption(PORT);
+    addOption(PUBLIC_PORT);
     addOption(NO_RMI);
     addOption(RMI_PORT);
     addOption(RMI_OBJECT_PORT);

Modified: trunk/src/jar/server/java/org/mulgara/server/EmbeddedMulgaraServer.java
===================================================================
--- trunk/src/jar/server/java/org/mulgara/server/EmbeddedMulgaraServer.java	2009-02-07 02:19:39 UTC (rev 1478)
+++ trunk/src/jar/server/java/org/mulgara/server/EmbeddedMulgaraServer.java	2009-02-07 02:21:08 UTC (rev 1479)
@@ -47,6 +47,7 @@
 // locally written packages
 import org.mulgara.config.MulgaraConfig;
 import org.mulgara.config.Connector;
+import org.mulgara.config.PublicConnector;
 import org.mulgara.server.SessionFactory;
 import org.mulgara.store.StoreException;
 import org.mulgara.store.xa.SimpleXAResourceException;
@@ -563,6 +564,7 @@
         if (System.getProperty(DISABLE_HTTP) == null && !mulgaraConfig.getJetty().getDisabled()) {
           httpEnabled = true;
           Connector httpConnector = mulgaraConfig.getJetty().getConnector();
+          PublicConnector httpPublicConnector = mulgaraConfig.getJetty().getPublicConnector();
     
           String httpHost = (String)parser.getOptionValue(EmbeddedMulgaraOptionParser.HTTP_HOST);
           httpHostName = (httpHost != null || httpConnector == null) ? httpHost : httpConnector.getHost();
@@ -574,6 +576,14 @@
           } else {
             if (httpConnector != null) ServerInfo.setHttpPort(httpConnector.getPort());
           }
+
+          // set the port on which to accept public HTTP requests
+          httpPort = (String)parser.getOptionValue(EmbeddedMulgaraOptionParser.PUBLIC_PORT);
+          if (httpPort != null) {
+            ServerInfo.setPublicHttpPort(Integer.parseInt(httpPort));
+          } else {
+            if (httpPublicConnector != null) ServerInfo.setPublicHttpPort(httpPublicConnector.getPort());
+          }
         } else {
           httpEnabled = false;
           httpHostName = "";

Modified: trunk/src/jar/server/java/org/mulgara/server/HttpServices.java
===================================================================
--- trunk/src/jar/server/java/org/mulgara/server/HttpServices.java	2009-02-07 02:19:39 UTC (rev 1478)
+++ trunk/src/jar/server/java/org/mulgara/server/HttpServices.java	2009-02-07 02:21:08 UTC (rev 1479)
@@ -23,6 +23,7 @@
 import java.net.URL;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -41,6 +42,7 @@
 import org.mortbay.util.MultiException;
 import org.mulgara.config.Connector;
 import org.mulgara.config.MulgaraConfig;
+import org.mulgara.config.PublicConnector;
 import org.mulgara.util.MortbayLogger;
 import org.mulgara.util.Reflect;
 import org.mulgara.util.TempDir;
@@ -103,6 +105,9 @@
   /** The HTTP server instance. */
   private final Server httpServer;
 
+  /** The Public HTTP server instance. */
+  private final Server httpPublicServer;
+
   /** The configuration for the server. */
   private final MulgaraConfig config;
 
@@ -129,7 +134,11 @@
     this.hostServer = hostServer;
     this.config = config;
     this.hostName = hostName;
-    httpServer = createHttpServer();
+    assert !config.getJetty().isDisabled();
+    // get servers as a pair so we can set them here. Needed because they are final.
+    Pair<Server,Server> servers = createHttpServers();
+    httpServer = servers.first();
+    httpPublicServer = servers.second();
   }
 
 
@@ -141,7 +150,8 @@
   @SuppressWarnings("unchecked")
   public void start() throws ExceptionList, Exception {
     try {
-      httpServer.start();
+      if (httpServer != null) httpServer.start();
+      if (httpPublicServer != null) httpPublicServer.start();
     } catch (MultiException e) {
       throw new ExceptionList(e.getThrowables());
     }
@@ -153,13 +163,17 @@
    * @throws Exception Both the server and the services are able to throw exceptions.
    */
   public void stop() throws Exception {
-    httpServer.stop();
+    try {
+      if (httpServer != null) httpServer.stop();
+    } finally {
+      if (httpPublicServer != null) httpPublicServer.stop();
+    }
   }
 
 
   /**
    * Creates an HTTP server.
-   * @return an HTTP server
+   * @return a pair of private/public servers.
    * @throws IOException if the server configuration cannot be found
    * @throws SAXException if the HTTP server configuration file is invalid
    * @throws ClassNotFoundException if the HTTP server configuration file contains a reference to an unkown class
@@ -167,30 +181,24 @@
    * @throws InvocationTargetException if an error ocurrs while trying to configure the HTTP server
    * @throws IllegalAccessException If a class loaded by the server is accessed in an unexpected way.
    */
-  public Server createHttpServer() throws IOException, SAXException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+  public Pair<Server,Server> createHttpServers() throws IOException, SAXException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
     if (logger.isDebugEnabled()) logger.debug("Creating HTTP server instance");
 
     // Set the magic logging property for Jetty to use Log4j
     System.setProperty(MortbayLogger.LOGGING_CLASS_PROPERTY, MortbayLogger.class.getCanonicalName());
 
     // create and register a new HTTP server
-    Server server;
-    if (config.getJetty().getConnector() == null) {
-      // create a default server
-      server = new Server(ServerInfo.getHttpPort());
-    } else {
-      // create a server with a configured connector
-      server = new Server();
-      addConnector(server);
-    }
+    Server privateServer = buildAndConfigure(new JettyConnector(config.getJetty().getConnector()), ServerInfo.getHttpPort());
+    Server publicServer = buildAndConfigure(new JettyConnector(config.getJetty().getPublicConnector()), ServerInfo.getPublicHttpPort());
 
+
     // Accumulator for all the services
-    Map<String,String> services = new HashMap<String,String>();
+    Map<String,String> privateServices = new HashMap<String,String>();
 
-    // start all the configured services.
+    // start all the private configured services.
     for (ContextStarter starter: getContextStarters()) {
       try {
-        starter.fn(server).add(services);
+        starter.fn(privateServer).addTo(privateServices);
       } catch (IllegalStateException e) {
         // not fatal, so just log the problem and go on
         logger.warn("Unable to start web service", e.getCause());
@@ -198,21 +206,52 @@
     }
 
     // we have all the services, so now instantiate the service listing service
-    addWebServiceListingContext(server, services);
+    addWebServiceListingContext(privateServer, privateServices);
 
+    // start the public contexts
+    for (ContextStarter starter: getPublicContextStarters()) {
+      try {
+        starter.fn(publicServer);
+      } catch (IllegalStateException e) {
+        logger.warn("Unable to start public web service", e.getCause());
+      }
+    }
+
+    // get all the handlers in use by both servers
+    List<Handler> handlers = new ArrayList<Handler>(Arrays.asList(privateServer.getChildHandlers()));
+    handlers.addAll(Arrays.asList(publicServer.getChildHandlers()));
+
     // add our class loader as the classloader of all contexts, unless this is a webapp in which case we wrap it
     ClassLoader classLoader = this.getClass().getClassLoader();
-    for (Handler handler: server.getChildHandlers()) {
+    for (Handler handler: handlers) {
       if (handler instanceof WebAppContext) ((WebAppContext)handler).setClassLoader(new WebAppClassLoader(classLoader, (WebAppContext)handler));
       else if (handler instanceof ContextHandler) ((ContextHandler)handler).setClassLoader(classLoader);
     }
 
-    // return the server
-    return server;
+    // return the servers
+    return new Pair<Server,Server>(privateServer, publicServer);
   }
 
 
   /**
+   * Create a server object, and configure it.
+   * @param cfg The Jetty configuration for the server.
+   * @return The created server.
+   * @throws UnknownHostException The configured host name is invalid.
+   */
+  Server buildAndConfigure(JettyConnector cfg, int port) throws UnknownHostException {
+    Server s;
+    if (cfg.isProvided()) {
+      s = new Server(port);
+    } else {
+      s = new Server();
+      addConnector(s, cfg);
+    }
+    return s;
+  }
+
+
+  /**
    * Creates a list of functions for starting contexts.
    * <strong>This defines the list of services to be run.</strong>
    * @return A list that can start all the configured contexts.
@@ -241,12 +280,26 @@
 
 
   /**
+   * Creates a list of functions for starting public contexts.
+   * <strong>This defines the list of services to be run.</strong>
+   * @return A list that can start all the configured contexts.
+   */
+  private List<ContextStarter> getPublicContextStarters() {
+    List<ContextStarter> starters = new ArrayList<ContextStarter>();
+    starters.add(new ContextStarter() { public Service fn(Server s) throws IOException {
+      return addServletContext(s, "org.mulgara.protocol.http.PublicSparqlServlet", SPARQL_PATH, "SPARQL HTTP Service");
+    } });
+    return starters;
+  }
+
+
+  /**
    * Adds a listener to the <code>httpServer</code>. The listener is created and configured
    * according to the Jetty configuration.
    * @param httpServer the server to add the listener to
    * @throws UnknownHostException if an invalid hostname was specified in the Mulgara server configuration
    */
-  private void addConnector(Server httpServer) throws UnknownHostException {
+  private void addConnector(Server httpServer, JettyConnector jettyConfig) throws UnknownHostException {
     if (httpServer == null) throw new IllegalArgumentException("Null \"httpServer\" parameter");
 
     if (logger.isDebugEnabled()) logger.debug("Adding socket listener");
@@ -261,10 +314,8 @@
       if (logger.isDebugEnabled()) logger.debug("Servlet container listening on all host interfaces");
     }
 
-    // set the listener to the jetty configuration
-    Connector jettyConfig = (Connector)config.getJetty().getConnector();
-    connector.setPort(ServerInfo.getHttpPort());
 
+    if (jettyConfig.hasPort()) connector.setPort(jettyConfig.getPort());
     if (jettyConfig.hasMaxIdleTimeMs()) connector.setMaxIdleTime(jettyConfig.getMaxIdleTimeMs());
     if (jettyConfig.hasLowResourceMaxIdleTimeMs()) connector.setLowResourceMaxIdleTime(jettyConfig.getLowResourceMaxIdleTimeMs());
     if (jettyConfig.hasAcceptors()) {
@@ -398,4 +449,108 @@
     return outFile.getAbsolutePath();
   }
 
+
+  /**
+   * A common class for representing the identical configuration found in the
+   * separate Connector and PublicConnector classes.
+   */
+  private class JettyConnector {
+    boolean provided = false;
+    Boolean disabled = null;
+    String host = null;
+    Integer port = null;
+    Integer acceptors = null;
+    Integer maxIdleTimeMs = null;
+    Integer lowResourceMaxIdleTimeMs = null;
+
+    /**
+     * Creates a config from a Connector object.
+     * @param c The Connector to build the config from.
+     */
+    public JettyConnector(Connector c) {
+      if (c == null) return;
+      provided = true;
+      if (c.hasDisabled()) disabled = c.isDisabled();
+      host = c.getHost();
+      if (c.hasPort()) port = c.getPort();
+      if (c.hasAcceptors()) acceptors = c.getAcceptors();
+      if (c.hasMaxIdleTimeMs()) maxIdleTimeMs = c.getMaxIdleTimeMs();
+      if (c.hasLowResourceMaxIdleTimeMs()) lowResourceMaxIdleTimeMs = c.getLowResourceMaxIdleTimeMs();
+    }
+
+    /**
+     * Creates a config from a PublicConnector object.
+     * @param c The PublicConnector to build the config from.
+     */
+    public JettyConnector(PublicConnector c) {
+      if (c == null) return;
+      provided = true;
+      if (c.hasDisabled()) disabled = c.isDisabled();
+      host = c.getHost();
+      if (c.hasPort()) port = c.getPort();
+      if (c.hasAcceptors()) acceptors = c.getAcceptors();
+      if (c.hasMaxIdleTimeMs()) maxIdleTimeMs = c.getMaxIdleTimeMs();
+      if (c.hasLowResourceMaxIdleTimeMs()) lowResourceMaxIdleTimeMs = c.getLowResourceMaxIdleTimeMs();
+    }
+
+    /** @return if this config was provided. */
+    public boolean isProvided() {
+      return provided;
+    }
+
+    /** @return if this config is disabled or not. */
+    public boolean isDisabled() {
+      return disabled;
+    }
+
+    /** @return the host name */
+    public String getHost() {
+      return host;
+    }
+
+    /** @return the port to use */
+    public int getPort() {
+      return port;
+    }
+
+    /** @return the number of acceptors to use */
+    public int getAcceptors() {
+      return acceptors;
+    }
+
+    /** @return the maxIdleTimeMs */
+    public int getMaxIdleTimeMs() {
+      return maxIdleTimeMs;
+    }
+
+    /** @return the lowResourceMaxIdleTimeMs */
+    public int getLowResourceMaxIdleTimeMs() {
+      return lowResourceMaxIdleTimeMs;
+    }
+
+    /** @return <code>true</code> if the Disabled value was provided. */
+    public boolean hasDisabled() {
+      return disabled != null;
+    }
+
+    /** @return <code>true</code> if the Port value was provided. */
+    public boolean hasPort() {
+      return port != null;
+    }
+
+    /** @return <code>true</code> if the Accepted value was provided. */
+    public boolean hasAcceptors() {
+      return acceptors != null;
+    }
+
+    /** @return <code>true</code> if the MaxIdelTimeMs value was provided. */
+    public boolean hasMaxIdleTimeMs() {
+      return maxIdleTimeMs != null;
+    }
+
+    /** @return <code>true</code> if the LogResourceMaxIdeTimeMs value was provided. */
+    public boolean hasLowResourceMaxIdleTimeMs() {
+      return lowResourceMaxIdleTimeMs != null;
+    }
+  }
 }

Modified: trunk/src/jar/server/java/org/mulgara/server/ServerInfo.java
===================================================================
--- trunk/src/jar/server/java/org/mulgara/server/ServerInfo.java	2009-02-07 02:19:39 UTC (rev 1478)
+++ trunk/src/jar/server/java/org/mulgara/server/ServerInfo.java	2009-02-07 02:21:08 UTC (rev 1479)
@@ -75,6 +75,9 @@
   /** The port used for HTTP. */
   private static int httpPort = 8080;
 
+  /** The port used for public HTTP. */
+  private static int publicHttpPort = 8081;
+
   /** The set of hostname aliases. */
   private static Set<String> hostnames = new HashSet<String>();
 
@@ -149,6 +152,16 @@
 
 
   /**
+   * Returns the port the public HTTP server is bound to.
+   *
+   * @return the port the public HTTP server is bound to
+   */
+  public static int getPublicHttpPort() {
+    return publicHttpPort;
+  }
+
+
+  /**
    * Returns the set of host name aliases for the server.
    *
    * @return the set of host names
@@ -222,9 +235,20 @@
    * @param httpPort the port the HTTP server is bound to
    */
   static void setHttpPort(int httpPort) {
+    if (httpPort == ServerInfo.publicHttpPort) throw new IllegalArgumentException("Public and private HTTP ports cannot be the same");
     ServerInfo.httpPort = httpPort;
   }
 
+  /**
+   * Sets the port the public HTTP server is bound to.
+   *
+   * @param publicHttpPort the port the public HTTP server is bound to
+   */
+  static void setPublicHttpPort(int publicHttpPort) {
+    if (publicHttpPort == ServerInfo.httpPort) throw new IllegalArgumentException("Public and private HTTP ports cannot be the same");
+    ServerInfo.publicHttpPort = publicHttpPort;
+  }
+
   public static String toStaticString() {
     StringBuilder s = new StringBuilder();
     s.append("Server URI = ").append(serverURI).append("\n");
@@ -234,6 +258,7 @@
     s.append("Bound host name = ").append(boundHostname).append("\n");
     s.append("RMI Port = ").append(rmiPort).append("\n");
     s.append("HTTP Port = ").append(httpPort).append("\n");
+    s.append("Public HTTP Port = ").append(publicHttpPort).append("\n");
     s.append("Host names = ").append(hostnames).append("\n");
     return s.toString();
   }

Modified: trunk/src/jar/util/java/org/mulgara/util/functional/Pair.java
===================================================================
--- trunk/src/jar/util/java/org/mulgara/util/functional/Pair.java	2009-02-07 02:19:39 UTC (rev 1478)
+++ trunk/src/jar/util/java/org/mulgara/util/functional/Pair.java	2009-02-07 02:21:08 UTC (rev 1479)
@@ -45,5 +45,5 @@
 
   public static <C1,C2> Pair<C1,C2> p(C1 c1, C2 c2) { return new Pair<C1,C2>(c1, c2); }
 
-  public Map<T1,T2> add(Map<T1,T2> map) { map.put(first, second); return map; }
+  public Map<T1,T2> addTo(Map<T1,T2> map) { map.put(first, second); return map; }
 }




More information about the Mulgara-svn mailing list