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:
parent
00957a8435
commit
8e19d18057
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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+"]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -247,6 +247,8 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
}
|
||||
if (Log.isDebugEnabled())
|
||||
Log.debug(dump());
|
||||
|
||||
System.err.println(dump());
|
||||
mex.ifExceptionThrow();
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue