298667 DeploymentManager improvements

git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@1173 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
Greg Wilkins 2009-12-30 23:45:16 +00:00
parent 00957a8435
commit 8e19d18057
17 changed files with 452 additions and 272 deletions

View File

@ -7,6 +7,7 @@ jetty-7.0.2-SNAPSHOT
+ 298144 Unit test for jetty-client connecting to a server that uses Basic Auth
+ 298145 Reorganized test harness to separate the HTTP PUT and HTTP GET test URLs
+ 298234 Unit test for jetty-client handling different HTTP error codes
+ 298667 DeploymentManager providers create ContextHandlers
+ JETTY-910 Allow request listeners to access session
+ JETTY-1155 HttpConnection.close notifies HttpExchange
+ JETTY-1156 SSL blocking close with JVM Bug busy key fix

View File

@ -16,7 +16,10 @@ package org.eclipse.jetty.embedded;
import java.lang.management.ManagementFactory;
import org.eclipse.jetty.deploy.ContextDeployer;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.WebAppDeployer;
import org.eclipse.jetty.deploy.providers.ContextAppProvider;
import org.eclipse.jetty.deploy.providers.WebAppProvider;
import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.server.Connector;
@ -77,23 +80,23 @@ public class LikeJettyXml
{ contexts, new DefaultHandler(), requestLogHandler });
server.setHandler(handlers);
// Setup deployers
DeploymentManager deployer = new DeploymentManager();
deployer.setContexts(contexts);
server.addBean(deployer);
ContextDeployer deployer0 = new ContextDeployer();
deployer0.setContexts(contexts);
deployer0.setConfigurationDir(jetty_home + "/contexts");
deployer0.setScanInterval(1);
server.addBean(deployer0);
ContextAppProvider context_provider = new ContextAppProvider();
context_provider.setMonitoredDir(jetty_home + "/contexts");
context_provider.setScanInterval(5);
server.addBean(context_provider);
deployer.addAppProvider(context_provider);
WebAppDeployer deployer1 = new WebAppDeployer();
deployer1.setContexts(contexts);
deployer1.setWebAppDir(jetty_home + "/webapps");
deployer1.setParentLoaderPriority(false);
deployer1.setExtract(true);
deployer1.setAllowDuplicates(false);
deployer1.setDefaultsDescriptor(jetty_home + "/etc/webdefault.xml");
server.addBean(deployer1);
WebAppProvider webapp_provider = new WebAppProvider();
webapp_provider.setMonitoredDir(jetty_home + "/webapps");
webapp_provider.setParentLoaderPriority(false);
webapp_provider.setExtractWars(true);
webapp_provider.setDefaultsDescriptor(jetty_home + "/etc/webdefault.xml");
deployer.addAppProvider(webapp_provider);
HashLoginService login = new HashLoginService();
login.setName("Test Realm");

View File

