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 + 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 + 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 + 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-910 Allow request listeners to access session
+ JETTY-1155 HttpConnection.close notifies HttpExchange + JETTY-1155 HttpConnection.close notifies HttpExchange
+ JETTY-1156 SSL blocking close with JVM Bug busy key fix + 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 java.lang.management.ManagementFactory;
import org.eclipse.jetty.deploy.ContextDeployer; import org.eclipse.jetty.deploy.ContextDeployer;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.WebAppDeployer; 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.jmx.MBeanContainer;
import org.eclipse.jetty.security.HashLoginService; import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Connector;
@ -77,23 +80,23 @@ public class LikeJettyXml
{ contexts, new DefaultHandler(), requestLogHandler }); { contexts, new DefaultHandler(), requestLogHandler });
server.setHandler(handlers); server.setHandler(handlers);
// Setup deployers // Setup deployers
DeploymentManager deployer = new DeploymentManager();
deployer.setContexts(contexts);
server.addBean(deployer);
ContextDeployer deployer0 = new ContextDeployer(); ContextAppProvider context_provider = new ContextAppProvider();
deployer0.setContexts(contexts); context_provider.setMonitoredDir(jetty_home + "/contexts");
deployer0.setConfigurationDir(jetty_home + "/contexts"); context_provider.setScanInterval(5);
deployer0.setScanInterval(1); server.addBean(context_provider);
server.addBean(deployer0); deployer.addAppProvider(context_provider);
WebAppDeployer deployer1 = new WebAppDeployer(); WebAppProvider webapp_provider = new WebAppProvider();
deployer1.setContexts(contexts); webapp_provider.setMonitoredDir(jetty_home + "/webapps");
deployer1.setWebAppDir(jetty_home + "/webapps"); webapp_provider.setParentLoaderPriority(false);
deployer1.setParentLoaderPriority(false); webapp_provider.setExtractWars(true);
deployer1.setExtract(true); webapp_provider.setDefaultsDescriptor(jetty_home + "/etc/webdefault.xml");
deployer1.setAllowDuplicates(false); deployer.addAppProvider(webapp_provider);
deployer1.setDefaultsDescriptor(jetty_home + "/etc/webdefault.xml");
server.addBean(deployer1);
HashLoginService login = new HashLoginService(); HashLoginService login = new HashLoginService();
login.setName("Test Realm"); login.setName("Test Realm");

View File

