From 8e19d18057c02ac35e6edb81b7f83609faca37b5 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 30 Dec 2009 23:45:16 +0000 Subject: [PATCH] 298667 DeploymentManager improvements git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@1173 7e9141cc-0065-0410-87d8-b60c137991c4 --- VERSION.txt | 1 + .../eclipse/jetty/embedded/LikeJettyXml.java | 31 +- .../java/org/eclipse/jetty/deploy/App.java | 128 +------ .../eclipse/jetty/deploy/AppLifeCycle.java | 3 +- .../org/eclipse/jetty/deploy/AppProvider.java | 12 + .../jetty/deploy/DeploymentManager.java | 26 +- .../deploy/bindings/StandardStarter.java | 7 - .../deploy/bindings/StandardUndeployer.java | 6 +- .../deploy/providers/ContextAppProvider.java | 21 ++ .../providers/MonitoredDirAppProvider.java | 342 +++++++++++++----- .../deploy/providers/WebAppProvider.java | 35 ++ .../eclipse/jetty/deploy/MockAppProvider.java | 37 +- .../resources/jetty-deploymgr-contexts.xml | 14 +- .../webapp/WebappRegistrationHelper.java | 2 +- jetty-server/src/main/config/etc/jetty.xml | 10 +- .../java/org/eclipse/jetty/server/Server.java | 2 + .../java/org/eclipse/jetty/util/Scanner.java | 47 ++- 17 files changed, 452 insertions(+), 272 deletions(-) create mode 100644 jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ContextAppProvider.java create mode 100644 jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java diff --git a/VERSION.txt b/VERSION.txt index c20b8f7d320..f56c062d50b 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -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 diff --git a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java index f625cab7f7d..dda63c7e0f3 100644 --- a/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java +++ b/example-jetty-embedded/src/main/java/org/eclipse/jetty/embedded/LikeJettyXml.java @@ -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"); diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/App.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/App.java index 0c90ef792b1..2171b470d39 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/App.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/App.java @@ -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+"]"; + } } diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppLifeCycle.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppLifeCycle.java index 053914945b4..1cc5ef10a3a 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppLifeCycle.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppLifeCycle.java @@ -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); } } diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppProvider.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppProvider.java index 6bb8d39d28c..0c2191d1210 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppProvider.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/AppProvider.java @@ -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; } diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java index ad555f0b1cc..5feacfc0167 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/DeploymentManager.java @@ -111,7 +111,6 @@ public class DeploymentManager extends AbstractLifeCycle private final AppLifeCycle _lifecycle = new AppLifeCycle(); private final LinkedList _apps = new LinkedList(); 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() diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStarter.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStarter.java index 45122ed6c31..a07b33bedae 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStarter.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardStarter.java @@ -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"); - } } } diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java index 8ef4753dd00..f761a3a56c0 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/bindings/StandardUndeployer.java @@ -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) { diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ContextAppProvider.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ContextAppProvider.java new file mode 100644 index 00000000000..77b78d130aa --- /dev/null +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/ContextAppProvider.java @@ -0,0 +1,21 @@ +package org.eclipse.jetty.deploy.providers; + +import org.eclipse.jetty.deploy.ContextDeployer; + + +/* ------------------------------------------------------------ */ +/** Context directory App Provider. + *

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); + } + +} diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/MonitoredDirAppProvider.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/MonitoredDirAppProvider.java index e7cb909dd16..99710809b83 100644 --- a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/MonitoredDirAppProvider.java +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/MonitoredDirAppProvider.java @@ -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; } } diff --git a/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java new file mode 100644 index 00000000000..2c5b3dac331 --- /dev/null +++ b/jetty-deploy/src/main/java/org/eclipse/jetty/deploy/providers/WebAppProvider.java @@ -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. + *

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(); + } + + +} diff --git a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/MockAppProvider.java b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/MockAppProvider.java index 7737eac4082..13036d1b932 100644 --- a/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/MockAppProvider.java +++ b/jetty-deploy/src/test/java/org/eclipse/jetty/deploy/MockAppProvider.java @@ -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; + } } diff --git a/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml b/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml index 975f24bff9b..e87c14f8b86 100644 --- a/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml +++ b/jetty-deploy/src/test/resources/jetty-deploymgr-contexts.xml @@ -9,13 +9,6 @@ - - - - /xml-configured-jetty.properties - - - @@ -26,6 +19,13 @@ 1 true + + + + /xml-configured-jetty.properties + + + diff --git a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebappRegistrationHelper.java b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebappRegistrationHelper.java index ea9e0d57874..63fd9f03c2e 100644 --- a/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebappRegistrationHelper.java +++ b/jetty-osgi/jetty-osgi-boot/src/main/java/org/eclipse/jetty/osgi/boot/internal/webapp/WebappRegistrationHelper.java @@ -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")); diff --git a/jetty-server/src/main/config/etc/jetty.xml b/jetty-server/src/main/config/etc/jetty.xml index e690afac76b..4e536c8c943 100644 --- a/jetty-server/src/main/config/etc/jetty.xml +++ b/jetty-server/src/main/config/etc/jetty.xml @@ -115,12 +115,9 @@ Configured to behave similar to the legacy ContextDeployer --> - + /contexts - true - false 5 - false @@ -128,13 +125,10 @@ Configured to behave similar to the legacy WebAppDeployer --> - + /webapps - false - true /etc/webdefault.xml 5 - false diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java index ec43ac15140..759715f1bdc 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/Server.java @@ -247,6 +247,8 @@ public class Server extends HandlerWrapper implements Attributes } if (Log.isDebugEnabled()) Log.debug(dump()); + + System.err.println(dump()); mex.ifExceptionThrow(); } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/Scanner.java b/jetty-util/src/main/java/org/eclipse/jetty/util/Scanner.java index 70b79f142d5..77dc44664e7 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/Scanner.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/Scanner.java @@ -50,6 +50,7 @@ public class Scanner private List _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