@ -36,12 +36,10 @@ import org.xml.sax.SAXException;
public class App
{
private final DeploymentManager _manager;
private final AppProvider _provider;
private final String _originId;
private final File _archivePath;
private ContextHandler _context;
private boolean _extractWars = false;
private boolean _parentLoaderPriority = false;
private String _defaultsDescriptor;
/**
* Create an App with specified Origin ID and archivePath
@ -53,9 +51,10 @@ public class App
* @see App#getOriginId()
* @see App#getContextId()
*/
public App(DeploymentManager manager, String originId, File archivePath)
public App(DeploymentManager manager, AppProvider provider, String originId, File archivePath)
{
_manager=manager;
_provider = provider;
_originId = originId;
_archivePath = archivePath;
}
@ -68,6 +67,15 @@ public class App
{
return _manager;
}
/* ------------------------------------------------------------ */
/**
* @return The AppProvider
*/
public AppProvider getAppProvider()
{
return _provider;
}
/**
* Get the archive path to the App.
@ -94,117 +102,12 @@ public class App
{
if (_context == null)
{
if (FileID.isXmlFile(_archivePath))
{
this._context = createContextFromXml(_manager);
}
else if (FileID.isWebArchive(_archivePath))
{
// Treat as a Web Archive.
this._context = createContextDefault(_manager);
}
else
{
throw new IllegalStateException("Not an XML or Web Archive: " + _archivePath.getAbsolutePath());
}
_context=getAppProvider().createContextHandler(this);
this._context.setAttributes(new AttributesMap(_manager.getContextAttributes()));
}
return _context;
}
private ContextHandler createContextDefault(DeploymentManager deploymgr)
{
String context = _archivePath.getName();
// Context Path is the same as the archive.
if (FileID.isWebArchiveFile(_archivePath))
{
context = context.substring(0,context.length() - 4);
}
// Context path is "/" in special case of archive (or dir) named "root"
if (context.equalsIgnoreCase("root") || context.equalsIgnoreCase("root/"))
{
context = URIUtil.SLASH;
}
// Ensure "/" is Prepended to all context paths.
if (context.charAt(0) != '/')
{
context = "/" + context;
}
// Ensure "/" is Not Trailing in context paths.
if (context.endsWith("/") && context.length() > 0)
{
context = context.substring(0,context.length() - 1);
}
WebAppContext wah = new WebAppContext();
wah.setContextPath(context);
wah.setWar(_archivePath.getAbsolutePath());
if (_defaultsDescriptor != null)
{
wah.setDefaultsDescriptor(_defaultsDescriptor);
}
wah.setExtractWAR(_extractWars);
wah.setParentLoaderPriority(_parentLoaderPriority);
return wah;
}
@SuppressWarnings("unchecked")
private ContextHandler createContextFromXml(DeploymentManager deploymgr) throws MalformedURLException, IOException, SAXException, Exception
{
Resource resource = Resource.newResource(this._archivePath.toURI());
if (!resource.exists())
{
return null;
}
XmlConfiguration xmlc = new XmlConfiguration(resource.getURL());
Map props = new HashMap();
props.put("Server",deploymgr.getServer());
if (deploymgr.getConfigurationManager() != null)
{
props.putAll(deploymgr.getConfigurationManager().getProperties());
}
xmlc.setProperties(props);
return (ContextHandler)xmlc.configure();
}
public boolean isExtractWars()
{
return _extractWars;
}
public void setExtractWars(boolean extractWars)
{
this._extractWars = extractWars;
}
public boolean isParentLoaderPriority()
{
return _parentLoaderPriority;
}
public void setParentLoaderPriority(boolean parentLoaderPriority)
{
this._parentLoaderPriority = parentLoaderPriority;
}
public String getDefaultsDescriptor()
{
return _defaultsDescriptor;
}
public void setDefaultsDescriptor(String defaultsDescriptor)
{
this._defaultsDescriptor = defaultsDescriptor;
}
/**
* The unique id of the {@link App} relating to how it is installed on the jetty server side.
*
@ -228,4 +131,9 @@ public class App
{
return this._originId;
}
public String toString()
{
return "App["+_context+","+_originId+","+_archivePath+"]";
}
}

View File

@ -165,7 +165,8 @@ public class AppLifeCycle extends Graph
{
for (Binding binding : getBindings(node))
{
Log.info("Calling " + binding.getClass().getName());
if (Log.isDebugEnabled())
Log.debug("Calling " + binding.getClass().getName()+" for "+app);
binding.processBinding(node,app);
}
}

View File

@ -15,6 +15,9 @@
// ========================================================================
package org.eclipse.jetty.deploy;
import java.io.IOException;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.component.LifeCycle;
/**
@ -30,4 +33,13 @@ public interface AppProvider extends LifeCycle
* if the provider {@link #isRunning()}.
*/
void setDeploymentManager(DeploymentManager deploymentManager);
/* ------------------------------------------------------------ */
/** Create a ContextHandler for an App
* @param app The App
* @return A ContextHandler
* @throws IOException
* @throws Exception
*/
ContextHandler createContextHandler(App app) throws Exception;
}

View File

