All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bigdata.rdf.sail.webapp.NanoSparqlServer Maven / Gradle / Ivy

/**

Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.

Contact:
     SYSTAP, LLC DBA Blazegraph
     2501 Calvert ST NW #106
     Washington, DC 20008
     [email protected]

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
package com.bigdata.rdf.sail.webapp;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.SocketException;
import java.net.URL;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import javax.servlet.ServletContextListener;

import org.apache.log4j.Logger;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.xml.XmlConfiguration;

import com.bigdata.Banner;
import com.bigdata.journal.IIndexManager;
import com.bigdata.journal.ITx;
import com.bigdata.journal.Journal;
import com.bigdata.journal.TimestampUtility;
import com.bigdata.resources.IndexManager;
import com.bigdata.util.config.NicUtil;
import com.bigdata.util.httpd.Config;

/**
 * Utility class provides a simple SPARQL end point with a REST API.
 * 
 * @author thompsonbry
 * @author martyncutcher
 * 
 * @see 
 *      NanoSparqlServer  on the wiki.
 * 
 * @see  Jetty
 *      Documentation 
 * 
 * @see 
 *      Jetty XML Reference 
 * 
 * @see 
 *      Embedding Jetty 
 * 
 * @todo If the addressed instance uses full transactions, then mutation should
 *       also use a full transaction. Does it?
 * 
 * @todo Remote command to advance the read-behind point. This will let people
 *       bulk load a bunch of stuff before advancing queries to read from the
 *       new consistent commit point.
 */
public class NanoSparqlServer {
    
    static private final Logger log = Logger.getLogger(NanoSparqlServer.class);

    public interface SystemProperties {

        /**
         * The name of the system property that can be used to override the default
         * HTTP port in the bundled jetty.xml file.
         */
        String JETTY_PORT = "jetty.port";
        
        /**
         * The name of the system property that can be used to override the
         * location of the jetty.xml file that will be used to
         * configure jetty (default {@value #DEFAULT_JETTY_XML}).
         * 
         * @see 
         *      Allow configuration of embedded NSS jetty server using
         *      jetty-web.xml 
         * 
         * @see #DEFAULT_JETTY_XML
         */
        String JETTY_XML = "jettyXml";

        /**
         * The default value works when deployed under the IDE with the
         * bigdata-war/src directory on the classpath. When
         * deploying outside of that context, the value needs to be set
         * explicitly.
         */
        String DEFAULT_JETTY_XML = "jetty.xml";

        /**
         * The timeout in seconds that we will await the start of the jetty
         * {@link Server} (default {@value #DEFAULT_JETTY_START_TIMEOUT}).
         */
        String JETTY_STARTUP_TIMEOUT = "jetty.start.timeout";

        String DEFAULT_JETTY_STARTUP_TIMEOUT = "10";

        /**
         * When true, the state of jetty will be dumped onto a
         * logger after the server start.
         */
        String JETTY_DUMP_START = "jetty.dump.start";
        