@ -36,12 +36,10 @@ import org.xml.sax.SAXException;
public class App public class App
{ {
private final DeploymentManager _manager; private final DeploymentManager _manager;
private final AppProvider _provider;
private final String _originId; private final String _originId;
private final File _archivePath; private final File _archivePath;
private ContextHandler _context; private ContextHandler _context;
private boolean _extractWars = false;
private boolean _parentLoaderPriority = false;
private String _defaultsDescriptor;
/** /**
* Create an App with specified Origin ID and archivePath * Create an App with specified Origin ID and archivePath
@ -53,9 +51,10 @@ public class App
* @see App#getOriginId() * @see App#getOriginId()
* @see App#getContextId() * @see App#getContextId()
*/ */
public App(DeploymentManager manager, String originId, File archivePath) public App(DeploymentManager manager, AppProvider provider, String originId, File archivePath)
{ {
_manager=manager; _manager=manager;
_provider = provider;
_originId = originId; _originId = originId;
_archivePath = archivePath; _archivePath = archivePath;
} }
@ -69,6 +68,15 @@ public class App
return _manager; return _manager;
} }
/* ------------------------------------------------------------ */
/**
* @return The AppProvider
*/
public AppProvider getAppProvider()
{
return _provider;
}
/** /**
* Get the archive path to the App. * Get the archive path to the App.
* *
@ -94,117 +102,12 @@ public class App
{ {
if (_context == null) if (_context == null)
{ {
if (FileID.isXmlFile(_archivePath)) _context=getAppProvider().createContextHandler(this);
{
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());
}
this._context.setAttributes(new AttributesMap(_manager.getContextAttributes())); this._context.setAttributes(new AttributesMap(_manager.getContextAttributes()));
} }
return _context; 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. * 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; 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)) 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); binding.processBinding(node,app);
} }
} }

View File

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

View File

@ -36,12 +36,5 @@ public class StandardStarter implements AppLifeCycle.Binding
{ {
handler.start(); 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++) for (int i = 0, n = children.length; i < n; i++)
{ {
Handler child = children[i]; Handler child = children[i];
Log.info("Child handler: " + child); Log.debug("Child handler: " + child);
if (child.equals(context)) if (child.equals(context))
{ {
Log.info("Removing handler: " + child); Log.debug("Removing handler: " + child);
coll.removeHandler(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) 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.File;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jetty.deploy.App; import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppProvider; import org.eclipse.jetty.deploy.AppProvider;
import org.eclipse.jetty.deploy.ConfigurationManager;
import org.eclipse.jetty.deploy.DeploymentManager; 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.Scanner;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.Resource; 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; public boolean accept(File file, String name)
boolean acceptWar = true; {
if (!file.exists())
return false;
public boolean accept(File dir, String name)
{
String lowername = name.toLowerCase(); String lowername = name.toLowerCase();
if (acceptXml && (lowername.endsWith(".xml"))) if (_acceptContextXmlFiles && !file.isDirectory() && lowername.endsWith(".xml"))
{ {
return true; return true;
} }
if (acceptWar && (lowername.endsWith(".war"))) if (_acceptWarFiles && !file.isDirectory() && lowername.endsWith(".war"))
{
return true;
}
if (_acceptDirectories && file.isDirectory())
{ {
return true; return true;
} }
@ -57,106 +72,290 @@ public class MonitoredDirAppProvider extends AbstractLifeCycle implements AppPro
} }
} }
private Resource monitoredDir; private boolean _acceptContextXmlFiles = true;
private Scanner scanner; private boolean _acceptWarFiles = true;
private int scanInterval = 10; private boolean _acceptDirectories = true;
private boolean recursive = false; private Resource _monitoredDir;
private boolean extractWars = false; private Scanner _scanner;
private boolean parentLoaderPriority = false; private int _scanInterval = 10;
private String defaultsDescriptor; private boolean _recursive = false;
private DeploymentManager deploymgr; private boolean _extractWars = false;
private ExtensionFilenameFilter filenamefilter; private boolean _parentLoaderPriority = false;
private String _defaultsDescriptor;
private DeploymentManager _deploymentManager;
private FilenameFilter _filenamefilter;
private ConfigurationManager _configurationManager;
public MonitoredDirAppProvider() private final Scanner.DiscreteListener _scannerListener = new Scanner.DiscreteListener()
{ {
scanner = new Scanner();
filenamefilter = new ExtensionFilenameFilter();
}
private void 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);
}
public void fileAdded(String filename) throws Exception public void fileAdded(String filename) throws Exception
{ {
Log.info("fileAdded(" + filename + ")"); Log.debug("added ", filename);
addConfiguredContextApp(filename); addConfiguredContextApp(filename);
} }
public void fileChanged(String filename) throws Exception public void fileChanged(String filename) throws Exception
{ {
Log.info("fileChanged(" + filename + ")"); System.err.println("changed "+filename);
// TODO should this not be an add/remove?
Log.debug("changed ", filename);
addConfiguredContextApp(filename); addConfiguredContextApp(filename);
} }
public void fileRemoved(String filename) throws Exception 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: How to determine ID from filename that doesn't exist?
/* // TODO: we probably need a map from discovered filename to resulting App
Log.info("fileRemoved(" + filename + ")"); }
addConfiguredContextApp(filename); };
public MonitoredDirAppProvider()
{
_filenamefilter = new MonitoredFilenameFilter();
}
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(_deploymentManager,this,originId,new File(filename));
_deploymentManager.addApp(app);
return app;
}
/* ------------------------------------------------------------ */
/** 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
{
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;
}
@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("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();
}
@Override
protected void doStop() throws Exception
{
_scanner.stop();
_scanner.removeListener(_scannerListener);
_scanner=null;
}
public ConfigurationManager getConfigurationManager()
{
return _configurationManager;
} }
public String getDefaultsDescriptor() public String getDefaultsDescriptor()
{ {
return defaultsDescriptor; return _defaultsDescriptor;
}
/* ------------------------------------------------------------ */
/** Get the deploymentManager.
* @return the deploymentManager
*/
public DeploymentManager getDeploymentManager()
{
return _deploymentManager;
} }
public Resource getMonitoredDir() public Resource getMonitoredDir()
{ {
return monitoredDir; return _monitoredDir;
} }
public int getScanInterval() 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() public boolean isExtractWars()
{ {
return extractWars; return _extractWars;
} }
public boolean isParentLoaderPriority() public boolean isParentLoaderPriority()
{ {
return parentLoaderPriority; return _parentLoaderPriority;
} }
public boolean isRecursive() public boolean isRecursive()
{ {
return recursive; return _recursive;
} }
public void setAcceptContextXmlFiles(boolean flag) 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) 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) public void setDefaultsDescriptor(String defaultsDescriptor)
{ {
this.defaultsDescriptor = defaultsDescriptor; _defaultsDescriptor = defaultsDescriptor;
}
public void setDeploymentManager(DeploymentManager deploymentManager)
{
_deploymentManager = deploymentManager;
} }
public void setExtractWars(boolean extractWars) public void setExtractWars(boolean extractWars)
{ {
this.extractWars = extractWars; _extractWars = extractWars;
} }
public void setMonitoredDir(Resource contextsDir) public void setMonitoredDir(Resource contextsDir)
{ {
this.monitoredDir = contextsDir; _monitoredDir = contextsDir;
} }
/** /**
@ -167,7 +366,7 @@ public class MonitoredDirAppProvider extends AbstractLifeCycle implements AppPro
{ {
try try
{ {
monitoredDir = Resource.newResource(dir); _monitoredDir = Resource.newResource(dir);
} }
catch (Exception e) catch (Exception e)
{ {
@ -177,49 +376,16 @@ public class MonitoredDirAppProvider extends AbstractLifeCycle implements AppPro
public void setParentLoaderPriority(boolean parentLoaderPriority) public void setParentLoaderPriority(boolean parentLoaderPriority)
{ {
this.parentLoaderPriority = parentLoaderPriority; _parentLoaderPriority = parentLoaderPriority;
} }
public void setRecursive(boolean recursive) public void setRecursive(boolean recursive)
{ {
this.recursive = recursive; _recursive = recursive;
} }
public void setScanInterval(int scanInterval) public void setScanInterval(int scanInterval)
{ {
this.scanInterval = scanInterval; _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();
} }
} }

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 java.io.File;
import org.eclipse.jetty.deploy.test.MavenTestingUtils; 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.component.AbstractLifeCycle;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppContext;
public class MockAppProvider extends AbstractLifeCycle implements AppProvider public class MockAppProvider extends AbstractLifeCycle implements AppProvider
{ {
@ -39,7 +44,37 @@ public class MockAppProvider extends AbstractLifeCycle implements AppProvider
public void findWebapp(String name) public void findWebapp(String name)
{ {
File war = new File(webappsDir,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); 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"> <Set name="contexts">
<Ref id="Contexts" /> <Ref id="Contexts" />
</Set> </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 --> <!-- Providers of Apps -->
<Call name="addAppProvider"> <Call name="addAppProvider">
@ -26,6 +19,13 @@
</Set> </Set>
<Set name="scanInterval">1</Set> <Set name="scanInterval">1</Set>
<Set name="recursive">true</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> </New>
</Arg> </Arg>
</Call> </Call>

View File

@ -304,7 +304,7 @@ class WebappRegistrationHelper
try try
{ {
XmlConfiguration config = new XmlConfiguration(new FileInputStream(conffile)); 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.home",jettyHome);
config.getProperties().put("jetty.host",System.getProperty("jetty.host","")); config.getProperties().put("jetty.host",System.getProperty("jetty.host",""));
config.getProperties().put("jetty.port",System.getProperty("jetty.port","8080")); config.getProperties().put("jetty.port",System.getProperty("jetty.port","8080"));

View File

@ -115,12 +115,9 @@
Configured to behave similar to the legacy ContextDeployer --> Configured to behave similar to the legacy ContextDeployer -->
<Call name="addAppProvider"> <Call name="addAppProvider">
<Arg> <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="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="scanInterval">5</Set>
<Set name="recursive">false</Set>
</New> </New>
</Arg> </Arg>
</Call> </Call>
@ -128,13 +125,10 @@
Configured to behave similar to the legacy WebAppDeployer --> Configured to behave similar to the legacy WebAppDeployer -->
<Call name="addAppProvider"> <Call name="addAppProvider">
<Arg> <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="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="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
<Set name="scanInterval">5</Set> <Set name="scanInterval">5</Set>
<Set name="recursive">false</Set>
</New> </New>
</Arg> </Arg>
</Call> </Call>

View File

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

View File

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