@ -111,7 +111,6 @@ public class DeploymentManager extends AbstractLifeCycle
private final AppLifeCycle _lifecycle = new AppLifeCycle();
private final LinkedList<AppEntry> _apps = new LinkedList<AppEntry>();
private AttributesMap _contextAttributes = new AttributesMap();
private ConfigurationManager _configurationManager;
private ContextHandlerCollection _contexts;
private boolean _useStandardBindings = true;
private String _defaultLifeCycleGoal = "started";
@ -123,7 +122,7 @@ public class DeploymentManager extends AbstractLifeCycle
*/
public void addApp(App app)
{
Log.info("App Added: " + app.getOriginId());
Log.info("Deployable added: " + app.getOriginId());
AppEntry entry = new AppEntry();
entry.app = app;
entry.setLifeCycleNode(_lifecycle.getNodeByName("undeployed"));
@ -170,14 +169,13 @@ public class DeploymentManager extends AbstractLifeCycle
{
if (_useStandardBindings)
{
Log.info("Using standard bindings");
Log.debug("DeploymentManager using standard bindings");
addLifeCycleBinding(new StandardDeployer());
addLifeCycleBinding(new StandardStarter());
addLifeCycleBinding(new StandardStopper());
addLifeCycleBinding(new StandardUndeployer());
}
Log.info("Starting all Providers: " + _providers.size());
// Start all of the AppProviders
for (AppProvider provider : _providers)
{
@ -189,8 +187,6 @@ public class DeploymentManager extends AbstractLifeCycle
@Override
protected void doStop() throws Exception
{
Log.info("Stopping all Providers: " + _providers.size());
// Stop all of the AppProviders
for (AppProvider provider : _providers)
{
@ -343,11 +339,6 @@ public class DeploymentManager extends AbstractLifeCycle
return _contextAttributes.getAttribute(name);
}
public ConfigurationManager getConfigurationManager()
{
return _configurationManager;
}
public AttributesMap getContextAttributes()
{
return _contextAttributes;
@ -391,8 +382,8 @@ public class DeploymentManager extends AbstractLifeCycle
AppEntry entry = it.next();
if (entry.app.equals(app) && "undeployed".equals(entry.lifecyleNode.getName()))
{
Log.info("Remove App: " + entry.app);
it.remove();
Log.info("Deployable removed: " + entry.app);
}
}
}
@ -475,7 +466,7 @@ public class DeploymentManager extends AbstractLifeCycle
while (it.hasNext())
{
Node node = it.next();
Log.info("Executing Node: " + node);
Log.debug("Executing Node: " + node);
_lifecycle.runBindings(node,appentry.app,this);
appentry.setLifeCycleNode(node);
}
@ -521,11 +512,6 @@ public class DeploymentManager extends AbstractLifeCycle
_contextAttributes.setAttribute(name,value);
}
public void setConfigurationManager(ConfigurationManager configurationManager)
{
this._configurationManager = configurationManager;
}
public void setContextAttributes(AttributesMap contextAttributes)
{
this._contextAttributes = contextAttributes;
@ -556,13 +542,11 @@ public class DeploymentManager extends AbstractLifeCycle
public void undeployAll()
{
Log.info("Undeploy (All) started");
Log.info("Undeploy All");
for (AppEntry appentry : _apps)
{
Log.info("Undeploy: " + appentry);
requestAppGoal(appentry,"undeployed");
}
Log.info("Undeploy (All) completed");
}
public boolean isUseStandardBindings()

View File

@ -36,12 +36,5 @@ public class StandardStarter implements AppLifeCycle.Binding
{
handler.start();
}
// Remove other apps at same context
for (App other : app.getDeploymentManager().getAppsWithSameContext(app))
{
Log.info("Removing apps with same context: " + other);
app.getDeploymentManager().requestAppGoal(other,"undeployed");
}
}
}

View File

@ -50,12 +50,12 @@ public class StandardUndeployer implements AppLifeCycle.Binding
for (int i = 0, n = children.length; i < n; i++)
{
Handler child = children[i];
Log.info("Child handler: " + child);
Log.debug("Child handler: " + child);
if (child.equals(context))
{
Log.info("Removing handler: " + child);
Log.debug("Removing handler: " + child);
coll.removeHandler(child);
Log.info(String.format("After removal: %d (originally %d)",coll.getHandlers().length,originalCount));
Log.debug(String.format("After removal: %d (originally %d)",coll.getHandlers().length,originalCount));
}
else if (child instanceof HandlerCollection)
{

View File

@ -0,0 +1,21 @@
package org.eclipse.jetty.deploy.providers;
import org.eclipse.jetty.deploy.ContextDeployer;
/* ------------------------------------------------------------ */
/** Context directory App Provider.
* <p>This specialisation of {@link MonitoredDirAppProvider} is the
* replacement for {@link ContextDeployer} and it will scan a directory
* only for context.xml files.
* @see ContextDeployer
*/
public class ContextAppProvider extends MonitoredDirAppProvider
{
public ContextAppProvider()
{
super(true,false,false);
setRecursive(false);
}
}

View File

@ -17,38 +17,53 @@ package org.eclipse.jetty.deploy.providers;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppProvider;
import org.eclipse.jetty.deploy.ConfigurationManager;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.util.FileID;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.Scanner;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.xml.XmlConfiguration;
/**
* Backwards Compatible AppProvider for Monitoring a Contexts directory and deploying All Contexts.
* AppProvider for Monitoring directories for contexts.
*
* A Context may either be a WAR, a directory or an XML descriptor.
*
* Similar in scope to the original org.eclipse.jetty.deploy.ContextDeployer
*/
public class MonitoredDirAppProvider extends AbstractLifeCycle implements AppProvider, Scanner.DiscreteListener
public class MonitoredDirAppProvider extends AbstractLifeCycle implements AppProvider
{
class ExtensionFilenameFilter implements FilenameFilter
class MonitoredFilenameFilter implements FilenameFilter
{
boolean acceptXml = true;
boolean acceptWar = true;
public boolean accept(File dir, String name)
public boolean accept(File file, String name)
{
if (!file.exists())
return false;
String lowername = name.toLowerCase();
if (acceptXml && (lowername.endsWith(".xml")))
if (_acceptContextXmlFiles && !file.isDirectory() && lowername.endsWith(".xml"))
{
return true;
}
if (acceptWar && (lowername.endsWith(".war")))
if (_acceptWarFiles && !file.isDirectory() && lowername.endsWith(".war"))
{
return true;
}
if (_acceptDirectories && file.isDirectory())
{
return true;
}
@ -57,106 +72,290 @@ public class MonitoredDirAppProvider extends AbstractLifeCycle implements AppPro
}
}
private Resource monitoredDir;
private Scanner scanner;
private int scanInterval = 10;
private boolean recursive = false;
private boolean extractWars = false;
private boolean parentLoaderPriority = false;
private String defaultsDescriptor;
private DeploymentManager deploymgr;
private ExtensionFilenameFilter filenamefilter;
private boolean _acceptContextXmlFiles = true;
private boolean _acceptWarFiles = true;
private boolean _acceptDirectories = true;
private Resource _monitoredDir;
private Scanner _scanner;
private int _scanInterval = 10;
private boolean _recursive = false;
private boolean _extractWars = false;
private boolean _parentLoaderPriority = false;
private String _defaultsDescriptor;
private DeploymentManager _deploymentManager;
private FilenameFilter _filenamefilter;
private ConfigurationManager _configurationManager;
private final Scanner.DiscreteListener _scannerListener = new Scanner.DiscreteListener()
{
public void fileAdded(String filename) throws Exception
{
Log.debug("added ", filename);
addConfiguredContextApp(filename);
}
public void fileChanged(String filename) throws Exception
{
System.err.println("changed "+filename);
// TODO should this not be an add/remove?
Log.debug("changed ", filename);
addConfiguredContextApp(filename);
}
public void fileRemoved(String filename) throws Exception
{
System.err.println("removed "+filename);
Log.debug("removed ", filename);
// TODO: How to determine ID from filename that doesn't exist?
// TODO: we probably need a map from discovered filename to resulting App
}
};
public MonitoredDirAppProvider()
{
scanner = new Scanner();
filenamefilter = new ExtensionFilenameFilter();
_filenamefilter = new MonitoredFilenameFilter();
}
private void addConfiguredContextApp(String filename)
protected MonitoredDirAppProvider(boolean xml,boolean war, boolean dir)
{
_acceptContextXmlFiles=xml;
_acceptWarFiles=war;
_acceptDirectories=dir;
_filenamefilter = new MonitoredFilenameFilter();
}
protected MonitoredDirAppProvider(FilenameFilter filter, boolean xml,boolean war, boolean dir)
{
_acceptContextXmlFiles=xml;
_acceptWarFiles=war;
_acceptDirectories=dir;
_filenamefilter = filter;
}
private App addConfiguredContextApp(String filename)
{
String originId = filename;
App app = new App(deploymgr,originId,new File(filename));
app.setExtractWars(this.extractWars);
app.setParentLoaderPriority(this.parentLoaderPriority);
app.setDefaultsDescriptor(this.defaultsDescriptor);
this.deploymgr.addApp(app);
App app = new App(_deploymentManager,this,originId,new File(filename));
_deploymentManager.addApp(app);
return app;
}
public void fileAdded(String filename) throws Exception
/* ------------------------------------------------------------ */
/** Create a context Handler for an App instance.
* This method can create a {@link ContextHandler} from a context XML file
* or a {@link WebAppContext} from a WAR file or directory, depending on the
* settings of the accept fields.
* @see #setAcceptContextXmlFiles(boolean)
* @see #setAcceptWarFiles(boolean)
* @see #setAcceptDirectories(boolean)
* @see org.eclipse.jetty.deploy.AppProvider#createContextHandler(org.eclipse.jetty.deploy.App)
*/
public ContextHandler createContextHandler(final App app) throws Exception
{
Log.info("fileAdded(" + filename + ")");
addConfiguredContextApp(filename);
Resource resource = Resource.newResource(app.getArchivePath().toURI());
if (!resource.exists())
throw new IllegalStateException("App resouce does not exist "+resource);
if (_acceptContextXmlFiles && FileID.isXmlFile(app.getArchivePath()))
{
// TODO - it is a bit wierd that this ignores
// _defaultsDescriptor, _extractWars and _parentLoaderPriority
// This reflects that there really is the common base for Context
// and WebApp deployers should probably not have these bits in them
XmlConfiguration xmlc = new XmlConfiguration(resource.getURL());
Map props = new HashMap();
props.put("Server",_deploymentManager.getServer());
if (getConfigurationManager() != null)
props.putAll(getConfigurationManager().getProperties());
xmlc.setProperties(props);
return (ContextHandler)xmlc.configure();
}
String context = app.getArchivePath().getName();
if (_acceptWarFiles && FileID.isWebArchiveFile(app.getArchivePath()))
{
// Context Path is the same as the archive.
context = context.substring(0,context.length() - 4);
}
else if (_acceptDirectories && app.getArchivePath().isDirectory())
{
// must be a directory
}
else
throw new IllegalStateException("unable to create ContextHandler for "+app);
// special case of archive (or dir) named "root" is / context
if (context.equalsIgnoreCase("root") || context.equalsIgnoreCase("root/"))
context = URIUtil.SLASH;
// Ensure "/" is Prepended to all context paths.
if (context.charAt(0) != '/')
context = "/" + context;
// Ensure "/" is Not Trailing in context paths.
if (context.endsWith("/") && context.length() > 0)
context = context.substring(0,context.length() - 1);
WebAppContext wah = new WebAppContext();
wah.setContextPath(context);
wah.setWar(app.getArchivePath().getAbsolutePath());
if (_defaultsDescriptor != null)
wah.setDefaultsDescriptor(_defaultsDescriptor);
wah.setExtractWAR(_extractWars);
wah.setParentLoaderPriority(_parentLoaderPriority);
return wah;
}
public void fileChanged(String filename) throws Exception
@Override
protected void doStart() throws Exception
{
Log.info("fileChanged(" + filename + ")");
addConfiguredContextApp(filename);
Log.info(this.getClass().getSimpleName() + ".doStart()");
if (_monitoredDir == null)
{
throw new IllegalStateException("No configuration dir specified");
}
File scandir = _monitoredDir.getFile();
Log.info("Deployment monitor " + scandir+ " at intervale "+_scanInterval);
_scanner=new Scanner();
_scanner.setScanDirs(Collections.singletonList(scandir));
_scanner.setScanInterval(_scanInterval);
_scanner.setRecursive(_recursive);
_scanner.setFilenameFilter(_filenamefilter);
_scanner.setReportDirs(_acceptDirectories);
_scanner.addListener(_scannerListener);
_scanner.start();
}
public void fileRemoved(String filename) throws Exception
@Override
protected void doStop() throws Exception
{
// TODO: How to determine ID from filename that doesn't exist?
/*
Log.info("fileRemoved(" + filename + ")");
addConfiguredContextApp(filename);
*/
_scanner.stop();
_scanner.removeListener(_scannerListener);
_scanner=null;
}
public ConfigurationManager getConfigurationManager()
{
return _configurationManager;
}
public String getDefaultsDescriptor()
{
return defaultsDescriptor;
return _defaultsDescriptor;
}
/* ------------------------------------------------------------ */
/** Get the deploymentManager.
* @return the deploymentManager
*/
public DeploymentManager getDeploymentManager()
{
return _deploymentManager;
}
public Resource getMonitoredDir()
{
return monitoredDir;
return _monitoredDir;
}
public int getScanInterval()
{
return scanInterval;
return _scanInterval;
}
/* ------------------------------------------------------------ */
/** Get the acceptContextXmlFiles.
* @return the acceptContextXmlFiles
*/
public boolean isAcceptContextXmlFiles()
{
return _acceptContextXmlFiles;
}
/* ------------------------------------------------------------ */
/** Get the acceptDirectories.
* @return the acceptDirectories
*/
public boolean isAcceptDirectories()
{
return _acceptDirectories;
}
/* ------------------------------------------------------------ */
/** Get the acceptWarFiles.
* @return the acceptWarFiles
*/
public boolean isAcceptWarFiles()
{
return _acceptWarFiles;
}
public boolean isExtractWars()
{
return extractWars;
return _extractWars;
}
public boolean isParentLoaderPriority()
{
return parentLoaderPriority;
return _parentLoaderPriority;
}
public boolean isRecursive()
{
return recursive;
return _recursive;
}
public void setAcceptContextXmlFiles(boolean flag)
{
filenamefilter.acceptXml = flag;
if (isRunning())
throw new IllegalStateException();
_acceptContextXmlFiles = flag;
}
public void setAcceptDirectories(boolean flag)
{
if (isRunning())
throw new IllegalStateException();
_acceptDirectories = flag;
}
public void setAcceptWarFiles(boolean flag)
{
filenamefilter.acceptWar = flag;
if (isRunning())
throw new IllegalStateException();
_acceptWarFiles = flag;
}
public void setConfigurationManager(ConfigurationManager configurationManager)
{
_configurationManager = configurationManager;
}
public void setDefaultsDescriptor(String defaultsDescriptor)
{
this.defaultsDescriptor = defaultsDescriptor;
_defaultsDescriptor = defaultsDescriptor;
}
public void setDeploymentManager(DeploymentManager deploymentManager)
{
_deploymentManager = deploymentManager;
}
public void setExtractWars(boolean extractWars)
{
this.extractWars = extractWars;
_extractWars = extractWars;
}
public void setMonitoredDir(Resource contextsDir)
{
this.monitoredDir = contextsDir;
_monitoredDir = contextsDir;
}
/**
@ -167,59 +366,26 @@ public class MonitoredDirAppProvider extends AbstractLifeCycle implements AppPro
{
try
{
monitoredDir = Resource.newResource(dir);
_monitoredDir = Resource.newResource(dir);
}
catch (Exception e)
{
throw new IllegalArgumentException(e);
}
}
public void setParentLoaderPriority(boolean parentLoaderPriority)
{
this.parentLoaderPriority = parentLoaderPriority;
_parentLoaderPriority = parentLoaderPriority;
}
public void setRecursive(boolean recursive)
{
this.recursive = recursive;
_recursive = recursive;
}
public void setScanInterval(int scanInterval)
{
this.scanInterval = scanInterval;
}
public void setDeploymentManager(DeploymentManager deploymentManager)
{
this.deploymgr = deploymentManager;
}
@Override
protected void doStart() throws Exception
{
Log.info(this.getClass().getSimpleName() + ".doStart()");
if (monitoredDir == null)
{
throw new IllegalStateException("No configuration dir specified");
}
File scandir = monitoredDir.getFile();
Log.info("ScanDir: " + scandir);
this.scanner.setScanDirs(Collections.singletonList(scandir));
this.scanner.setScanInterval(scanInterval);
this.scanner.setRecursive(recursive);
this.scanner.setFilenameFilter(filenamefilter);
this.scanner.addListener(this);
this.scanner.start();
Log.info("Started scanner: " + scanner);
}
@Override
protected void doStop() throws Exception
{
Log.info(this.getClass().getSimpleName() + ".doStop()");
this.scanner.removeListener(this);
this.scanner.stop();
_scanInterval = scanInterval;
}
}

View File

@ -0,0 +1,35 @@
package org.eclipse.jetty.deploy.providers;
import org.eclipse.jetty.deploy.ConfigurationManager;
import org.eclipse.jetty.deploy.WebAppDeployer;
/* ------------------------------------------------------------ */
/** Context directory App Provider.
* <p>This specialisation of {@link MonitoredDirAppProvider} is the
* replacement for {@link WebAppDeployer} and it will scan a directory
* only for warfiles or directories files.
* @see WebAppDeployer
*/
public class WebAppProvider extends MonitoredDirAppProvider
{
public WebAppProvider()
{
super(false,true,true);
setRecursive(false);
setScanInterval(0);
}
/* ------------------------------------------------------------ */
/**
* Configuration Managers are not supported for WebAppProvider, so this
* methods throws an {@link UnsupportedOperationException}.
*/
@Override
public void setConfigurationManager(ConfigurationManager configurationManager)
{
throw new UnsupportedOperationException();
}
}

View File

@ -18,7 +18,12 @@ package org.eclipse.jetty.deploy;
import java.io.File;
import org.eclipse.jetty.deploy.test.MavenTestingUtils;
import org.eclipse.jetty.deploy.util.FileID;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppContext;
public class MockAppProvider extends AbstractLifeCycle implements AppProvider
{
@ -39,7 +44,37 @@ public class MockAppProvider extends AbstractLifeCycle implements AppProvider
public void findWebapp(String name)
{
File war = new File(webappsDir,name);
App app = new App(deployMan,"mock-" + name,war);
App app = new App(deployMan,this,"mock-" + name,war);
this.deployMan.addApp(app);
}
public ContextHandler createContextHandler(App app) throws Exception
{
WebAppContext context = new WebAppContext();
context.setWar(Resource.newResource(app.getArchivePath().toURL()).toString());
String path = app.getArchivePath().getName();
if (FileID.isWebArchiveFile(app.getArchivePath()))
{
// Context Path is the same as the archive.
path = path.substring(0,path.length() - 4);
}
// special case of archive (or dir) named "root" is / context
if (path.equalsIgnoreCase("root") || path.equalsIgnoreCase("root/"))
path = URIUtil.SLASH;
// Ensure "/" is Prepended to all context paths.
if (path.charAt(0) != '/')
path = "/" + path;
// Ensure "/" is Not Trailing in context paths.
if (path.endsWith("/") && path.length() > 0)
path = path.substring(0,path.length() - 1);
context.setContextPath(path);
return context;
}
}

View File

@ -9,13 +9,6 @@
<Set name="contexts">
<Ref id="Contexts" />
</Set>
<Set name="configurationManager">
<New class="org.eclipse.jetty.deploy.FileConfigurationManager">
<Set name="file">
<Property name="test.targetdir" default="target" />/xml-configured-jetty.properties
</Set>
</New>
</Set>
<!-- Providers of Apps -->
<Call name="addAppProvider">
@ -26,6 +19,13 @@
</Set>
<Set name="scanInterval">1</Set>
<Set name="recursive">true</Set>
<Set name="configurationManager">
<New class="org.eclipse.jetty.deploy.FileConfigurationManager">
<Set name="file">
<Property name="test.targetdir" default="target" />/xml-configured-jetty.properties
</Set>
</New>
</Set>
</New>
</Arg>
</Call>

View File

@ -304,7 +304,7 @@ class WebappRegistrationHelper
try
{
XmlConfiguration config = new XmlConfiguration(new FileInputStream(conffile));
config.getIdMap().put("server","_server");
config.getIdMap().put("Server","_server");
config.getProperties().put("jetty.home",jettyHome);
config.getProperties().put("jetty.host",System.getProperty("jetty.host",""));
config.getProperties().put("jetty.port",System.getProperty("jetty.port","8080"));

View File

@ -115,12 +115,9 @@
Configured to behave similar to the legacy ContextDeployer -->
<Call name="addAppProvider">
<Arg>
<New class="org.eclipse.jetty.deploy.providers.MonitoredDirAppProvider">
<New class="org.eclipse.jetty.deploy.providers.ContextAppProvider">
<Set name="monitoredDir"><Property name="jetty.home" default="." />/contexts</Set>
<Set name="acceptContextXmlFiles">true</Set>
<Set name="acceptWarFiles">false</Set>
<Set name="scanInterval">5</Set>
<Set name="recursive">false</Set>
</New>
</Arg>
</Call>
@ -128,13 +125,10 @@
Configured to behave similar to the legacy WebAppDeployer -->
<Call name="addAppProvider">
<Arg>
<New class="org.eclipse.jetty.deploy.providers.MonitoredDirAppProvider">
<New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
<Set name="monitoredDir"><Property name="jetty.home" default="." />/webapps</Set>
<Set name="acceptContextXmlFiles">false</Set>
<Set name="acceptWarFiles">true</Set>
<Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
<Set name="scanInterval">5</Set>
<Set name="recursive">false</Set>
</New>
</Arg>
</Call>

View File

@ -247,6 +247,8 @@ public class Server extends HandlerWrapper implements Attributes
}
if (Log.isDebugEnabled())
Log.debug(dump());
System.err.println(dump());
mex.ifExceptionThrow();
}

View File

@ -50,6 +50,7 @@ public class Scanner
private List<File> _scanDirs;
private volatile boolean _running = false;
private boolean _reportExisting = true;
private boolean _reportDirs = true;
private Timer _timer;
private TimerTask _task;
private boolean _recursive=true;
@ -97,11 +98,11 @@ public class Scanner
/**
* Set the scan interval
* @param scanInterval pause between scans in seconds
* @param scanInterval pause between scans in seconds, or 0 for no scan after the initial scan.
*/
public synchronized void setScanInterval(int scanInterval)
{
this._scanInterval = scanInterval;
_scanInterval = scanInterval;
schedule();
}
@ -154,7 +155,7 @@ public class Scanner
*/
public void setFilenameFilter (FilenameFilter filter)
{
this._filter = filter;
_filter = filter;
}
/**
@ -166,6 +167,7 @@ public class Scanner
return _filter;
}
/* ------------------------------------------------------------ */
/**
* Whether or not an initial scan will report all files as being
* added.
@ -174,9 +176,31 @@ public class Scanner
*/
public void setReportExistingFilesOnStartup (boolean reportExisting)
{
this._reportExisting = reportExisting;
_reportExisting = reportExisting;
}
/* ------------------------------------------------------------ */
public boolean getReportExistingFilesOnStartup()
{
return _reportExisting;
}
/* ------------------------------------------------------------ */
/** Set if found directories should be reported.
* @param dirs
*/
public void setReportDirs(boolean dirs)
{
_reportDirs=dirs;
}
/* ------------------------------------------------------------ */
public boolean getReportDirs()
{
return _reportDirs;
}
/* ------------------------------------------------------------ */
/**
* Add an added/removed/changed listener
* @param listener
@ -276,7 +300,7 @@ public class Scanner
/**
* Perform a pass of the scanner and report changes
*/
public void scan ()
public synchronized void scan ()
{
scanFiles();
reportDifferences(_currentScan, _prevScan);
@ -288,7 +312,7 @@ public class Scanner
* Recursively scan all files in the designated directories.
* @return Map of name of file to last modified time
*/
public void scanFiles ()
public synchronized void scanFiles ()
{
if (_scanDirs==null)
return;
@ -300,7 +324,7 @@ public class Scanner
File dir = itor.next();
if ((dir != null) && (dir.exists()))
scanFile(dir, _currentScan);
scanFile(dir, _currentScan,0);
}
}
@ -361,14 +385,14 @@ public class Scanner
* @param f file or directory
* @param scanInfoMap map of filenames to last modified times
*/
private void scanFile (File f, Map scanInfoMap)
private void scanFile (File f, Map scanInfoMap, int depth)
{
try
{
if (!f.exists())
return;
if (f.isFile())
if (f.isFile() || depth>0&& _reportDirs && f.isDirectory())
{
if ((_filter == null) || ((_filter != null) && _filter.accept(f.getParentFile(), f.getName())))
{
@ -377,11 +401,12 @@ public class Scanner
scanInfoMap.put(name, new Long(lastModified));
}
}
else if (f.isDirectory() && (_recursive || _scanDirs.contains(f)))
if (f.isDirectory() && (_recursive || _scanDirs.contains(f)))
{
File[] files = f.listFiles();
for (int i=0;i<files.length;i++)
scanFile(files[i], scanInfoMap);
scanFile(files[i], scanInfoMap,depth+1);
}
}
catch (IOException e)