blob: 9953678d815b09586dd1a30367486fa9adef588d [file] [log] [blame]
/**
* 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.manifoldcf.jettyrunner;
import java.io.*;
import org.apache.manifoldcf.core.interfaces.*;
import org.apache.manifoldcf.crawler.system.*;
import org.apache.manifoldcf.crawler.*;
import org.apache.manifoldcf.agents.system.AgentsDaemon;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.server.Connector;
/**
* Run ManifoldCF with jetty.
*
*/
public class ManifoldCFJettyRunner
{
public static final String _rcsid = "@(#)$Id: ManifoldCFJettyRunner.java 989983 2010-08-27 00:10:12Z kwright $";
public static final String crawlerUIWarPathProperty = "org.apache.manifoldcf.crawleruiwarpath";
public static final String authorityServiceWarPathProperty = "org.apache.manifoldcf.authorityservicewarpath";
public static final String apiServiceWarPathProperty = "org.apache.manifoldcf.apiservicewarpath";
public static final String useJettyParentClassLoaderProperty = "org.apache.manifoldcf.usejettyparentclassloader";
public static final String jettyPortProperty = "org.apache.manifoldcf.jettyport";
protected final int port;
protected Server server;
public ManifoldCFJettyRunner( int port, String crawlerWarPath, String authorityServiceWarPath, String apiWarPath, boolean useParentLoader )
{
this.port = port;
server = new Server( port );
server.setStopAtShutdown( true );
// Initialize the servlets
ContextHandlerCollection contexts = new ContextHandlerCollection();
server.setHandler(contexts);
WebAppContext lcfCrawlerUI = new WebAppContext(crawlerWarPath,"/mcf-crawler-ui");
// This can cause jetty to ignore all of the framework and jdbc jars in the war, which is what we
// want in the single-process case.
lcfCrawlerUI.setParentLoaderPriority(useParentLoader);
contexts.addHandler(lcfCrawlerUI);
WebAppContext lcfAuthorityService = new WebAppContext(authorityServiceWarPath,"/mcf-authority-service");
// This can cause jetty to ignore all of the framework and jdbc jars in the war, which is what we
// want in the single-process case.
lcfAuthorityService.setParentLoaderPriority(useParentLoader);
contexts.addHandler(lcfAuthorityService);
WebAppContext lcfApi = new WebAppContext(apiWarPath,"/mcf-api-service");
// This can cause jetty to ignore all of the framework and jdbc jars in the war, which is what we
// want in the single-process case.
lcfApi.setParentLoaderPriority(useParentLoader);
contexts.addHandler(lcfApi);
}
public void start()
throws ManifoldCFException
{
if(!server.isRunning() )
{
try
{
server.start();
}
catch (Exception e)
{
throw new ManifoldCFException("Couldn't start: "+e.getMessage(),e);
}
}
}
public void stop()
throws ManifoldCFException
{
if( server.isRunning() )
{
try
{
server.stop();
}
catch (Exception e)
{
throw new ManifoldCFException("Couldn't stop: "+e.getMessage(),e);
}
try
{
server.join();
}
catch (InterruptedException e)
{
throw new ManifoldCFException(e.getMessage(),e,ManifoldCFException.INTERRUPTED);
}
}
}
/**
* Returns the Local Port of the first Connector found for the jetty Server.
* @return the port number.
*/
public int getLocalPort()
throws ManifoldCFException
{
return this.port;
/*
Connector[] conns = server.getConnectors();
if (0 == conns.length) {
throw new ManifoldCFException("Jetty Server has no Connectors");
}
return conns[0].getLocalPort();
*/
}
/** Run the agents process. This method will not return unless the agents process is shut down.
*/
public static void runAgents(IThreadContext tc)
throws ManifoldCFException
{
String processID = ManifoldCF.getProcessID();
// Do this so we don't have to call stopAgents() ourselves.
AgentsDaemon ad = new AgentsDaemon(processID);
ad.registerAgentsShutdownHook(tc);
ad.runAgents(tc);
}
/**
* A main class that starts jetty+mcf
*/
public static void main( String[] args )
{
if (args.length != 4 && args.length != 1 && args.length != 0)
{
System.err.println("Usage: ManifoldCFJettyRunner [<port> [<crawler-war-path> <authority-service-war-path> <api-war-path>]]");
System.exit(1);
}
// Ready to begin in earnest...
if (System.getProperty(ManifoldCF.lcfConfigFileProperty) == null)
System.setProperty(ManifoldCF.lcfConfigFileProperty,"./properties.xml");
try
{
IThreadContext tc = ThreadContextFactory.make();
ManifoldCF.initializeEnvironment(tc);
// Grab the parameters which locate the wars and describe how we work with Jetty. These are not shared.
File crawlerWarPath = ManifoldCF.getFileProperty(crawlerUIWarPathProperty);
File authorityserviceWarPath = ManifoldCF.getFileProperty(authorityServiceWarPathProperty);
File apiWarPath = ManifoldCF.getFileProperty(apiServiceWarPathProperty);
boolean useParentClassLoader = ManifoldCF.getBooleanProperty(useJettyParentClassLoaderProperty,true);
int jettyPort = ManifoldCF.getIntProperty(jettyPortProperty,8345);
if (args.length > 0)
{
try
{
jettyPort = Integer.parseInt(args[0]);
}
catch (NumberFormatException e)
{
throw new ManifoldCFException("Illegal value for jetty port argument: "+e.getMessage(),e);
}
}
if (args.length == 4)
{
crawlerWarPath = new File(args[1]);
authorityserviceWarPath = new File(args[2]);
apiWarPath = new File(args[3]);
}
else
{
if (crawlerWarPath == null)
throw new ManifoldCFException("The property '"+crawlerUIWarPathProperty+"' must be set");
if (authorityserviceWarPath == null)
throw new ManifoldCFException("The property '"+authorityServiceWarPathProperty+"' must be set");
if (apiWarPath == null)
throw new ManifoldCFException("The property '"+apiServiceWarPathProperty+"' must be set");
}
if (useParentClassLoader)
{
// Clear the agents shutdown signal.
AgentsDaemon.clearAgentsShutdownSignal(tc);
// Do the basic initialization of the database and its schema
ManifoldCF.createSystemDatabase(tc);
ManifoldCF.installTables(tc);
org.apache.manifoldcf.crawler.system.ManifoldCF.registerThisAgent(tc);
ManifoldCF.reregisterAllConnectors(tc);
}
System.err.println("Starting jetty...");
// Create a jetty instance
ManifoldCFJettyRunner jetty = new ManifoldCFJettyRunner(jettyPort,crawlerWarPath.toString(),authorityserviceWarPath.toString(),apiWarPath.toString(),useParentClassLoader);
// This will register a shutdown hook as well.
jetty.start();
System.err.println("Jetty started.");
if (useParentClassLoader)
{
System.err.println("Starting crawler...");
runAgents(tc);
System.err.println("Shutting down crawler...");
}
else
{
// Go to sleep until interrupted.
while (true)
{
try
{
Thread.sleep(5000);
continue;
}
catch (InterruptedException e)
{
break;
}
}
}
}
catch (ManifoldCFException e)
{
if (Logging.root != null)
Logging.root.error("Exception: "+e.getMessage(),e);
e.printStackTrace(System.err);
System.exit(1);
}
}
}