        /**
         * This property specifies the resource path for the web application. In
         * order for this mechanism to work, the jetty.xml file
         * MUST contain a line which allows the resourceBase of the web
         * application to be set from an environment variable. For example:
         * 
         * 
         * <SystemProperty name="jetty.resourceBase" default="bigdata-war/src" />
         * 
* * The jetty.resourceBase variable may identify either a * file or a resource on the class path. To force the use of the web * application embedded within the bigdata.jar you need to * specify a JAR URL along the following lines (using the appropriate * file path and jar name and version: * *
         * jar:file:../lib/bigdata-1.3.0.jar!/bigdata-war/src
         * 
* * The use of absolute file paths are recommended for reliable * resolution. *

* The order of preference is: *

    *
  1. jetty.resourceBase is specified. The value of this * environment variable will be used to locate the web application.
  2. *
  3. * jetty.resourceBase is not specified (either * null or whitespace). *
      *
    1. An attempt is made to locate the bigdata-war/src * resource in the file system (relative to the current working * directory). If found, the jetty.resourceBase environment * variable is set to this resource using a file: style * URL. This will cause jetty to use the web application directory in * the file system.
    2. *
    3. * An attempt is made to locate the resource * /WEB-INF/web.xml using the classpath (this handles the * case when running under the eclipse IDE). If found, the the * jetty.resourceBase is set to the URL formed by removing * the trailing WEB-INF/web.xml for the located resource. * This will cause jetty to use the web application resource on the * classpath. If there are multiple such resources on the classpath, the * first such resource will be discovered and used.
    4. *
    5. An attempt is made to locate the resource * bigdata-war/src/main/webapp/WEB-INF/web.xml using the classpath * (this handles the case when running from the command line using a * bigdata JAR). If found, the the jetty.resourceBase is * set to the URL formed by the trailing WEB-INF/web.xml * for the located resource. This will cause jetty to use the web * application resource on the classpath. If there are multiple such * resources on the classpath, the first such resource will be * discovered and used.
    6. *
    7. * Otherwise, the jetty.resourceBase environment variable * is not modified and the default location specified in the * jetty.xml file will be used. If jetty is unable to * resolve that resource, then the web application will not start.
    8. *
    *
* * @see NSS does not * start from command line: bigdata-war/src not found */ String JETTY_RESOURCE_BASE = "jetty.resourceBase"; /** * The location of the override-web.xml resource. The * default is given in jetty.xml and serves to locate the * resource when deployed under an IDE. If not explicitly given, value * of the environment variable is set by the same logic that sets the * {@link #JETTY_RESOURCE_BASE} environment variable. This allows the * override-web.xml resource to be found in its default * location (which is the same directory / package as the * web.xml file) while still preserving the ability to * override the location of that resource explicitly by setting the * environment variable before starting the server. * * @see ProxyServlet in * web.xml breaks tomcat WAR (HA LBS) */ String JETTY_OVERRIDE_WEB_XML = "jetty.overrideWebXml"; /** * The location to over propertyFile used to create the servlet. This * to allow overriding the default value via passing a Java Property at * the command line. */ String BIGDATA_PROPERTY_FILE = "bigdata.propertyFile"; /** * The jetty.home property. */ String JETTY_HOME = "jetty.home"; } /** * Run an httpd service exposing a SPARQL endpoint. The service will respond * to the following URL paths: *
*
http://localhost:port/
*
The SPARQL end point for the default namespace as specified by the * namespace command line argument.
*
http://localhost:port/namespace/NAMESPACE
*
where NAMESPACE is the namespace of some triple store or * quad store, may be used to address ANY triple or quads store in the * bigdata instance.
*
http://localhost:port/status
*
A status page.
*
* * @param args * USAGE:
* To start the server:
* (options) port namespace (propertyFile|configFile) ) *

* Where: *

*
port
*
The port on which the service will respond -or- * 0 to use any open port.
*
namespace
*
The namespace of the default SPARQL endpoint (the * namespace will be kb if none was specified when * the triple/quad store was created).
*
propertyFile
*
A java properties file for a standalone {@link Journal}.
*
configFile
*
A jini configuration file for a bigdata federation.
*
* and options are any of: *
*
-jettyXml
*
The location of the jetty.xml resource that will be used * to start the {@link Server} (default is the file in the JAR). * The default will locate the jetty.xml resource * that is bundled with the JAR. This preserves the historical * behavior. If you want to use a different * jetty.xml file, just override this property on * the command line -or- specify the * {@link NanoSparqlServer.SystemProperties#JETTY_XML} system * property.
*
-nthreads
*
The #of threads which will be used to answer SPARQL * queries (default * {@value ConfigParams#DEFAULT_QUERY_THREAD_POOL_SIZE}).
*
-forceOverflow
*
Force a compacting merge of all shards on all data * services in a bigdata federation (this option should only be * used for benchmarking purposes).
*
-readLock
*
The commit time against which the server will assert a * read lock by holding open a read-only transaction against that * commit point OR -1 (MINUS ONE) to assert a read * lock against the last commit point. When given, queries will * default to read against this commit point. Otherwise queries * will default to read against the most recent commit point on * the database. Regardless, each query will be issued against a * read-only transaction. *
-servletContextListenerClass
*
The name of a class that extends * {@link BigdataRDFServletContextListener}. This allows you to * hook the {@link ServletContextListener} events.
*
*

*/ // *
bufferCapacity [#bytes]
// *
Specify the capacity of the buffers used to decouple the // * query evaluation from the consumption of the HTTP response by // * the client. The capacity may be specified in bytes or // * kilobytes, e.g., 5k.
public static void main(final String[] args) throws Exception { Banner.banner(); int port = 80; String namespace = "kb"; int queryThreadPoolSize = ConfigParams.DEFAULT_QUERY_THREAD_POOL_SIZE; boolean forceOverflow = false; Long readLock = null; /* * Note: This default will locate the jetty.xml resource that is bundled * with the JAR. This preserves the historical behavior. If you want to * use a different jetty.xml file, just override this property on the * command line. */ String jettyXml = System.getProperty(// SystemProperties.JETTY_XML,// "jetty.xml"// // SystemProperties.DEFAULT_JETTY_XML ); // Set the resource base to inside of the jar file if jetty.home is not set // This is for running as the executable jar if (System.getProperty(SystemProperties.JETTY_HOME) == null) { final URL jettyJarXml = jettyXml.getClass().getResource("/war"); System.setProperty(SystemProperties.JETTY_HOME, jettyJarXml.toExternalForm()); // Also set the Jetty Resource Base to this value, if it is not // configured. if (System.getProperty(SystemProperties.JETTY_RESOURCE_BASE) == null) { System.setProperty(SystemProperties.JETTY_RESOURCE_BASE, jettyJarXml.toExternalForm()); } } /* * Handle all arguments starting with "-". These should appear before * any non-option arguments to the program. */ int i = 0; while (i < args.length) { final String arg = args[i]; if (arg.startsWith("-")) { if (arg.equals("-forceOverflow")) { forceOverflow = true; } else if (arg.equals("-nthreads")) { final String s = args[++i]; queryThreadPoolSize = Integer.valueOf(s); if (queryThreadPoolSize < 0) { usage(1/* status */, "-nthreads must be non-negative, not: " + s); } } else if (arg.equals("-readLock")) { final String s = args[++i]; readLock = Long.valueOf(s); if (readLock != ITx.READ_COMMITTED && !TimestampUtility.isCommitTime(readLock .longValue())) { usage(1/* status */, "Read lock must be commit time or -1 (MINUS ONE) to assert a read lock on the last commit time: " + readLock); } } else if (arg.equals("-jettyXml")) { jettyXml = args[++i]; } else { usage(1/* status */, "Unknown argument: " + arg); } } else { break; } i++; } /* * Finally, there should be exactly THREE (3) command line arguments * remaining. These are the [port], the [namespace] and the * [propertyFile] (journal) or [configFile] (scale-out). */ final int nremaining = args.length - i; if (nremaining != 3) { /* * There are either too many or too few arguments remaining. */ usage(1/* status */, nremaining < 3 ? "Too few arguments." : "Too many arguments"); } /* * http service port. */ { final String s = args[i++]; try { port = Integer.valueOf(s); } catch (NumberFormatException ex) { usage(1/* status */, "Could not parse as port# : '" + s + "'"); } } /* * Namespace. */ namespace = args[i++]; // Note: This is checked by the ServletContextListener. // /* // * Property file. // */ final String propertyFile = args[i++]; //Through an Exception is the propertyFile does not exist. final File pFile = new File(propertyFile); if(!pFile.exists()) { final String errMsg = "Property or config file " + propertyFile + " does not exist and is a required parameter."; System.err.println(errMsg); log.error(errMsg); throw new RuntimeException(errMsg); } // final File file = new File(propertyFile); // if (!file.exists()) { // throw new RuntimeException("Could not find file: " + file); // } // boolean isJini = false; // if (propertyFile.endsWith(".config")) { // // scale-out. // isJini = true; // } else if (propertyFile.endsWith(".properties")) { // // local journal. // isJini = false; // } else { // /* // * Note: This is a hack, but we are recognizing the jini // * configuration file with a .config extension and the journal // * properties file with a .properties extension. // */ // usage(1/* status */, // "File should have '.config' or '.properties' extension: " // + file); // } /* * Setup the ServletContext properties. */ final Map initParams = new LinkedHashMap(); initParams.put( ConfigParams.PROPERTY_FILE, propertyFile); initParams.put(ConfigParams.NAMESPACE, namespace); initParams.put(ConfigParams.QUERY_THREAD_POOL_SIZE, Integer.toString(queryThreadPoolSize)); initParams.put( ConfigParams.FORCE_OVERFLOW, Boolean.toString(forceOverflow)); if (readLock != null) { initParams.put( ConfigParams.READ_LOCK, Long.toString(readLock)); } // Create the service. final Server server = NanoSparqlServer.newInstance(port, jettyXml, null/* indexManager */, initParams); awaitServerStart(server); // Wait for the service to terminate. server.join(); } /** * Await a {@link Server} start up to a timeout. * * @parma server The {@link Server} to start. * @throws InterruptedException * @throws TimeoutException * @throws Exception */ public static void awaitServerStart(final Server server) throws InterruptedException, TimeoutException, Exception { // Note: Does not appear to help. // // final WebAppContext wac = getWebApp(server); // // if (wac == null) // throw new Exception("WebApp is not available?"); final long timeout = Long.parseLong(System.getProperty( SystemProperties.JETTY_STARTUP_TIMEOUT, SystemProperties.DEFAULT_JETTY_STARTUP_TIMEOUT)); boolean ok = false; final long begin = System.nanoTime(); final long nanos = TimeUnit.SECONDS.toNanos(timeout); long remaining = nanos; try { // Start Server. log.warn("Starting NSS"); server.start(); // Await running. remaining = nanos - (System.nanoTime() - begin); while (server.isStarting() && !server.isRunning() /* && !wac.isRunning() */ && remaining > 0) { Thread.sleep(100/* ms */); // remaining = nanos - (now - begin) [aka elapsed] remaining = nanos - (System.nanoTime() - begin); } if (remaining < 0) { throw new TimeoutException(); } // if (!wac.isRunning()) // throw new Exception("WebApp is not running?"); ok = true; } finally { if (!ok) { // Complain if Server did not start. final String msg = "Server did not start."; System.err.println(msg); log.fatal(msg); if (server != null) { /* * Support the jetty dump-after-start semantics. */ if (Boolean.getBoolean(SystemProperties.JETTY_DUMP_START)) { log.warn(server.dump()); } server.stop(); server.destroy(); } } } /* * Support the jetty dump-after-start semantics. */ if (Boolean.getBoolean(SystemProperties.JETTY_DUMP_START)) { log.warn(server.dump()); } /* * Report *an* effective URL of this service. * * Note: This is an effective local URL (and only one of them, and even * then only one for the first connector). It does not reflect any * knowledge about the desired external deployment URL for the service * end point. */ final String serviceURL; { final int actualPort = getLocalPort(server); String hostAddr = getHost(); serviceURL = new URL("http", hostAddr, actualPort, ""/* file */) .toExternalForm(); final String msg = "serviceURL: " + serviceURL; System.out.println(msg); if (log.isInfoEnabled()) log.warn(msg); } } /** * Utility method to get the host for the currently running NSS. * If {@link NicUtil} returns a null pointer, it is set to the * value of {@link Config#DEFAULT_HOST}. * * @return The hostname for the running instance. * * @throws SocketException * @throws IOException */ protected static String getHost() throws SocketException, IOException { String hostAddr = NicUtil.getIpAddress("default.nic", "default", true/* loopbackOk */); if (hostAddr == null) { hostAddr = Config.DEFAULT_HOST; } return hostAddr; } /** * Start the embedded {@link Server}. *

* Note: The port override argument given here is applied by setting the * {@link NanoSparqlServer.SystemProperties#JETTY_PORT} System property. The * old value of that property is restored afterwards, but there is a * side-effect which could be visible to concurrent threads. * * @param port * The port on which the service will run -OR- ZERO (0) for any * open port. * @param indexManager * The {@link IIndexManager} (optional). * @param initParams * Initialization parameters for the web application as specified * by {@link ConfigParams} (optional). * * @return The server instance. * * @see SystemProperties */ static public Server newInstance(final int port, final IIndexManager indexManager, final Map initParams) throws Exception { // The jetty.xml resource to be used. final String jettyXml = System.getProperty(SystemProperties.JETTY_XML, SystemProperties.DEFAULT_JETTY_XML); return newInstance(port, jettyXml, indexManager, initParams); } /** * Start the embedded {@link Server}. *

* Note: The port override argument given here is applied by setting the * {@link NanoSparqlServer.SystemProperties#JETTY_PORT} System property. The * old value of that property is restored afterwards, but there is a * side-effect which could be visible to concurrent threads. * * @param port * The port on which the service will run -OR- ZERO (0) for any * open port. * @param jettyXml * The location of the jetty.xml resource. * @param indexManager * The {@link IIndexManager} (optional). * @param initParams * Initialization parameters for the web application as specified * by {@link ConfigParams} (optional). * * @return The server instance. * * @see SystemProperties */ synchronized// synchronized to avoid having the side-effect on the port visible to concurrent jetty starts. static public Server newInstance(final int port, final String jettyXml, final IIndexManager indexManager, final Map initParams) throws Exception { if (jettyXml == null) throw new IllegalArgumentException(); // Set the property to override the value in jetty.xml. final String oldport = System.setProperty(SystemProperties.JETTY_PORT, Integer.toString(port)); try { return newInstance(jettyXml, indexManager, initParams); } finally { if (oldport != null) { // Restore the old value for the port. System.setProperty(SystemProperties.JETTY_PORT, oldport); } } } /** * Variant used when you already have the {@link IIndexManager}. *

* When the optional {@link IIndexManager} argument is specified, it will be * set as an attribute on the {@link WebAppContext}. This will cause the * webapp to use the pre-existing {@link IIndexManager} rather than * attempting to open a new {@link IIndexManager} based on the * propertyFile init parameter specified in * web.xml. The HA initialization pattern relies on this. *

* When the {@link IIndexManager} is NOT specified, the life cycle of the * {@link IIndexManager} will be managed by the server and the * {@link IndexManager} instance will be opened (and eventually closed) by * the {@link BigdataRDFServletContextListener} based on the configured * value of the propertyFile init parameter in * web.xml. This form is used by {@link #main(String[])} and * can be used with either the {@link Journal} or the scale-out * architecture. * * @param jettyXml * The jetty.xml file that will be used to configure * jetty. * @param indexManager * The {@link IIndexManager} (optional). * @param initParams * Optional map containing overrides for the init parameters * declared in web.xml. * * @return The server instance. * * @see * Allow configuration of embedded NSS jetty server using jetty-web.xml * */ static public Server newInstance(// final String jettyXml,// final IIndexManager indexManager,// final Map initParams// ) throws Exception { if (jettyXml == null) throw new IllegalArgumentException(); // Used to search the classpath for jetty.xml. final ClassLoader classLoader = NanoSparqlServer.class .getClassLoader(); // final ClassLoader classLoader = indexManager.getClass() // .getClassLoader(); /* * Configure the jetty Server using a jetty.xml file. In turn, the * jetty.xml file configures the webapp using a web.xml file. The caller * can override the location of the jetty.xml file using the [jetty.xml] * environment variable if they need to change the way in which either * jetty or the webapp are configured. You can also override many of the * properties in the [jetty.xml] file using environment variables. For * example, they can also override the location of the web application * (including the web.xml file) using the [jetty.resourceBase] * environment variable. */ final Server server; { // Find the effective jetty.xml URL. final URL jettyXmlURL = getEffectiveJettyXmlURL(classLoader, jettyXml); // Build the server configuration from that jetty.xml resource. final XmlConfiguration configuration; { // Open jetty.xml resource. final Resource jettyConfig = Resource.newResource(jettyXmlURL); InputStream is = null; try { is = jettyConfig.getInputStream(); // Build configuration. configuration = new XmlConfiguration(is); } finally { if (is != null) { is.close(); } } } // Configure/apply jetty.resourceBase overrides. configureEffectiveResourceBase(classLoader); // Configure the jetty server. server = (Server) configuration.configure(); } /* * Configure any overrides for the web application init-params. */ configureWebAppOverrides(server, indexManager, initParams); return server; } private static URL getEffectiveJettyXmlURL(final ClassLoader classLoader, final String jettyXml) throws MalformedURLException { // Locate jetty.xml. URL jettyXmlUrl; boolean isFile = false; boolean isClassPath = false; if (new File(jettyXml).exists()) { // Check the file system. jettyXmlUrl = new URL("file:" + jettyXml); isFile = true; } else { // Check the classpath. jettyXmlUrl = classLoader.getResource(jettyXml); if(jettyXmlUrl == null) { jettyXmlUrl = classLoader.getResource("/" + jettyXml); } isClassPath = true; } // See BLZG-1447 // Check if it is running as a test suite in Eclipse or Maven. // If it is running as maven surefire execution the target/bigdata.war // will exist. final File warFile = new File("target/bigdata.war"); if (jettyXmlUrl == null && warFile.exists()) { // This is the maven surefire plugin case. jettyXmlUrl = classLoader.getResource("jetty/jettyMavenTest.xml"); } else if (jettyXmlUrl == null) { jettyXmlUrl = classLoader.getResource("jetty/jettyEclipseTest.xml"); } //If we still didn't get it, we may be running the executable jar. if (jettyXmlUrl == null) { // This is the executable jar a file // reference into the jar jettyXmlUrl = classLoader.getResource("jetty.xml"); isFile = true; } if (jettyXmlUrl == null) { if(jettyXmlUrl == null) throw new RuntimeException("Not found: " + jettyXml); } if (log.isInfoEnabled()) log.info("jetty configuration: jettyXml=" + jettyXml + ", isFile=" + isFile + ", isClassPath=" + isClassPath + ", jettyXmlUrl=" + jettyXmlUrl); return jettyXmlUrl; } /** * Search (a) the local file system; and (b) the classpath for the web * application. If the resource is located, then set the * [jetty.resourceBase] property. This search sequence gives preference to * the local file system and then searches the classpath (which jetty does * not known how to do by itself.) * * @throws MalformedURLException * * @see NSS does not start * from command line: bigdata-war/src not found */ private static void configureEffectiveResourceBase( final ClassLoader classLoader) throws MalformedURLException { // Check the environment variable. String resourceBaseStr = System .getProperty(SystemProperties.JETTY_RESOURCE_BASE); //Try JETTY_HOME if the Resource Base is null if(resourceBaseStr == null ) { resourceBaseStr = System .getProperty(SystemProperties.JETTY_HOME); } // Check the environment variable for the override web. final String jettyOverrideWeb = System .getProperty(SystemProperties.JETTY_OVERRIDE_WEB_XML); // true iff declared as an environment variable. final boolean isDeclared = resourceBaseStr != null && resourceBaseStr.trim().length() > 0; boolean isFile = false; // iff found in local file system. boolean isClassPath = false; // iff found on classpath. if (!isDeclared) { /* * jetty.resourceBase not declared in the environment. */ // The default location to check in the file system. final File file = new File("bigdata-war-html/src/main/webapp/"); final URL resourceBaseURL; if (file.exists()) { // Check the file system. See #1108 // resourceBaseURL = new URL("file:" + file.getAbsolutePath()); resourceBaseURL = file.toURI().toURL(); isFile = true; } else { /* * Check the classpath. * * Note: When checking the classpath we need to test different * resources depending on whether we are running under the * eclipse IDE or at the command line! */ URL tmp = null; String src = null; if (tmp == null) { /** * Eclipse IDE class path. * * Note: This is what gets found when running under eclipse. * The URL will be in the configured build directory for the * eclipse project. So, something like: * *

                     * file:/Users/bryan/Documents/workspace/BIGDATA_RELEASE_1_3_0_NEW_SVN/bin/WEB-INF/web.xml
                     * 
*/ tmp = ClassLoader.getSystemClassLoader().getResource( src = "bigdata-war-html/src/main/webapp/WEB-INF/web.xml"); } // if (tmp == null)// Eclipse IDE class path (system class loader). // tmp = ClassLoader.getSystemClassLoader().getResource( // src = "WEB-INF/web.xml"); // if (tmp == null) // tmp = classLoader // JAR class path. // .getResource(src = "/bigdata-war/src/WEB-INF/web.xml"); if (tmp == null) { /** * JAR class path (system class loader). * * Note: This is what gets located when we run from the * command line (outside of eclipse). The resulting JAR URL * will be something like: * *
                     * jar:file:/Users/bryan/Documents/workspace/BIGDATA_RELEASE_1_3_0_NEW_SVN/ant-build/lib/bigdata-1.3.0-20140517.jar!/bigdata-war/src/WEB-INF/web.xml
                     * 
*/ tmp = ClassLoader.getSystemClassLoader().getResource( src = "war/src/main/webapp/WEB-INF/web.xml"); } if (tmp != null) { if (src != null) { if(log.isInfoEnabled()) log.info("Found: src=" + src + ", url=" + tmp); } resourceBaseURL = new URL(trimURISubstring(tmp,"WEB-INF/web.xml")); } else { resourceBaseURL = null; } isClassPath = resourceBaseURL != null; } if (resourceBaseURL != null) { /* * We found the resource either in the file system or in the * classpath. * * Explicitly set the discovered value on the jetty.resourceBase * property. This will cause jetty to use the version of that * resource that we discovered above. * * Note: If we did not find the resource, then the default value * from the jetty.xml SystemProperty expression will be used by * jetty. If it can not find a resource using that default * value, then the startup will fail. We leave this final check * to jetty itself since it will interpret the jetty.xml file * itself. */ resourceBaseStr = resourceBaseURL.toExternalForm(); System.setProperty(SystemProperties.JETTY_RESOURCE_BASE, resourceBaseStr); } } //Don't override the value if it is explicitly declared. //If we have a resource base, but not a declared jetty override //use the WEB-INF/override-web.xml as the default. if (resourceBaseStr != null && jettyOverrideWeb == null) { final URL overrideWebXmlURL = new URL(resourceBaseStr + (resourceBaseStr.endsWith("/") ? "" : "/") + "WEB-INF/override-web.xml"); System.setProperty(SystemProperties.JETTY_OVERRIDE_WEB_XML, overrideWebXmlURL.toExternalForm()); } if (log.isInfoEnabled()) log.info("jetty configuration"// + ": resourceBaseStr=" + resourceBaseStr + ", isDeclared=" + isDeclared + ", isFile=" + isFile + ", isClassPath=" + isClassPath + ", jetty.resourceBase(effective)=" + System.getProperty(SystemProperties.JETTY_RESOURCE_BASE) + ", jetty.overrideWebXml(effective)=" + System.getProperty(SystemProperties.JETTY_OVERRIDE_WEB_XML)); } /** * Convenience method to prune last substring occurance from URL. * @param src * @param sub * @return */ final static String trimURISubstring(URL src, String sub) { final String s = src.toExternalForm(); final int endIndex = s.lastIndexOf(sub); final String t = s.substring(0, endIndex); return t; } /** * Configure the webapp (overrides, IIndexManager, etc.) *

* Note: These overrides are achieved by setting the {@link WebAppContext} * attribute named * {@link BigdataRDFServletContextListener#INIT_PARAM_OVERRIDES}. The * {@link BigdataRDFServletContextListener} then consults the attribute when * reporting the effective value of the init-params. This convoluted * mechanism is required because you can not otherwise override the * init-params without editing web.xml. */ private static void configureWebAppOverrides(// final Server server,// final IIndexManager indexManager,// final Map initParams// ) { final WebAppContext wac = getWebApp(server); if (wac == null) { /* * This is a fatal error. If we can not set the IIndexManager, the * NSS will try to interpret the propertyFile in web.xml rather than * using the one that is already open and specified by the caller. * Among other things, that breaks the HAJournalServer startup. */ throw new RuntimeException("Could not locate " + WebAppContext.class.getName()); } /* * Force the use of the caller's IIndexManager. This is how we get the * NSS to use the already open Journal for the HAJournalServer. */ if (indexManager != null) { // Set the IIndexManager attribute on the WebAppContext. wac.setAttribute(IIndexManager.class.getName(), indexManager); } /* * Note: You simply can not override the init parameters specified in * web.xml. Therefore, this sets the overrides on an attribute. The * attribute is then consulted when the web app starts and its the * override values are used if given. */ if (initParams != null) { wac.setAttribute( BigdataRDFServletContextListener.INIT_PARAM_OVERRIDES, initParams); } } /** * Return the {@link WebAppContext} for the {@link Server}. * * @param server * The {@link Server}. * * @return The {@link WebAppContext} associated with the bigdata webapp. */ public static WebAppContext getWebApp(final Server server) { final WebAppContext wac = server .getChildHandlerByClass(WebAppContext.class); /* * Note: This assumes that this is the webapp for bigdata. If there are * multiple webapps then this assumption is no longer valid and things * will break. */ return wac; } /** * Best effort attempt to return the port at which the local jetty * {@link Server} is receiving http connections. * * @param server * The server. * * @return The local port. * * @throws IllegalArgumentException * if the argument is null. */ public static int getLocalPort(final Server server) { if (server == null) throw new IllegalArgumentException(); final Connector[] a = server.getConnectors(); if (a.length == 0) { /* * This will happen if there are no configured connectors in * jetty.xml, jetty-http.xml, etc. */ throw new IllegalStateException("No connectors?"); } return ((ServerConnector) a[0]).getLocalPort(); } /** * Print the optional message on stderr, print the usage information on * stderr, and then force the program to exit with the given status code. * * @param status * The status code. * @param msg * The optional message */ protected static void usage(final int status, final String msg) { if (msg != null) { System.err.println(msg); } System.err .println("[options] port namespace (propertyFile|configFile)"); System.exit(status); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy