Merging jetty-deploy-manager-graph from sandbox to trunk jetty-deploy.

git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@1124 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
Joakim Erdfelt 2009-12-04 21:59:58 +00:00
parent 9dfabfb184
commit 815e822aa9
47 changed files with 5804 additions and 13 deletions

View File

@ -61,10 +61,31 @@
<artifactId>jetty-xml</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp-verifier</artifactId>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.5</version>
<configuration>
<docfilessubdirs>true</docfilessubdirs>
<detectLinks>true</detectLinks>
<detectJavaApiLink>true</detectJavaApiLink>
</configuration>
</plugin>
</plugins>
</reporting>
</project>

View File

@ -0,0 +1,220 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jetty.deploy.util.FileID;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.AttributesMap;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.xml.XmlConfiguration;
import org.xml.sax.SAXException;
/**
* The information about an App that is managed by the {@link DeploymentManager}
*/
public class App
{
private File archivePath;
private ContextHandler handler;
private boolean extractWars = false;
private boolean parentLoaderPriority = false;
private String defaultsDescriptor;
private String originId;
/**
* Create an App with specified Origin ID and archivePath
*
* @param originId
* the origin ID (The ID that the {@link AppProvider} knows about)
* @param archivePath
* the path to the app (can be a file *.war or *.jar, or a webapp exploded directory)
* @see App#getOriginId()
* @see App#getContextId()
*/
public App(String originId, File archivePath)
{
this.originId = originId;
this.archivePath = archivePath;
}
/**
* Get the archive path to the App.
*
* Might exist as a Directory (example: an exploded webapp, or a jetty:run) or a File (example: a WAR file)
*
* @return the
*/
public File getArchivePath()
{
return this.archivePath;
}
/**
* Get ContextHandler for the App.
*
* Create it if needed.
*
* @return the {@link ContextHandler} to use for the App when fully started. (Portions of which might be ignored
* when App is in the {@link AppState#STAGED} state}
* @throws Exception
*/
public ContextHandler getContextHandler(DeploymentManager deployMgr) throws Exception
{
if (handler == null)
{
if (FileID.isXmlFile(archivePath))
{
this.handler = createContextFromXml(deployMgr);
}
else if (FileID.isWebArchive(archivePath))
{
// Treat as a Web Archive.
this.handler = createContextDefault(deployMgr);
}
else
{
throw new IllegalStateException("Not an XML or Web Archive: " + archivePath.getAbsolutePath());
}
this.handler.setAttributes(new AttributesMap(deployMgr.getContextAttributes()));
}
return handler;
}
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.
*
* @return the generated Id for the App.
*/
public String getContextId()
{
if (this.handler == null)
{
return null;
}
return this.handler.getContextPath();
}
/**
* The origin of this {@link App} as specified by the {@link AppProvider}
*
* @return String representing the origin of this app.
*/
public String getOriginId()
{
return this.originId;
}
}

View File

@ -0,0 +1,192 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jetty.deploy.graph.Graph;
import org.eclipse.jetty.deploy.graph.Node;
import org.eclipse.jetty.util.log.Log;
/**
* The lifecycle of an App in the {@link DeploymentManager}.
*
* Setups a the default {@link Graph}, and manages the bindings to the life cycle via the {@link DeployLifeCycleBinding}
* annotation.
* <p>
* <img src="doc-files/AppLifeCycle.png">
*/
public class AppLifeCycle extends Graph
{
public static interface Binding
{
/**
* Get a list of targets that this implementation should bind to.
*
* @return the array of String node names to bind to. (use <code>"*"</code> to bind to all known node names)
*/
String[] getBindingTargets();
/**
* Event called to process a {@link AppLifeCycle} binding.
*
* @param node
* the node being processed
* @param app
* the app being processed
* @param deploymentManager
* the {@link DeploymentManager} tracking the {@link AppLifeCycle} and {@link App}
* @throws Exception
* if any problem severe enough to halt the AppLifeCycle processing
*/
void processBinding(Node node, App app, DeploymentManager deploymentManager) throws Exception;
}
// Private string constants defined to avoid typos on repeatedly used strings
private static final String NODE_UNDEPLOYED = "undeployed";
private static final String NODE_PRE_DEPLOYING = "pre-deploying";
private static final String NODE_DEPLOYING = "deploying";
private static final String NODE_DEPLOYED = "deployed";
private static final String NODE_PRE_STARTING = "pre-starting";
private static final String NODE_STARTING = "starting";
private static final String NODE_STARTED = "started";
private static final String NODE_PRE_STOPPING = "pre-stopping";
private static final String NODE_STOPPING = "stopping";
private static final String NODE_PRE_UNDEPLOYING = "pre-undeploying";
private static final String NODE_UNDEPLOYING = "undeploying";
private Map<Node, List<Binding>> lifecyclebindings = new HashMap<Node, List<Binding>>();
public AppLifeCycle()
{
// Define Default Graph
// undeployed -> deployed
addEdge(NODE_UNDEPLOYED,NODE_PRE_DEPLOYING);
addEdge(NODE_PRE_DEPLOYING,NODE_DEPLOYING);
addEdge(NODE_DEPLOYING,NODE_DEPLOYED);
// deployed -> started
addEdge(NODE_DEPLOYED,NODE_PRE_STARTING);
addEdge(NODE_PRE_STARTING,NODE_STARTING);
addEdge(NODE_STARTING,NODE_STARTED);
// started -> deployed
addEdge(NODE_STARTED,NODE_PRE_STOPPING);
addEdge(NODE_PRE_STOPPING,NODE_STOPPING);
addEdge(NODE_STOPPING,NODE_DEPLOYED);
// deployed -> undeployed
addEdge(NODE_DEPLOYED,NODE_PRE_UNDEPLOYING);
addEdge(NODE_PRE_UNDEPLOYING,NODE_UNDEPLOYING);
addEdge(NODE_UNDEPLOYING,NODE_UNDEPLOYED);
}
public void addBinding(AppLifeCycle.Binding binding)
{
for (String nodeName : binding.getBindingTargets())
{
if (nodeName.equals("*"))
{
// Special Case: Bind to all Nodes
for (Node node : getNodes())
{
bindToNode(node,binding);
}
}
else
{
// Bind to specific node
Node node = getNodeByName(nodeName);
bindToNode(node,binding);
}
}
}
private void bindToNode(Node node, AppLifeCycle.Binding binding)
{
List<Binding> bindings = lifecyclebindings.get(node);
if (bindings == null)
{
bindings = new ArrayList<Binding>();
}
bindings.add(binding);
lifecyclebindings.put(node,bindings);
}
/**
* Get all {@link Node} bound objects.
*
* @return Set of Object(s) for all lifecycle bindings. never null.
*/
public Set<AppLifeCycle.Binding> getBindings()
{
Set<Binding> boundset = new HashSet<Binding>();
for (List<Binding> bindings : lifecyclebindings.values())
{
boundset.addAll(bindings);
}
return boundset;
}
/**
* Get all objects bound to a specific {@link Node}
*
* @return Set of Object(s) for specific lifecycle bindings. never null.
*/
public Set<AppLifeCycle.Binding> getBindings(Node node)
{
Set<Binding> boundset = new HashSet<Binding>();
List<Binding> bindings = lifecyclebindings.get(node);
if (bindings == null)
{
return boundset;
}
boundset.addAll(bindings);
return boundset;
}
public Set<Binding> getBindings(String nodeName)
{
Node node = getNodeByName(nodeName);
return getBindings(node);
}
public void runBindings(Node node, App app, DeploymentManager deploymentManager) throws Throwable
{
List<Binding> bindings = this.lifecyclebindings.get(node);
if (bindings == null)
{
return;
}
for (Binding binding : bindings)
{
Log.info("Calling " + binding.getClass().getName());
binding.processBinding(node,app,deploymentManager);
}
}
}

View File

@ -0,0 +1,33 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy;
import org.eclipse.jetty.util.component.LifeCycle;
/**
* Object responsible for providing {@link App}s to the {@link DeploymentManager}
*/
public interface AppProvider extends LifeCycle
{
/**
* Set the Deployment Manager
*
* @param deploymentManager
* @throws IllegalStateException
* if the provider {@link #isRunning()}.
*/
void setDeploymentManager(DeploymentManager deploymentManager);
}

View File

@ -0,0 +1,561 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import org.eclipse.jetty.deploy.bindings.StandardDeployer;
import org.eclipse.jetty.deploy.bindings.StandardStarter;
import org.eclipse.jetty.deploy.bindings.StandardStopper;
import org.eclipse.jetty.deploy.bindings.StandardUndeployer;
import org.eclipse.jetty.deploy.graph.Node;
import org.eclipse.jetty.deploy.support.ConfigurationManager;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.util.AttributesMap;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
/**
* The Deployment Manager.
* <p>
* Responsibilities:
* <p>
* <img src="doc-files/DeploymentManager_Roles.png">
* <ol>
* <li>Tracking Apps and their LifeCycle Location</li>
* <li>Managing AppProviders and the Apps that they provide.</li>
* <li>Executing AppLifeCycle on App based on current and desired LifeCycle Location.</li>
* </ol>
* <p>
* <img src="doc-files/DeploymentManager.png">
*/
public class DeploymentManager extends AbstractLifeCycle
{
/**
* Represents a single tracked app within the deployment manager.
*/
public class AppEntry
{
/**
* Version of the app.
*
* Note: Auto-increments on each {@link DeploymentManager#addApp(App)}
*/
private int version;
/**
* The app being tracked.
*/
private App app;
/**
* The lifecycle node location of this App
*/
private Node lifecyleNode;
/**
* Tracking the various AppState timestamps (in system milliseconds)
*/
private Map<Node, Long> stateTimestamps = new HashMap<Node, Long>();
public App getApp()
{
return app;
}
public Node getLifecyleNode()
{
return lifecyleNode;
}
public Map<Node, Long> getStateTimestamps()
{
return stateTimestamps;
}
public int getVersion()
{
return version;
}
void setLifeCycleNode(Node node)
{
this.lifecyleNode = node;
this.stateTimestamps.put(node,Long.valueOf(System.currentTimeMillis()));
}
}
private List<AppProvider> providers = new ArrayList<AppProvider>();
private AppLifeCycle lifecycle = new AppLifeCycle();
private 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";
/**
* Receive an app for processing.
*
* Most commonly used by the various {@link AppProvider} implementations.
*/
public void addApp(App app)
{
Log.info("App Added: " + app.getOriginId());
AppEntry entry = new AppEntry();
entry.app = app;
entry.setLifeCycleNode(lifecycle.getNodeByName("undeployed"));
apps.add(entry);
if (defaultLifeCycleGoal != null)
{
// Immediately attempt to go to default lifecycle state
this.requestAppGoal(entry,defaultLifeCycleGoal);
}
}
public void addAppProvider(AppProvider provider)
{
providers.add(provider);
if (isStarted() || isStarting())
{
startAppProvider(provider);
}
}
public void addLifeCycleBinding(AppLifeCycle.Binding binding)
{
lifecycle.addBinding(binding);
}
@Override
protected void doStart() throws Exception
{
if (useStandardBindings)
{
Log.info("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)
{
startAppProvider(provider);
}
super.doStart();
}
@Override
protected void doStop() throws Exception
{
Log.info("Stopping all Providers: " + providers.size());
// Stop all of the AppProviders
for (AppProvider provider : providers)
{
try
{
provider.stop();
}
catch (Exception e)
{
Log.warn("Unable to start AppProvider",e);
}
}
super.doStop();
}
private AppEntry findAppByContextId(String contextId)
{
if (contextId == null)
{
return null;
}
for (AppEntry entry : apps)
{
if (contextId.equals(entry.app.getContextId()))
{
return entry;
}
}
return null;
}
private AppEntry findAppByOriginId(String originId)
{
if (originId == null)
{
return null;
}
for (AppEntry entry : apps)
{
if (originId.equals(entry.app.getOriginId()))
{
return entry;
}
}
return null;
}
public App getAppByContextId(String contextId)
{
AppEntry entry = findAppByContextId(contextId);
if (entry == null)
{
return null;
}
return entry.app;
}
public App getAppByOriginId(String originId)
{
AppEntry entry = findAppByOriginId(originId);
if (entry == null)
{
return null;
}
return entry.app;
}
public Collection<AppEntry> getAppEntries()
{
return apps;
}
public Collection<AppProvider> getAppProviders()
{
return providers;
}
public Collection<App> getApps()
{
List<App> ret = new ArrayList<App>();
for (AppEntry entry : apps)
{
ret.add(entry.app);
}
return ret;
}
/**
* Get Set of {@link App}s by {@link Node}
*
* @param state
* the state to look for.
* @return
*/
public Collection<App> getApps(Node node)
{
List<App> ret = new ArrayList<App>();
for (AppEntry entry : apps)
{
if (entry.lifecyleNode == node)
{
ret.add(entry.app);
}
}
return ret;
}
public List<App> getAppsWithSameContext(App app)
{
List<App> ret = new ArrayList<App>();
if (app == null)
{
return ret;
}
String contextId = app.getContextId();
if (contextId == null)
{
// No context? Likely not deployed or started yet.
return ret;
}
for (AppEntry entry : apps)
{
if (entry.app.equals(app))
{
// Its the input app. skip it.
// TODO: is this filter needed?
continue;
}
if (contextId.equals(entry.app.getContextId()))
{
ret.add(entry.app);
}
}
return ret;
}
/**
* Get a contextAttribute that will be set for every Context deployed by this provider.
*
* @param name
* @return
*/
public Object getAttribute(String name)
{
return contextAttributes.getAttribute(name);
}
public ConfigurationManager getConfigurationManager()
{
return configurationManager;
}
public AttributesMap getContextAttributes()
{
return contextAttributes;
}
public ContextHandlerCollection getContexts()
{
return contexts;
}
public String getDefaultLifeCycleGoal()
{
return defaultLifeCycleGoal;
}
public AppLifeCycle getLifeCycle()
{
return lifecycle;
}
public Server getServer()
{
if (contexts == null)
{
return null;
}
return contexts.getServer();
}
/**
* Remove the app from the tracking of the DeploymentManager
*
* @param app
* if the app is Unavailable remove it from the deployment manager.
*/
public void removeApp(App app)
{
ListIterator<AppEntry> it = apps.listIterator();
while (it.hasNext())
{
AppEntry entry = it.next();
if (entry.app.equals(app) && "undeployed".equals(entry.lifecyleNode.getName()))
{
Log.info("Remove App: " + entry.app);
it.remove();
}
}
}
public void removeAppProvider(AppProvider provider)
{
providers.remove(provider);
try
{
provider.stop();
}
catch (Exception e)
{
Log.warn("Unable to stop Provider",e);
}
}
/**
* Remove a contextAttribute that will be set for every Context deployed by this provider.
*
* @param name
*/
public void removeAttribute(String name)
{
contextAttributes.removeAttribute(name);
}
/**
* Move an {@link App} through the {@link AppLifeCycle} to the desired {@link Node}, executing each lifecycle step
* in the process to reach the desired state.
*
* @param app
* the app to move through the process
* @param nodeName
* the name of the node to attain
*/
public void requestAppGoal(App app, String nodeName)
{
AppEntry appentry = findAppByContextId(app.getContextId());
if (appentry == null)
{
appentry = findAppByOriginId(app.getOriginId());
if (appentry == null)
{
throw new IllegalStateException("App not being tracked by Deployment Manager: " + app);
}
}
requestAppGoal(appentry,nodeName);
}
/**
* Move an {@link App} through the {@link AppLifeCycle} to the desired {@link Node}, executing each lifecycle step
* in the process to reach the desired state.
*
* @param appentry
* the internal appentry to move through the process
* @param nodeName
* the name of the node to attain
*/
private void requestAppGoal(AppEntry appentry, String nodeName)
{
Node destinationNode = lifecycle.getNodeByName(nodeName);
// Compute lifecycle steps
List<Node> path = lifecycle.findPath(appentry.lifecyleNode,destinationNode);
if (path.isEmpty())
{
// nothing to do. already there.
return;
}
// Execute each Node binding. Stopping at any thrown exception.
try
{
Iterator<Node> it = path.iterator();
if (it.hasNext()) // Any entries?
{
// The first entry in the path is always the start node
// We don't want to run bindings on that entry (again)
it.next(); // skip first entry
while (it.hasNext())
{
Node node = it.next();
Log.info("Executing Node: " + node);
lifecycle.runBindings(node,appentry.app,this);
appentry.setLifeCycleNode(node);
}
}
}
catch (Throwable t)
{
Log.warn("Unable to reach node goal: " + nodeName,t);
}
}
/**
* Move an {@link App} through the {@link AppLifeCycle} to the desired {@link Node}, executing each lifecycle step
* in the process to reach the desired state.
*
* @param appId
* the id of the app to move through the process
* @param nodeName
* the name of the node to attain
*/
public void requestAppGoal(String appId, String nodeName)
{
AppEntry appentry = findAppByContextId(appId);
if (appentry == null)
{
appentry = findAppByOriginId(appId);
if (appentry == null)
{
throw new IllegalStateException("App not being tracked by Deployment Manager: " + appId);
}
}
requestAppGoal(appentry,nodeName);
}
/**
* Set a contextAttribute that will be set for every Context deployed by this provider.
*
* @param name
* @param value
*/
public void setAttribute(String name, Object value)
{
contextAttributes.setAttribute(name,value);
}
public void setConfigurationManager(ConfigurationManager configurationManager)
{
this.configurationManager = configurationManager;
}
public void setContextAttributes(AttributesMap contextAttributes)
{
this.contextAttributes = contextAttributes;
}
public void setContexts(ContextHandlerCollection contexts)
{
this.contexts = contexts;
}
public void setDefaultLifeCycleGoal(String defaultLifeCycleState)
{
this.defaultLifeCycleGoal = defaultLifeCycleState;
}
private void startAppProvider(AppProvider provider)
{
try
{
provider.setDeploymentManager(this);
provider.start();
}
catch (Exception e)
{
Log.warn("Unable to start AppProvider",e);
}
}
public void undeployAll()
{
Log.info("Undeploy (All) started");
for (AppEntry appentry : apps)
{
Log.info("Undeploy: " + appentry);
requestAppGoal(appentry,"undeployed");
}
Log.info("Undeploy (All) completed");
}
public boolean isUseStandardBindings()
{
return useStandardBindings;
}
public void setUseStandardBindings(boolean useStandardBindings)
{
this.useStandardBindings = useStandardBindings;
}
}

View File

@ -0,0 +1,41 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy.bindings;
import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppLifeCycle;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.graph.Node;
import org.eclipse.jetty.server.handler.ContextHandler;
public class StandardDeployer implements AppLifeCycle.Binding
{
public String[] getBindingTargets()
{
return new String[]
{ "deploying" };
}
public void processBinding(Node node, App app, DeploymentManager deploymentManager) throws Exception
{
ContextHandler handler = app.getContextHandler(deploymentManager);
if (handler == null)
{
throw new NullPointerException("No Handler created for App: " + app);
}
deploymentManager.getContexts().addHandler(handler);
}
}

View File

@ -0,0 +1,46 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy.bindings;
import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppLifeCycle;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.graph.Node;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.log.Log;
public class StandardStarter implements AppLifeCycle.Binding
{
public String[] getBindingTargets() {
return new String[] { "starting" };
}
public void processBinding(Node node, App app, DeploymentManager deploymentManager) throws Exception
{
ContextHandler handler = app.getContextHandler(deploymentManager);
if (!handler.isStarted())
{
handler.start();
}
// Remove other apps at same context
for (App other : deploymentManager.getAppsWithSameContext(app))
{
Log.info("Removing apps with same context: " + other);
deploymentManager.requestAppGoal(other,"undeployed");
}
}
}

View File

@ -0,0 +1,40 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy.bindings;
import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppLifeCycle;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.graph.Node;
import org.eclipse.jetty.server.handler.ContextHandler;
public class StandardStopper implements AppLifeCycle.Binding
{
public String[] getBindingTargets()
{
return new String[]
{ "stopping" };
}
public void processBinding(Node node, App app, DeploymentManager deploymentManager) throws Exception
{
ContextHandler handler = app.getContextHandler(deploymentManager);
if (!handler.isStopped())
{
handler.stop();
}
}
}

View File

@ -0,0 +1,67 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy.bindings;
import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppLifeCycle;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.graph.Node;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.util.log.Log;
public class StandardUndeployer implements AppLifeCycle.Binding
{
public String[] getBindingTargets()
{
return new String[]
{ "undeploying" };
}
public void processBinding(Node node, App app, DeploymentManager deploymentManager) throws Exception
{
ContextHandler handler = app.getContextHandler(deploymentManager);
ContextHandlerCollection chcoll = deploymentManager.getContexts();
recursiveRemoveContext(chcoll,handler);
deploymentManager.removeApp(app);
}
private void recursiveRemoveContext(HandlerCollection coll, ContextHandler context)
{
Handler children[] = coll.getHandlers();
int originalCount = children.length;
for (int i = 0, n = children.length; i < n; i++)
{
Handler child = children[i];
Log.info("Child handler: " + child);
if (child.equals(context))
{
Log.info("Removing handler: " + child);
coll.removeHandler(child);
Log.info(String.format("After removal: %d (originally %d)",coll.getHandlers().length,originalCount));
}
else if (child instanceof HandlerCollection)
{
recursiveRemoveContext((HandlerCollection)child,context);
}
}
}
}

View File

@ -0,0 +1,78 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy.graph;
/**
* Basic Graph Edge
*/
public class Edge
{
private Node from;
private Node to;
public Edge(Node from, Node to)
{
this.from = from;
this.to = to;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((from == null)?0:from.hashCode());
result = prime * result + ((to == null)?0:to.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Edge other = (Edge)obj;
if (from == null)
{
if (other.from != null)
return false;
}
else if (!from.equals(other.from))
return false;
if (to == null)
{
if (other.to != null)
return false;
}
else if (!to.equals(other.to))
return false;
return true;
}
public Node getFrom()
{
return from;
}
public Node getTo()
{
return to;
}
}

View File

@ -0,0 +1,385 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy.graph;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import java.util.Stack;
/**
* Basic directed graph implementation
*/
public class Graph
{
private class EdgeSearch
{
private Set<Edge> seenEdges = new HashSet<Edge>();
private List<NodePath> paths = new ArrayList<NodePath>();
public EdgeSearch(Node from)
{
NodePath path = new NodePath();
path.add(from);
paths.add(path);
}
public void breadthFirst(Node destination)
{
// Test existing edge endpoints
if (hasReachedDestination(destination))
{
// Found our destination!
// Now remove the other paths that do not end at the destination
ListIterator<NodePath> pathiter = paths.listIterator();
while (pathiter.hasNext())
{
NodePath path = pathiter.next();
if (path.lastNode() != destination)
{
pathiter.remove();
}
}
return;
}
List<NodePath> extrapaths = null;
// Add next unseen segments to paths.
boolean pathsAdded = false;
for (NodePath path : paths)
{
List<Edge> next = nextUnseenEdges(path);
if (next.size() == 0)
{
continue; // no new edges
}
pathsAdded = true;
// More than 1 path out? Split it.
if (next.size() > 1)
{
if (extrapaths == null)
{
extrapaths = new ArrayList<NodePath>();
}
// Split path for other edges
for (int i = 1, n = next.size(); i < n; i++)
{
NodePath split = path.forkPath();
// Add segment to split'd path
split.add(next.get(i).getTo());
// Add to extra paths
extrapaths.add(split);
}
}
// Add edge to current path
Edge edge = next.get(0);
path.add(edge.getTo());
// Mark all edges as seen
for (Edge e : next)
{
seenEdges.add(e);
}
}
// Do we have any extra paths?
if (extrapaths != null)
{
paths.addAll(extrapaths);
}
if (pathsAdded)
{
// recurse
breadthFirst(destination);
}
}
public NodePath getShortestPath()
{
NodePath shortest = null;
int shortestlen = Integer.MAX_VALUE;
for (NodePath path : paths)
{
if (shortest == null)
{
shortest = path;
continue;
}
int len = path.length();
if (len < shortestlen)
{
shortest = path;
shortestlen = len;
}
}
return shortest;
}
private boolean hasReachedDestination(Node destination)
{
for (NodePath path : paths)
{
if (path.lastNode() == destination)
{
return true;
}
}
return false;
}
private List<Edge> nextUnseenEdges(NodePath path)
{
List<Edge> next = new ArrayList<Edge>();
for (Edge edge : findEdgesFrom(path.lastNode()))
{
if (seenEdges.contains(edge) == false)
{
next.add(edge);
}
}
return next;
}
}
private class NodePath implements Iterable<Node>
{
private Stack<Node> path;
public NodePath()
{
path = new Stack<Node>();
}
public void add(Node node)
{
path.push(node);
}
public NodePath forkPath()
{
NodePath ep = new NodePath();
for (Node node : this)
{
ep.add(node);
}
return ep;
}
public Collection<Node> getCollection()
{
return path;
}
public Iterator<Node> iterator()
{
return path.iterator();
}
public Node lastNode()
{
return path.peek();
}
public int length()
{
return path.size();
}
}
private Set<Node> nodes = new HashSet<Node>();
private Set<Edge> edges = new HashSet<Edge>();
public void addEdge(Edge edge)
{
this.edges.add(edge);
}
public void addEdge(String from, String to)
{
Node fromNode = null;
Node toNode = null;
try
{
fromNode = getNodeByName(from);
}
catch (NodeNotFoundException e)
{
fromNode = new Node(from);
addNode(fromNode);
}
try
{
toNode = getNodeByName(to);
}
catch (NodeNotFoundException e)
{
toNode = new Node(to);
addNode(toNode);
}
Edge edge = new Edge(fromNode,toNode);
addEdge(edge);
}
public void addNode(Node node)
{
this.nodes.add(node);
}
/**
* Find all edges that are connected to the specific node, both as an outgoing {@link Edge#getFrom()} or incoming
* {@link Edge#getTo()} end point.
*
* @param node
* the node with potential end points
* @return the set of edges connected to the node
*/
public Set<Edge> findEdges(Node node)
{
Set<Edge> fromedges = new HashSet<Edge>();
for (Edge edge : this.edges)
{
if ((edge.getFrom() == node) || (edge.getTo() == node))
{
fromedges.add(edge);
}
}
return fromedges;
}
/**
* Find all edges that are connected {@link Edge#getFrom()} the specific node.
*
* @param node
* the node with potential edges from it
* @return the set of edges from the node
*/
public Set<Edge> findEdgesFrom(Node from)
{
Set<Edge> fromedges = new HashSet<Edge>();
for (Edge edge : this.edges)
{
if (edge.getFrom() == from)
{
fromedges.add(edge);
}
}
return fromedges;
}
/**
* Using BFS (Breadth First Search) return the path from a any arbitrary node to any other.
*
* @param from
* the node from
* @param to
* the node to
* @return the path to take
*/
public List<Node> findPath(Node from, Node to)
{
if (from == to)
{
return Collections.emptyList();
}
// Perform a Breadth First Search (BFS) of the tree.
EdgeSearch search = new EdgeSearch(from);
search.breadthFirst(to);
NodePath nodepath = search.getShortestPath();
List<Node> path = new ArrayList<Node>();
path.addAll(nodepath.getCollection());
return path;
}
public Set<Edge> getEdges()
{
return edges;
}
public Node getNodeByName(String name)
{
for (Node node : nodes)
{
if (node.getName().equals(name))
{
return node;
}
}
throw new NodeNotFoundException("Unable to find node: " + name);
}
public Set<Node> getNodes()
{
return nodes;
}
public void removeEdge(Edge edge)
{
this.edges.remove(edge);
}
public void removeEdge(String fromNodeName, String toNodeName)
{
Node fromNode = getNodeByName(fromNodeName);
Node toNode = getNodeByName(toNodeName);
Edge edge = new Edge(fromNode,toNode);
removeEdge(edge);
}
public void removeNode(Node node)
{
this.nodes.remove(node);
}
public void setEdges(Set<Edge> edges)
{
this.edges = edges;
}
public void setNodes(Set<Node> nodes)
{
this.nodes = nodes;
}
}

View File

@ -0,0 +1,31 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy.graph;
public class ImpossiblePathException extends RuntimeException
{
private static final long serialVersionUID = 8423437443748056467L;
public ImpossiblePathException(String message, Throwable cause)
{
super(message,cause);
}
public ImpossiblePathException(String message)
{
super(message);
}
}

View File

@ -0,0 +1,69 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy.graph;
/**
* Basic Graph Node
*/
public class Node
{
private String name;
public Node(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
@Override
public String toString()
{
return "Node[" + name + "]";
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((name == null)?0:name.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Node other = (Node)obj;
if (name == null)
{
if (other.name != null)
return false;
}
else if (!name.equals(other.name))
return false;
return true;
}
}

View File

@ -0,0 +1,34 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy.graph;
/**
* NodeNotFoundException for when a referenced node cannot be found.
*/
public class NodeNotFoundException extends RuntimeException
{
private static final long serialVersionUID = -7126395440535048386L;
public NodeNotFoundException(String message, Throwable cause)
{
super(message,cause);
}
public NodeNotFoundException(String message)
{
super(message);
}
}

View File

@ -0,0 +1,226 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy.providers;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Collections;
import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppProvider;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.util.Scanner;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.Resource;
/**
* Backwards Compatible AppProvider for Monitoring a Contexts directory and deploying All Contexts.
*
* Similar in scope to the original org.eclipse.jetty.deploy.ContextDeployer
*/
public class MonitoredDirAppProvider extends AbstractLifeCycle implements AppProvider, Scanner.DiscreteListener
{
class ExtensionFilenameFilter implements FilenameFilter
{
boolean acceptXml = true;
boolean acceptWar = true;
public boolean accept(File dir, String name)
{
String lowername = name.toLowerCase();
if (acceptXml && (lowername.endsWith(".xml")))
{
return true;
}
if (acceptWar && (lowername.endsWith(".war")))
{
return true;
}
return false;
}
}
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;
public MonitoredDirAppProvider()
{
scanner = new Scanner();
filenamefilter = new ExtensionFilenameFilter();
}
private void addConfiguredContextApp(String filename)
{
String originId = filename;
App app = new App(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
{
Log.info("fileAdded(" + filename + ")");
addConfiguredContextApp(filename);
}
public void fileChanged(String filename) throws Exception
{
Log.info("fileChanged(" + filename + ")");
addConfiguredContextApp(filename);
}
public void fileRemoved(String filename) throws Exception
{
// TODO: How to determine ID from filename that doesn't exist?
/*
Log.info("fileRemoved(" + filename + ")");
addConfiguredContextApp(filename);
*/
}
public String getDefaultsDescriptor()
{
return defaultsDescriptor;
}
public Resource getMonitoredDir()
{
return monitoredDir;
}
public int getScanInterval()
{
return scanInterval;
}
public boolean isExtractWars()
{
return extractWars;
}
public boolean isParentLoaderPriority()
{
return parentLoaderPriority;
}
public boolean isRecursive()
{
return recursive;
}
public void setAcceptContextXmlFiles(boolean flag)
{
filenamefilter.acceptXml = flag;
}
public void setAcceptWarFiles(boolean flag)
{
filenamefilter.acceptWar = flag;
}
public void setDefaultsDescriptor(String defaultsDescriptor)
{
this.defaultsDescriptor = defaultsDescriptor;
}
public void setExtractWars(boolean extractWars)
{
this.extractWars = extractWars;
}
public void setMonitoredDir(Resource contextsDir)
{
this.monitoredDir = contextsDir;
}
/**
* @param dir
* Directory to scan for context descriptors or war files
*/
public void setMonitoredDir(String dir)
{
try
{
monitoredDir = Resource.newResource(dir);
}
catch (Exception e)
{
throw new IllegalArgumentException(e);
}
}
public void setParentLoaderPriority(boolean parentLoaderPriority)
{
this.parentLoaderPriority = parentLoaderPriority;
}
public void setRecursive(boolean recursive)
{
this.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.scan();
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,27 @@
// ========================================================================
// Copyright (c) 2006-2009 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy.support;
import java.util.Map;
/**
* ConfigurationManager
*
* Type for allow injection of property values
* for replacement in jetty xml files during deployment.
*/
public interface ConfigurationManager
{
public Map<?, ?> getProperties();
}

View File

@ -0,0 +1,66 @@
// ========================================================================
// Copyright (c) 2006-2009 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy.support;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Map;
import java.util.Properties;
import org.eclipse.jetty.util.resource.Resource;
/**
* FileConfigurationManager
*
* Supplies properties defined in a file.
*/
public class FileConfigurationManager implements ConfigurationManager
{
private Resource _file;
private Properties _properties = new Properties();
public FileConfigurationManager()
{
}
public void setFile(String filename) throws MalformedURLException, IOException
{
_file = Resource.newResource(filename);
}
/**
* @see org.eclipse.jetty.deploy.ConfigurationManager#getProperties()
*/
public Map<?, ?> getProperties()
{
try
{
loadProperties();
return _properties;
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
private void loadProperties() throws FileNotFoundException, IOException
{
if (_properties.isEmpty())
{
_properties.load(_file.getInputStream());
}
}
}

View File

@ -0,0 +1,76 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy.util;
import java.io.File;
/**
* Simple, yet surprisingly common utility methods for identifying various file types commonly seen and worked with in a
* deployment scenario.
*/
public class FileID
{
/**
* Is the path a Web Archive?
*
* @param path
* the path to test.
* @return True if a .war or .jar or exploded web directory
* @see FileID#isWebArchiveFile(File)
*/
public static boolean isWebArchive(File path)
{
if (path.isFile())
{
String name = path.getName().toLowerCase();
return (name.endsWith(".war") || name.endsWith(".jar"));
}
File webInf = new File(path,"WEB-INF");
File webXml = new File(webInf,"web.xml");
return webXml.exists() && webXml.isFile();
}
/**
* Is the path a Web Archive File (not directory)
*
* @param path
* the path to test.
* @return True if a .war or .jar file.
* @see FileID#isWebArchive(File)
*/
public static boolean isWebArchiveFile(File path)
{
if (!path.isFile())
{
return false;
}
String name = path.getName().toLowerCase();
return (name.endsWith(".war") || name.endsWith(".jar"));
}
public static boolean isXmlFile(File path)
{
if (!path.isFile())
{
return false;
}
String name = path.getName().toLowerCase();
return name.endsWith(".xml");
}
}

View File

@ -0,0 +1,39 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.webapp.deploy;
import java.util.logging.Logger;
import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppLifeCycle;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.graph.Node;
public class DeployAuditLogBinding implements AppLifeCycle.Binding
{
private Logger logger = Logger.getLogger("audit.deploy");
public String[] getBindingTargets()
{
return new String[]
{ "*" };
}
public void processBinding(Node node, App app, DeploymentManager deploymentManager) throws Exception
{
logger.info("Reached LifeCycle " + node.getName() + " on app " + app.getOriginId());
}
}

View File

@ -0,0 +1,95 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.webapp.deploy;
import java.io.File;
import java.net.URI;
import java.util.Collection;
import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppLifeCycle;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.deploy.graph.Node;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.webapp.verifier.RuleSet;
import org.eclipse.jetty.webapp.verifier.Severity;
import org.eclipse.jetty.webapp.verifier.Violation;
import org.eclipse.jetty.webapp.verifier.WebappVerifier;
/**
* Deploy Binding for the Webapp Verifier.
*
* Will verify the webapp being deployed, to ensure that it satisfies the ruleset configured.
*/
public class WebappVerifierBinding implements AppLifeCycle.Binding
{
private String rulesetPath;
public String getRulesetPath()
{
return rulesetPath;
}
public void setRulesetPath(String rulesetPath)
{
this.rulesetPath = rulesetPath;
}
public String[] getBindingTargets()
{
return new String[]
{ "pre-deploying" };
}
public void processBinding(Node node, App app, DeploymentManager deploymentManager) throws Exception
{
File rulesetFile = new File(this.rulesetPath);
RuleSet ruleset = RuleSet.load(rulesetFile);
URI warURI = app.getArchivePath().toURI();
WebappVerifier verifier = ruleset.createWebappVerifier(warURI);
verifier.visitAll();
Collection<Violation> violations = verifier.getViolations();
if (violations.size() <= 0)
{
// Nothing to report.
Log.info("Webapp Verifier - All Rules Passed - No Violations");
return;
}
boolean haltWebapp = false;
Log.info("Webapp Verifier Found " + violations.size() + " violations.");
for (Violation violation : violations)
{
if (violation.getSeverity() == Severity.ERROR)
{
haltWebapp = true;
}
Log.info(violation.toString());
}
if (haltWebapp)
{
throw new IllegalStateException("Webapp Failed Webapp Verification");
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -0,0 +1,482 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generated by Graphviz version 2.20.2 (Mon Mar 30 10:11:53 UTC 2009)
For user: (joakim) Joakim Erdfelt,,, -->
<!-- Title: G Pages: 1 -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="765"
height="900"
viewBox="0 0 327 590"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.46"
sodipodi:docname="AppLifecycle.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.0"
inkscape:export-filename="/home/joakim/code/webtide/jetty7-git/sandbox/jetty-deploy-manager/src/main/javadoc/org/eclipse/jetty/deploy/doc-files/AppLifecycle.png"
inkscape:export-xdpi="40"
inkscape:export-ydpi="40">
<metadata
id="metadata184">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs182">
<marker
inkscape:stockid="Arrow2Lstart"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow2Lstart"
style="overflow:visible">
<path
id="path4328"
style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
transform="scale(1.1) translate(1,0)" />
</marker>
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Lend"
style="overflow:visible">
<path
id="path3605"
style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.97309,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z"
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
</marker>
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL"
style="overflow:visible">
<path
id="path3727"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="scale(0.8,0.8)" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend"
style="overflow:visible">
<path
id="path3587"
d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 368.75 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="408.75 : 368.75 : 1"
inkscape:persp3d-origin="204.375 : 245.83333 : 1"
id="perspective186" />
<title
id="title5">G</title>
<title
id="title10">incoming_app</title>
<title
id="title17">command_deploy</title>
<title
id="title33">state_deployed</title>
</defs>
<sodipodi:namedview
inkscape:window-height="1151"
inkscape:window-width="1920"
inkscape:pageshadow="2"
inkscape:pageopacity="1"
guidetolerance="10"
gridtolerance="10.0"
objecttolerance="13"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#ffffff"
id="base"
showgrid="false"
inkscape:zoom="0.92828283"
inkscape:cx="387.34766"
inkscape:cy="428.51283"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:current-layer="svg2"
showguides="true"
inkscape:guide-bbox="true"
inkscape:document-units="cm"
units="in"
inkscape:snap-guide="true"
inkscape:snap-bbox="true"
inkscape:bbox-paths="false"
inkscape:bbox-nodes="false"
inkscape:snap-intersection-line-segments="true"
inkscape:object-paths="true"
inkscape:object-nodes="true"
inkscape:snap-center="false">
<inkscape:grid
type="xygrid"
id="grid3514"
dotted="true"
visible="true"
enabled="true"
units="cm"
spacingx="0.25cm"
spacingy="0.25cm"
empspacing="5" />
</sodipodi:namedview>
<g
id="g3445"
transform="matrix(1.2491264,0,0,1.2491264,109.41031,84.061397)">
<polygon
style="fill:#ffa500;stroke:#ffa500;stroke-width:0.80055952"
points="228,-510 144,-510 144,-468 228,-468 228,-510 "
id="polygon3447"
transform="translate(4,586)" />
<text
x="190"
y="92.600006"
style="font-size:14.39999962px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
id="text3449"
sodipodi:linespacing="125%">
<tspan
sodipodi:role="line"
id="tspan3451"
x="190"
y="92.600006">Phase</tspan>
<tspan
sodipodi:role="line"
id="tspan3453"
x="190"
y="110.60001">DEPLOY</tspan>
</text>
</g>
<g
id="g3917">
<polygon
transform="matrix(1.6111428,0,0,1.2491264,-118.06476,648.90074)"
id="polygon3491"
points="230,-432 138,-432 138,-390 230,-390 230,-432 "
style="fill:#00ffff;stroke:#00ffff;stroke-width:0.70490372" />
<text
sodipodi:linespacing="125%"
id="text3493"
style="font-size:17.98741913px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
y="130.01364"
x="178.38551">
<tspan
sodipodi:role="line"
id="tspan3503"
x="178.38551"
y="130.01364">State</tspan>
<tspan
sodipodi:role="line"
id="tspan3505"
x="178.38551"
y="152.49792">UNAVAILABLE</tspan>
</text>
</g>
<g
id="g3549"
transform="matrix(1.2491264,0,0,1.2491264,-227.0731,84.061397)">
<polygon
style="fill:#ffa500;stroke:#ffa500;stroke-width:0.80055952"
points="228,-510 144,-510 144,-468 228,-468 228,-510 "
id="polygon3551"
transform="translate(4,586)" />
<text
x="190"
y="92.600006"
style="font-size:14.39999962px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
id="text3553"
sodipodi:linespacing="125%">
<tspan
sodipodi:role="line"
id="tspan3559"
x="190"
y="92.600006">Phase</tspan>
<tspan
sodipodi:role="line"
id="tspan3561"
x="190"
y="110.60001">UNDEPLOY</tspan>
</text>
</g>
<g
id="g3483"
transform="matrix(1.2491264,0,0,1.2491264,-102.88457,7.5836656)">
<ellipse
style="fill:#c1c1c1;fill-opacity:1;stroke:none"
cx="222"
cy="-564"
rx="96.784599"
ry="18"
id="ellipse3485"
sodipodi:cx="222"
sodipodi:cy="-564"
sodipodi:rx="96.784599"
sodipodi:ry="18"
transform="translate(4,586)" />
<text
x="226"
y="26.099976"
style="font-size:14.39999962px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
id="text3487"
sodipodi:linespacing="125%">Incoming WebApp</text>
</g>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.9988189;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#Arrow2Lend)"
d="M 180.40071,57.523395 L 180.40071,108.36997"
id="path2594"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cc"
id="path3923"
d="M 252.49807,154.27312 L 294.28101,190.29424"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 294.28101,213.09705 L 236.46989,265.1469"
id="path3925"
sodipodi:nodetypes="cc" />
<g
id="g3469"
transform="matrix(1.2491264,0,0,1.2491264,-55.825685,55.721845)">
<polygon
style="fill:#00ffff;stroke:#00ffff;stroke-width:0.80055952"
points="230,-432 138,-432 138,-390 230,-390 230,-432 "
id="polygon3471"
transform="translate(4,586)" />
<text
x="188"
y="170.60001"
style="font-size:14.39999962px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
id="text3473"
sodipodi:linespacing="125%">
<tspan
sodipodi:role="line"
id="tspan3475"
x="188"
y="170.60001">State</tspan>
<tspan
sodipodi:role="line"
id="tspan3477"
x="188"
y="188.60001">DEPLOYED</tspan>
</text>
</g>
<g
id="g5403"
transform="matrix(1.2491264,0,0,1.2491264,-56.840602,191.55677)">
<polygon
style="fill:#00ffff;stroke:#00ffff;stroke-width:0.80055952"
points="230,-432 138,-432 138,-390 230,-390 230,-432 "
id="polygon5405"
transform="translate(4,586)" />
<text
x="188"
y="170.60001"
style="font-size:14.39999962px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
id="text5407"
sodipodi:linespacing="125%">
<tspan
sodipodi:role="line"
id="tspan5417"
x="188"
y="170.60001">State</tspan>
<tspan
sodipodi:role="line"
id="tspan5419"
x="188"
y="188.60001">STAGED</tspan>
</text>
</g>
<path
sodipodi:nodetypes="cc"
id="path3929"
d="M 120.53534,398.20562 L 62.724228,352.50272"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
id="path3935"
d="M 294.28101,355.83348 L 235.45498,398.20563"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<g
transform="matrix(1.2491264,0,0,1.2491264,109.41031,219.89633)"
id="g3535">
<polygon
transform="translate(4,586)"
id="polygon3537"
points="228,-510 144,-510 144,-468 228,-468 228,-510 "
style="fill:#ffa500;stroke:#ffa500;stroke-width:0.80055952" />
<text
sodipodi:linespacing="125%"
id="text3539"
style="font-size:14.39999962px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
y="92.600006"
x="190">
<tspan
sodipodi:role="line"
id="tspan3545"
x="190"
y="92.600006">Phase</tspan>
<tspan
sodipodi:role="line"
id="tspan3547"
x="190"
y="110.60001">STAGE</tspan>
</text>
</g>
<path
sodipodi:nodetypes="cc"
id="path3927"
d="M 236.46989,284.21436 L 293.65647,330.6791"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
id="path3941"
d="M 62.724228,186.76323 L 104.27295,153.52683"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
id="path3943"
d="M 121.55027,263.8367 L 62.724228,212.94524"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<text
x="-10.835248"
y="23.769073"
style="font-size:20.46376419px;font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:100%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans Bold Italic"
id="text2456"
sodipodi:linespacing="100%">
<tspan
sodipodi:role="line"
id="tspan2460"
x="-10.835244"
y="23.769073"
style="font-size:20.46376419px;font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:100%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans Bold Italic">Deployment</tspan>
<tspan
sodipodi:role="line"
x="-10.835247"
y="44.232838"
id="tspan2464"
style="font-size:20.46376419px;font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:100%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans Bold Italic">Lifecycle</tspan>
</text>
<g
id="g2472"
transform="matrix(1.2491264,0,0,1.2491264,109.41031,355.73126)">
<polygon
style="fill:#ffa500;stroke:#ffa500;stroke-width:0.80055952"
points="228,-510 144,-510 144,-468 228,-468 228,-510 "
id="polygon2474"
transform="translate(4,586)" />
<text
x="190"
y="92.600006"
style="font-size:14.39999962px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
id="text2476"
sodipodi:linespacing="125%">
<tspan
y="92.600006"
x="190"
id="tspan2478"
sodipodi:role="line">Phase</tspan>
<tspan
y="110.60001"
x="190"
id="tspan2480"
sodipodi:role="line">START</tspan>
</text>
</g>
<g
id="g2482"
transform="matrix(1.2491264,0,0,1.2491264,-227.0731,219.89633)">
<polygon
style="fill:#ffa500;stroke:#ffa500;stroke-width:0.80055952"
points="228,-510 144,-510 144,-468 228,-468 228,-510 "
id="polygon2484"
transform="translate(4,586)" />
<text
x="190"
y="92.600006"
style="font-size:14.39999962px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
id="text2486"
sodipodi:linespacing="125%">
<tspan
y="92.600006"
x="190"
id="tspan2488"
sodipodi:role="line">Phase</tspan>
<tspan
y="110.60001"
x="190"
id="tspan2490"
sodipodi:role="line">STOP</tspan>
</text>
</g>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 236.46989,420.04929 L 293.65647,466.51403"
id="path2492"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 62.724228,326.37326 L 121.55027,286.42657"
id="path2494"
sodipodi:nodetypes="cc" />
<g
transform="matrix(1.2491264,0,0,1.2491264,-56.840602,327.3917)"
id="g2551">
<polygon
transform="translate(4,586)"
id="polygon2553"
points="230,-432 138,-432 138,-390 230,-390 230,-432 "
style="fill:#00ffff;stroke:#00ffff;stroke-width:0.80055952" />
<text
sodipodi:linespacing="125%"
id="text2555"
style="font-size:14.39999962px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
y="170.60001"
x="188">
<tspan
y="170.60001"
x="188"
id="tspan2557"
sodipodi:role="line">State</tspan>
<tspan
y="188.60001"
x="188"
id="tspan2559"
sodipodi:role="line">STARTED</tspan>
</text>
</g>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 120.53534,536.86536 L 23.883096,367.29325"
id="path2561"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 294.28101,491.66841 L 235.45498,545.3398"
id="path2563"
sodipodi:nodetypes="cc" />
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@ -0,0 +1,570 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generated by Graphviz version 2.20.2 (Mon Mar 30 10:11:53 UTC 2009)
For user: (joakim) Joakim Erdfelt,,, -->
<!-- Title: G Pages: 1 -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="965.69556"
height="852.49811"
viewBox="0 0 327 590"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.46"
sodipodi:docname="DeploymentManager.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.0"
inkscape:export-filename="/home/joakim/code/webtide/jetty7-git/sandbox/jetty-deploy-manager/src/main/javadoc/org/eclipse/jetty/deploy/doc-files/DeploymentManager.png"
inkscape:export-xdpi="59.964943"
inkscape:export-ydpi="59.964943">
<metadata
id="metadata184">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs182">
<marker
inkscape:stockid="Arrow2Lstart"
orient="auto"
refY="0"
refX="0"
id="Arrow2Lstart"
style="overflow:visible">
<path
id="path4328"
style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.97309,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z"
transform="matrix(1.1,0,0,1.1,1.1,0)" />
</marker>
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Lend"
style="overflow:visible">
<path
id="path3605"
style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.97309,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z"
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
</marker>
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL"
style="overflow:visible">
<path
id="path3727"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="scale(0.8,0.8)" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend"
style="overflow:visible">
<path
id="path3587"
d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 368.75 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="408.75 : 368.75 : 1"
inkscape:persp3d-origin="204.375 : 245.83333 : 1"
id="perspective186" />
<title
id="title5">G</title>
<title
id="title10">incoming_app</title>
<title
id="title17">command_deploy</title>
<title
id="title33">state_deployed</title>
</defs>
<sodipodi:namedview
inkscape:window-height="1151"
inkscape:window-width="1920"
inkscape:pageshadow="2"
inkscape:pageopacity="1"
guidetolerance="10"
gridtolerance="10.0"
objecttolerance="13"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#ffffff"
id="base"
showgrid="false"
inkscape:zoom="1"
inkscape:cx="474.19853"
inkscape:cy="442.53354"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:current-layer="svg2"
showguides="true"
inkscape:guide-bbox="true"
inkscape:document-units="cm"
units="cm"
inkscape:snap-guide="true"
inkscape:snap-bbox="true"
inkscape:bbox-paths="false"
inkscape:bbox-nodes="false"
inkscape:snap-intersection-line-segments="true"
inkscape:object-paths="true"
inkscape:object-nodes="true"
inkscape:snap-center="false">
<inkscape:grid
type="xygrid"
id="grid3514"
dotted="true"
visible="true"
enabled="true"
units="cm"
spacingx="0.25cm"
spacingy="0.25cm"
empspacing="5" />
</sodipodi:namedview>
<text
x="-78.66259"
y="28.720337"
style="font-size:20.46376419px;font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:100%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans Bold Italic"
id="text2456"
sodipodi:linespacing="100%">
<tspan
sodipodi:role="line"
id="tspan2460"
x="-78.662582"
y="28.720337"
style="font-size:20.46376419px;font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:100%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans Bold Italic">Deployment</tspan>
<tspan
sodipodi:role="line"
x="-78.66259"
y="49.184101"
id="tspan2464"
style="font-size:20.46376419px;font-style:italic;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:100%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans Bold Italic">Management</tspan>
</text>
<g
id="g3282"
transform="translate(102.27151,-84.291492)">
<polygon
style="fill:#ffad70;fill-opacity:1;stroke:none;stroke-width:0.1850972"
points="230,-432 138,-432 138,-390 230,-390 230,-432 "
id="polygon3273"
transform="matrix(2.3250213,0,0,1.0137256,-252.78172,805.8122)" />
<text
x="174.1483"
y="394.13333"
style="font-size:17.98741913px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
id="text3275"
sodipodi:linespacing="125%">
<tspan
y="394.13333"
x="174.1483"
id="tspan3277"
sodipodi:role="line">DeploymentManager</tspan>
</text>
</g>
<g
id="g3304"
transform="translate(129.1072,31.5257)">
<polygon
style="fill:#d5ff70;fill-opacity:1;stroke:none;stroke-width:0.1850972"
points="230,-432 138,-432 138,-390 230,-390 230,-432 "
id="polygon3289"
transform="matrix(1.5190294,0,0,1.4508985,-250.33457,723.80726)" />
<text
x="28.670605"
y="122.9516"
style="font-size:17.98741913px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
id="text3291"
sodipodi:linespacing="125%">
<tspan
y="122.9516"
x="28.670605"
id="tspan3293"
sodipodi:role="line">AppProvider</tspan>
<tspan
id="tspan3300"
y="145.43587"
x="28.670603"
sodipodi:role="line">Contexts Dir</tspan>
</text>
</g>
<g
id="g3310"
transform="translate(300.00818,31.5257)">
<polygon
transform="matrix(1.5190294,0,0,1.4508985,-250.33457,723.80726)"
id="polygon3312"
points="230,-432 138,-432 138,-390 230,-390 230,-432 "
style="fill:#d5ff70;fill-opacity:1;stroke:none;stroke-width:0.1850972" />
<text
sodipodi:linespacing="125%"
id="text3314"
style="font-size:17.98741913px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
y="122.9516"
x="28.670605">
<tspan
sodipodi:role="line"
id="tspan3316"
x="28.670605"
y="122.9516">AppProvider</tspan>
<tspan
sodipodi:role="line"
x="28.670605"
y="145.43587"
id="tspan3318">Webapps Dir</tspan>
</text>
</g>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 246.279,212.30268 L 216.9954,189.48254"
id="path3344"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cc"
id="path3879"
d="M 246.279,212.30268 L 281.25982,189.48254"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
id="path3889"
d="M 338.25506,189.48254 L 338.25509,283.59126"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
id="path3891"
d="M 177.84916,189.48255 L 177.54883,283.59124"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<g
id="g3916"
transform="translate(105.09632,-15.083658)">
<polygon
transform="matrix(1.5190294,0,0,1.0137261,-95.187633,465.47084)"
id="polygon3903"
points="230,-432 138,-432 138,-390 230,-390 230,-432 "
style="fill:#70d9ff;fill-opacity:1;stroke:none;stroke-width:0.1850972" />
<text
sodipodi:linespacing="125%"
id="text3905"
style="font-size:17.98741913px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
y="53.791767"
x="184.1996">
<tspan
id="tspan3909"
sodipodi:role="line"
x="184.1996"
y="53.791767">File System</tspan>
</text>
</g>
<path
sodipodi:nodetypes="cc"
id="path3921"
d="M 204.70466,128.54481 L 240.721,55.034003"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 343.12033,128.54481 L 309.92883,55.034003"
id="path3923"
sodipodi:nodetypes="cc" />
<polygon
style="fill:#ff913e;fill-opacity:1;stroke:none;stroke-width:0.1850972"
points="230,-432 138,-432 138,-390 230,-390 230,-432 "
id="polygon4134"
transform="matrix(0.4627878,0,0,-5.402269,346.01282,-1753.521)" />
<g
id="g3971"
transform="translate(328.9625,-22.190946)">
<polygon
style="fill:#ffad70;fill-opacity:1;stroke:none;stroke-width:0.1850972"
points="230,-432 138,-432 138,-390 230,-390 230,-432 "
id="polygon3958"
transform="matrix(1.8107217,0,0,1.0137258,-329.65122,830.47882)" />
<text
x="2.6476707"
y="418.79987"
style="font-size:17.98741913px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
id="text3960"
sodipodi:linespacing="125%">
<tspan
id="tspan3964"
y="418.79987"
x="2.6476688"
sodipodi:role="line">DefaultDeployer</tspan>
</text>
</g>
<g
id="g3976"
transform="translate(328.58482,33.210928)">
<polygon
style="fill:#ffad70;fill-opacity:1;stroke:none;stroke-width:0.1850972"
points="230,-432 138,-432 138,-390 230,-390 230,-432 "
id="polygon3978"
transform="matrix(1.8107217,0,0,1.0137258,-329.65122,830.47882)" />
<text
x="2.6476707"
y="418.79987"
style="font-size:17.98741913px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
id="text3980"
sodipodi:linespacing="125%">
<tspan
id="tspan3982"
y="418.79987"
x="2.6476722"
sodipodi:role="line">DefaultStarter</tspan>
</text>
</g>
<g
id="g3984"
transform="translate(329.29103,86.176108)">
<polygon
style="fill:#ffad70;fill-opacity:1;stroke:none;stroke-width:0.1850972"
points="230,-432 138,-432 138,-390 230,-390 230,-432 "
id="polygon3986"
transform="matrix(1.8107217,0,0,1.0137258,-329.65122,830.47882)" />
<text
x="2.6476707"
y="418.79987"
style="font-size:17.98741913px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
id="text3988"
sodipodi:linespacing="125%">
<tspan
id="tspan3990"
y="418.79987"
x="2.6476693"
sodipodi:role="line">DefaultStopper</tspan>
</text>
</g>
<g
id="g4003"
transform="translate(148.88088,-17.953732)">
<polygon
style="fill:#ffad70;fill-opacity:1;stroke:none;stroke-width:0.1850972"
points="230,-432 138,-432 138,-390 230,-390 230,-432 "
id="polygon3994"
transform="matrix(2.102414,0,0,1.0137258,-216.3303,986.86761)" />
<text
x="169.63997"
y="575.18866"
style="font-size:17.98741913px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
id="text3996"
sodipodi:linespacing="125%">
<tspan
id="tspan3998"
y="575.18866"
x="169.63997"
sodipodi:role="line">DefaultUndeployer</tspan>
</text>
</g>
<g
id="g4136"
transform="translate(163.00492,-10.846444)">
<polygon
transform="matrix(2.309669,0,0,3.2368503,-636.87384,1707.8548)"
id="polygon3927"
points="230,-432 138,-432 138,-390 230,-390 230,-432 "
style="fill:#70d9ff;fill-opacity:1;stroke:none;stroke-width:0.1850972" />
<text
sodipodi:linespacing="125%"
id="text3929"
style="font-size:17.98741913px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
y="331.32928"
x="-211.42046">
<tspan
id="tspan3933"
sodipodi:role="line"
x="-211.42046"
y="331.32928">Jetty Server</tspan>
</text>
<g
transform="translate(3.6339138,14.123438)"
id="g4042">
<rect
style="opacity:1;fill:#ffffff;fill-opacity:0.57352941;stroke:none;stroke-width:1.52362204;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4033"
width="135.59087"
height="42.576458"
x="-282.93228"
y="367.66122"
ry="0" />
<text
x="-216.01076"
y="395.65521"
style="font-size:17.98741913px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
id="text4038"
sodipodi:linespacing="125%">
<tspan
y="395.65521"
x="-216.01076"
sodipodi:role="line"
id="tspan4040">Handler</tspan>
</text>
</g>
</g>
<path
sodipodi:nodetypes="cc"
id="path4027"
d="M 249.19086,394.86412 L 19.29742,380.32317"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 248.81318,455.59753 L 19.29742,388.44449"
id="path4047"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cc"
id="path4049"
d="M 249.5194,508.56271 L 19.29742,398.33131"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 236.80775,555.87827 L 19.29742,408.92435"
id="path4051"
sodipodi:nodetypes="cc" />
<text
transform="matrix(0.9979899,6.3372504e-2,-6.3372504e-2,0.9979899,0,0)"
id="text4053"
y="375.59882"
x="71.124741"
style="font-size:13.11166096px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="375.59882"
x="71.124741"
id="tspan4055"
sodipodi:role="line">Create/Add ContextHandler</tspan></text>
<text
transform="matrix(0.960082,0.2797186,-0.2797186,0.960082,0,0)"
id="text4061"
y="363.9259"
x="239.78268"
style="font-size:13.1116581px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="363.9259"
x="239.78268"
id="tspan4063"
sodipodi:role="line">Start Handler</tspan></text>
<text
transform="matrix(0.9021783,0.4313632,-0.4313632,0.9021783,0,0)"
id="text4065"
y="346.85672"
x="305.1987"
style="font-size:13.11165524px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="346.85672"
x="305.1987"
id="tspan4067"
sodipodi:role="line">Stop Handler</tspan></text>
<text
transform="matrix(0.8286045,0.5598344,-0.5598344,0.8286045,0,0)"
id="text4069"
y="324.38153"
x="358.96548"
style="font-size:13.1116581px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"
inkscape:transform-center-x="50.663071"
inkscape:transform-center-y="-52.951508"><tspan
y="324.38153"
x="358.96548"
id="tspan4071"
sodipodi:role="line">Remove Handler</tspan></text>
<path
sodipodi:nodetypes="cc"
id="path4073"
d="M 384.24468,305.40822 C 415.02857,303.94581 422.97175,327.74882 428.85613,353.36389"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99881887;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<text
transform="matrix(0.8492228,0.5280347,-0.5280347,0.8492228,0,0)"
id="text4075"
y="38.223793"
x="494.58685"
style="font-size:13.11166382px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"
inkscape:transform-center-x="-244.6352"
inkscape:transform-center-y="-504.72461"><tspan
y="38.223793"
x="494.58685"
sodipodi:role="line"
id="tspan4079">Process Phases</tspan></text>
<text
sodipodi:linespacing="125%"
id="text4094"
style="font-size:24.99049759px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
y="-423.87344"
x="420.23651"
transform="matrix(0,1,-1,0,0,0)">
<tspan
sodipodi:role="line"
id="tspan4096"
x="420.23651"
y="-423.87344">Lifecycle</tspan>
</text>
<text
transform="matrix(1,1.6038357e-4,-1.6038357e-4,1,0,0)"
id="text2579"
y="228.70334"
x="180.83775"
style="font-size:13.11166191px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"
inkscape:transform-center-x="-17.522216"
inkscape:transform-center-y="1.6854193"><tspan
y="228.70334"
x="180.83775"
sodipodi:role="line"
id="tspan3922">App</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.00542861;stroke-linecap:butt;stroke-linejoin:miter;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 246.54365,283.59124 L 246.279,212.30268"
id="path2583"
sodipodi:nodetypes="cc" />
<text
transform="matrix(1,1.6038357e-4,-1.6038357e-4,1,0,0)"
id="text3912"
y="228.69254"
x="248.14288"
style="font-size:13.11166191px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"
inkscape:transform-center-x="-17.522216"
inkscape:transform-center-y="1.6854193"><tspan
y="228.69254"
x="248.14288"
sodipodi:role="line"
id="tspan3916">Start</tspan><tspan
y="245.08211"
x="248.14288"
sodipodi:role="line"
id="tspan3920">Stop</tspan></text>
<text
transform="matrix(1,1.6038357e-4,-1.6038357e-4,1,0,0)"
id="text3926"
y="228.6776"
x="341.29437"
style="font-size:13.11166191px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"
inkscape:transform-center-x="-17.522216"
inkscape:transform-center-y="1.6854193"><tspan
y="228.6776"
x="341.29437"
sodipodi:role="line"
id="tspan3928">App</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1,389 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generated by Graphviz version 2.20.2 (Mon Mar 30 10:11:53 UTC 2009)
For user: (joakim) Joakim Erdfelt,,, -->
<!-- Title: G Pages: 1 -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="439.37006"
height="729.92126"
viewBox="0 0 327 590"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.46"
sodipodi:docname="DeploymentManager Roles.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.0"
inkscape:export-filename="/home/joakim/code/webtide/jetty7-git/sandbox/jetty-deploy-manager/src/main/javadoc/org/eclipse/jetty/deploy/doc-files/DeploymentManager_Roles.png"
inkscape:export-xdpi="40"
inkscape:export-ydpi="40">
<metadata
id="metadata184">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs182">
<linearGradient
id="linearGradient3424">
<stop
style="stop-color:#ff7107;stop-opacity:1;"
offset="0"
id="stop3426" />
<stop
style="stop-color:#ffeee0;stop-opacity:1;"
offset="1"
id="stop3428" />
</linearGradient>
<marker
inkscape:stockid="Arrow2Lstart"
orient="auto"
refY="0"
refX="0"
id="Arrow2Lstart"
style="overflow:visible">
<path
id="path4328"
style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.97309,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z"
transform="matrix(1.1,0,0,1.1,1.1,0)" />
</marker>
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Lend"
style="overflow:visible">
<path
id="path3605"
style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.97309,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z"
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
</marker>
<marker
inkscape:stockid="TriangleOutL"
orient="auto"
refY="0"
refX="0"
id="TriangleOutL"
style="overflow:visible">
<path
id="path3727"
d="M 5.77,0 L -2.88,5 L -2.88,-5 L 5.77,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="scale(0.8,0.8)" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend"
style="overflow:visible">
<path
id="path3587"
d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 368.75 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="408.75 : 368.75 : 1"
inkscape:persp3d-origin="204.375 : 245.83333 : 1"
id="perspective186" />
<title
id="title5">G</title>
<title
id="title10">incoming_app</title>
<title
id="title17">command_deploy</title>
<title
id="title33">state_deployed</title>
</defs>
<sodipodi:namedview
inkscape:window-height="1151"
inkscape:window-width="1920"
inkscape:pageshadow="2"
inkscape:pageopacity="1"
guidetolerance="10"
gridtolerance="10.0"
objecttolerance="13"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#ffffff"
id="base"
showgrid="false"
inkscape:zoom="1"
inkscape:cx="261.1181"
inkscape:cy="392.53714"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:current-layer="svg2"
showguides="true"
inkscape:guide-bbox="true"
inkscape:document-units="cm"
units="cm"
inkscape:snap-guide="true"
inkscape:snap-bbox="true"
inkscape:bbox-paths="false"
inkscape:bbox-nodes="false"
inkscape:snap-intersection-line-segments="true"
inkscape:object-paths="true"
inkscape:object-nodes="true"
inkscape:snap-center="false">
<inkscape:grid
type="xygrid"
id="grid3514"
dotted="true"
visible="true"
enabled="true"
units="cm"
spacingx="0.25cm"
spacingy="0.25cm"
empspacing="5" />
</sodipodi:namedview>
<g
id="g4043"
transform="matrix(1.1578745,0,0,1.1578745,-22.605787,-30.429653)">
<g
transform="translate(6.2287521,5.1906208)"
id="g3432">
<rect
style="opacity:1;fill:#ff984b;fill-opacity:1;stroke:none;stroke-width:1.52362204;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect2582"
width="271.29678"
height="108.65714"
x="18.959866"
y="223.19566"
ry="46.920952"
rx="50.806107" />
<text
sodipodi:linespacing="125%"
id="text3275"
style="font-size:25.83806229px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans Bold"
y="268.40268"
x="153.72513">
<tspan
sodipodi:role="line"
id="tspan3277"
x="153.72513"
y="268.40268">Deployment</tspan>
<tspan
sodipodi:role="line"
x="153.72513"
y="300.70026"
id="tspan3378">Manager</tspan>
</text>
</g>
<g
transform="translate(62.97961,2.9413488)"
id="g3418">
<rect
rx="20.920155"
ry="46.920952"
y="347.77072"
x="-37.790993"
height="47.75378"
width="119.23236"
id="rect3380"
style="opacity:1;fill:#ffd7b9;fill-opacity:1;stroke:none;stroke-width:1.52362204;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
x="21.438501"
y="366.92834"
style="font-size:17.21594238px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:110.00000238%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
id="text3382"
sodipodi:linespacing="110%">
<tspan
id="tspan3386"
y="366.92834"
x="21.438501"
sodipodi:role="line">Bind</tspan>
<tspan
y="385.86588"
x="21.438503"
sodipodi:role="line"
id="tspan3390">Lifecycle</tspan>
</text>
</g>
<g
transform="translate(2.1078682,5.3948095)"
id="g3412">
<rect
style="opacity:1;fill:#ffd7b9;fill-opacity:1;stroke:none;stroke-width:1.52362204;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect3392"
width="119.23236"
height="47.75378"
x="175.14517"
y="345.31726"
ry="46.920952"
rx="20.920155" />
<text
sodipodi:linespacing="110%"
id="text3394"
style="font-size:17.21594238px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:110.00000238%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
y="364.21011"
x="234.37466">
<tspan
sodipodi:role="line"
x="234.37466"
y="364.21011"
id="tspan3396">Use</tspan>
<tspan
id="tspan3398"
sodipodi:role="line"
x="234.37466"
y="383.14764">Lifecycle</tspan>
</text>
</g>
<rect
style="opacity:1;fill:#ffd970;fill-opacity:1;stroke:none;stroke-width:1.52362204;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect3400"
width="271.29678"
height="108.65714"
x="25.188618"
y="412.13449"
ry="46.920952"
rx="50.806107" />
<text
sodipodi:linespacing="125%"
id="text3402"
style="font-size:25.83806229px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans Bold"
y="458.72568"
x="159.2618">
<tspan
sodipodi:role="line"
x="159.2618"
y="458.72568"
id="tspan3406">Deployment</tspan>
<tspan
id="tspan3410"
sodipodi:role="line"
x="159.2618"
y="491.02325">Lifecycle</tspan>
</text>
<g
transform="translate(6.2287521,-178.55759)"
id="g3438">
<rect
rx="50.806107"
ry="46.920952"
y="223.19566"
x="18.959866"
height="108.65714"
width="271.29678"
id="rect3440"
style="opacity:1;fill:#d5ff70;fill-opacity:1;stroke:none;stroke-width:1.52362204;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
x="153.72513"
y="268.40268"
style="font-size:25.83806229px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans Bold"
id="text3442"
sodipodi:linespacing="125%">
<tspan
id="tspan3446"
y="268.40268"
x="153.72513"
sodipodi:role="line">App</tspan>
<tspan
id="tspan3450"
y="300.70026"
x="153.72513"
sodipodi:role="line">Provider</tspan>
</text>
</g>
<g
id="g3452"
transform="translate(62.97961,-180.80686)">
<rect
style="opacity:1;fill:#ffd7b9;fill-opacity:1;stroke:none;stroke-width:1.52362204;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect3454"
width="119.23236"
height="47.75378"
x="-37.790993"
y="347.77072"
ry="46.920952"
rx="20.920155" />
<text
sodipodi:linespacing="110%"
id="text3456"
style="font-size:17.21594238px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:110.00000238%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
y="366.92834"
x="21.438501">
<tspan
id="tspan3478"
sodipodi:role="line"
x="21.438499"
y="366.92834">Manage</tspan>
<tspan
id="tspan3482"
sodipodi:role="line"
x="21.438501"
y="385.86588">Provider</tspan>
</text>
</g>
<g
transform="translate(215.04403,-180.80686)"
id="g3462">
<rect
rx="20.920155"
ry="46.920952"
y="347.77072"
x="-37.790993"
height="47.75378"
width="119.23236"
id="rect3464"
style="opacity:1;fill:#ffd7b9;fill-opacity:1;stroke:none;stroke-width:1.52362204;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
x="21.438501"
y="366.92834"
style="font-size:17.21594238px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:110.00000238%;writing-mode:lr-tb;text-anchor:middle;font-family:Sans;-inkscape-font-specification:Sans"
id="text3466"
sodipodi:linespacing="110%">
<tspan
y="366.92834"
x="21.438503"
sodipodi:role="line"
id="tspan3470">Process</tspan>
<tspan
id="tspan3474"
y="385.86588"
x="21.438499"
sodipodi:role="line">App</tspan>
</text>
</g>
<path
style="opacity:0.61261262;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.86833984;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 195.13829,151.79607 L 195.13829,229.04598"
id="path4023"
sodipodi:nodetypes="cc" />
<path
style="opacity:0.61261262;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.86833984;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 127.84895,230.68829 L 127.84895,153.43838"
id="path4037"
sodipodi:nodetypes="cc" />
<path
style="opacity:0.61261262;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.86833984;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 195.13829,335.87758 L 195.13829,413.12749"
id="path4039"
sodipodi:nodetypes="cc" />
<path
style="opacity:0.61261262;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.86833984;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow2Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 127.84895,335.87758 L 127.84895,413.12749"
id="path4041"
sodipodi:nodetypes="cc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,9 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Jetty DeploymentManager API Overview</TITLE>
</HEAD>
<BODY>
Short overview of the API.
</BODY>
</HTML>

View File

@ -0,0 +1 @@
# Default Bindings

View File

@ -0,0 +1,75 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jetty.deploy.graph.Node;
import org.junit.Assert;
/**
* Binds to all lifecycle nodes, and tracks the order of the lifecycle nodes for testing purposes.
*/
public class AppLifeCyclePathCollector implements AppLifeCycle.Binding
{
List<Node> actualOrder = new ArrayList<Node>();
public void clear()
{
actualOrder.clear();
}
public List<Node> getCapturedPath()
{
return actualOrder;
}
public String[] getBindingTargets()
{
return new String[]
{ "*" };
}
public void processBinding(Node node, App app, DeploymentManager deploymentManager) throws Exception
{
actualOrder.add(node);
}
public void assertExpected(String msg, List<String> expectedOrder)
{
if (expectedOrder.size() != actualOrder.size())
{
System.out.println("/* Expected Path */");
for (String path : expectedOrder)
{
System.out.println(path);
}
System.out.println("/* Actual Path */");
for (Node path : actualOrder)
{
System.out.println(path.getName());
}
Assert.assertEquals(msg + " / count",expectedOrder.size(),actualOrder.size());
}
for (int i = 0, n = expectedOrder.size(); i < n; i++)
{
Assert.assertEquals(msg + "[" + i + "]",expectedOrder.get(i),actualOrder.get(i).getName());
}
}
}

View File

@ -0,0 +1,217 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jetty.deploy.graph.Node;
import org.junit.Assert;
import org.junit.Test;
/**
* Just an overly picky test case to validate the potential paths.
*/
public class AppLifeCycleTest
{
private void assertNoPath(String from, String to)
{
assertPath(from,to,new ArrayList<String>());
}
private void assertPath(AppLifeCycle lifecycle, String from, String to, List<String> expected)
{
Node fromNode = lifecycle.getNodeByName(from);
Node toNode = lifecycle.getNodeByName(to);
List<Node> actual = lifecycle.findPath(fromNode,toNode);
String msg = "LifeCycle path from " + from + " to " + to;
Assert.assertNotNull(msg + " should never be null",actual);
if (expected.size() != actual.size())
{
System.out.println();
System.out.printf("/* from '%s' -> '%s' */%n",from,to);
System.out.println("/* Expected Path */");
for (String path : expected)
{
System.out.println(path);
}
System.out.println("/* Actual Path */");
for (Node path : actual)
{
System.out.println(path.getName());
}
Assert.assertEquals(msg + " / count",expected.size(),actual.size());
}
for (int i = 0, n = expected.size(); i < n; i++)
{
Assert.assertEquals(msg + "[" + i + "]",expected.get(i),actual.get(i).getName());
}
}
private void assertPath(String from, String to, List<String> expected)
{
AppLifeCycle lifecycle = new AppLifeCycle();
assertPath(lifecycle,from,to,expected);
}
@Test
public void testFindPath_Deployed_Deployed()
{
assertNoPath("deployed","deployed");
}
@Test
public void testFindPath_Deployed_Started()
{
List<String> expected = new ArrayList<String>();
expected.add("deployed");
expected.add("pre-starting");
expected.add("starting");
expected.add("started");
assertPath("deployed","started",expected);
}
@Test
public void testFindPath_Deployed_Undeployed()
{
List<String> expected = new ArrayList<String>();
expected.add("deployed");
expected.add("pre-undeploying");
expected.add("undeploying");
expected.add("undeployed");
assertPath("deployed","undeployed",expected);
}
@Test
public void testFindPath_Started_Deployed()
{
List<String> expected = new ArrayList<String>();
expected.add("started");
expected.add("pre-stopping");
expected.add("stopping");
expected.add("deployed");
assertPath("started","deployed",expected);
}
@Test
public void testFindPath_Started_Started()
{
assertNoPath("started","started");
}
@Test
public void testFindPath_Started_Undeployed()
{
List<String> expected = new ArrayList<String>();
expected.add("started");
expected.add("pre-stopping");
expected.add("stopping");
expected.add("deployed");
expected.add("pre-undeploying");
expected.add("undeploying");
expected.add("undeployed");
assertPath("started","undeployed",expected);
}
@Test
public void testFindPath_Undeployed_Deployed()
{
List<String> expected = new ArrayList<String>();
expected.add("undeployed");
expected.add("pre-deploying");
expected.add("deploying");
expected.add("deployed");
assertPath("undeployed","deployed",expected);
}
@Test
public void testFindPath_Undeployed_Started()
{
List<String> expected = new ArrayList<String>();
expected.add("undeployed");
expected.add("pre-deploying");
expected.add("deploying");
expected.add("deployed");
expected.add("pre-starting");
expected.add("starting");
expected.add("started");
assertPath("undeployed","started",expected);
}
@Test
public void testFindPath_Undeployed_Uavailable()
{
assertNoPath("undeployed","undeployed");
}
/**
* Request multiple lifecycle paths with a single lifecycle instance. Just to ensure that there is no state
* maintained between {@link AppLifeCycle#findPath(Node, Node)} requests.
*/
@Test
public void testFindPathMultiple()
{
AppLifeCycle lifecycle = new AppLifeCycle();
List<String> expected = new ArrayList<String>();
lifecycle.removeEdge("deployed","pre-starting");
lifecycle.addEdge("deployed","staging");
lifecycle.addEdge("staging","staged");
lifecycle.addEdge("staged","pre-starting");
// Deployed -> Deployed
expected.clear();
assertPath(lifecycle,"deployed","deployed",expected);
// Deployed -> Staged
expected.clear();
expected.add("deployed");
expected.add("staging");
expected.add("staged");
assertPath(lifecycle,"deployed","staged",expected);
// Staged -> Undeployed
expected.clear();
expected.add("staged");
expected.add("pre-starting");
expected.add("starting");
expected.add("started");
expected.add("pre-stopping");
expected.add("stopping");
expected.add("deployed");
expected.add("pre-undeploying");
expected.add("undeploying");
expected.add("undeployed");
assertPath(lifecycle,"staged","undeployed",expected);
// Undeployed -> Started
expected.clear();
expected.add("undeployed");
expected.add("pre-deploying");
expected.add("deploying");
expected.add("deployed");
expected.add("staging");
expected.add("staged");
expected.add("pre-starting");
expected.add("starting");
expected.add("started");
assertPath(lifecycle,"undeployed","started",expected);
}
}

View File

@ -0,0 +1,83 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.junit.Test;
public class DeploymentManagerLifeCyclePathTest
{
@Test
public void testStateTransition_NewToDeployed() throws Exception
{
DeploymentManager depman = new DeploymentManager();
depman.setDefaultLifeCycleGoal(null); // no default
AppLifeCyclePathCollector pathtracker = new AppLifeCyclePathCollector();
MockAppProvider mockProvider = new MockAppProvider();
depman.addLifeCycleBinding(pathtracker);
depman.addAppProvider(mockProvider);
depman.setContexts(new ContextHandlerCollection());
// Start DepMan
depman.start();
// Trigger new App
mockProvider.findWebapp("foo-webapp-1.war");
App app = depman.getAppByOriginId("mock-foo-webapp-1.war");
// Request Deploy of App
depman.requestAppGoal(app,"deployed");
// Setup Expectations.
List<String> expected = new ArrayList<String>();
// SHOULD NOT SEE THIS NODE VISITED - expected.add("undeployed");
expected.add("pre-deploying");
expected.add("deploying");
expected.add("deployed");
pathtracker.assertExpected("Test StateTransition / New -> Deployed",expected);
}
@Test
public void testStateTransition_Receive() throws Exception
{
DeploymentManager depman = new DeploymentManager();
depman.setDefaultLifeCycleGoal(null); // no default
AppLifeCyclePathCollector pathtracker = new AppLifeCyclePathCollector();
MockAppProvider mockProvider = new MockAppProvider();
depman.addLifeCycleBinding(pathtracker);
depman.addAppProvider(mockProvider);
// Start DepMan
depman.start();
// Trigger new App
mockProvider.findWebapp("foo-webapp-1.war");
// Perform no goal request.
// Setup Expectations.
List<String> expected = new ArrayList<String>();
pathtracker.assertExpected("Test StateTransition / New only",expected);
}
}

View File

@ -0,0 +1,87 @@
package org.eclipse.jetty.deploy;
import java.util.Collection;
import java.util.Set;
import org.eclipse.jetty.deploy.test.XmlConfiguredJetty;
import org.junit.Assert;
import org.junit.Test;
public class DeploymentManagerTest
{
@Test
public void testReceiveApp() throws Exception
{
DeploymentManager depman = new DeploymentManager();
depman.setDefaultLifeCycleGoal(null); // no default
AppLifeCyclePathCollector pathtracker = new AppLifeCyclePathCollector();
MockAppProvider mockProvider = new MockAppProvider();
depman.addLifeCycleBinding(pathtracker);
depman.addAppProvider(mockProvider);
// Start DepMan
depman.start();
// Trigger new App
mockProvider.findWebapp("foo-webapp-1.war");
// Test app tracking
Collection<App> apps = depman.getApps();
Assert.assertNotNull("Should never be null",apps);
Assert.assertEquals("Expected App Count",1,apps.size());
// Test app get
App actual = depman.getAppByOriginId("mock-foo-webapp-1.war");
Assert.assertNotNull("Should have gotten app (by id)",actual);
Assert.assertEquals("Should have gotten app (by id)","mock-foo-webapp-1.war",actual.getOriginId());
}
@Test
public void testBinding()
{
AppLifeCyclePathCollector pathtracker = new AppLifeCyclePathCollector();
DeploymentManager depman = new DeploymentManager();
depman.addLifeCycleBinding(pathtracker);
Set<AppLifeCycle.Binding> allbindings = depman.getLifeCycle().getBindings();
Assert.assertNotNull("All Bindings should never be null",allbindings);
Assert.assertEquals("All Bindings.size",1,allbindings.size());
Set<AppLifeCycle.Binding> deploybindings = depman.getLifeCycle().getBindings("deploying");
Assert.assertNotNull("'deploying' Bindings should not be null",deploybindings);
Assert.assertEquals("'deploying' Bindings.size",1,deploybindings.size());
}
@Test
public void testXmlConfigured() throws Exception
{
XmlConfiguredJetty jetty = null;
try
{
jetty = new XmlConfiguredJetty();
jetty.addConfiguration("jetty.xml");
jetty.addConfiguration("jetty-deploymgr-contexts.xml");
// Should not throw an Exception
jetty.load();
// Start it
jetty.start();
}
finally
{
if (jetty != null)
{
try
{
jetty.stop();
}
catch (Exception ignore)
{
// ignore
}
}
}
}
}

View File

@ -0,0 +1,45 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy;
import java.io.File;
import org.eclipse.jetty.deploy.test.MavenTestingUtils;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
public class MockAppProvider extends AbstractLifeCycle implements AppProvider
{
private DeploymentManager deployMan;
private File webappsDir;
public void setDeploymentManager(DeploymentManager deploymentManager)
{
this.deployMan = deploymentManager;
}
@Override
public void doStart()
{
this.webappsDir = MavenTestingUtils.getTestResourceDir("webapps");
}
public void findWebapp(String name)
{
File war = new File(webappsDir,name);
App app = new App("mock-" + name,war);
this.deployMan.addApp(app);
}
}

View File

@ -0,0 +1,116 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy.providers;
import java.io.IOException;
import org.eclipse.jetty.deploy.test.XmlConfiguredJetty;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* Similar in scope to {@link MonitoredDirAppProviderStartupTest}, except is concerned with the modification of existing
* deployed webapps due to incoming changes identified by the {@link MonitoredDirAppProvider}.
*/
public class MonitoredDirAppProviderRuntimeUpdatesTest
{
private static XmlConfiguredJetty jetty;
@Before
public void setupEnvironment() throws Exception
{
jetty = new XmlConfiguredJetty();
jetty.addConfiguration("jetty.xml");
jetty.addConfiguration("jetty-deploymgr-contexts.xml");
// Should not throw an Exception
jetty.load();
// Start it
jetty.start();
}
@After
public void teardownEnvironment() throws Exception
{
// Stop jetty.
jetty.stop();
}
/**
* Simple webapp deployment after startup of server.
*/
@Test
public void testAfterStartupContext() throws IOException
{
jetty.copyWebapp("foo-webapp-1.war","foo.war");
jetty.copyContext("foo.xml","foo.xml");
jetty.waitForDirectoryScan();
jetty.assertWebAppContextsExists("/foo");
}
/**
* Simple webapp deployment after startup of server, and then removal of the webapp.
*/
@Test
public void testAfterStartupThenRemoveContext() throws IOException
{
jetty.copyWebapp("foo-webapp-1.war","foo.war");
jetty.copyContext("foo.xml","foo.xml");
jetty.waitForDirectoryScan();
jetty.assertWebAppContextsExists("/foo");
jetty.removeContext("foo.xml");
jetty.waitForDirectoryScan();
// FIXME: hot undeploy with removal not working! - jetty.assertNoWebAppContexts();
}
/**
* Simple webapp deployment after startup of server, and then removal of the webapp.
*/
@Test
public void testAfterStartupThenUpdateContext() throws IOException
{
jetty.copyWebapp("foo-webapp-1.war","foo.war");
jetty.copyContext("foo.xml","foo.xml");
jetty.waitForDirectoryScan();
jetty.assertWebAppContextsExists("/foo");
// Test that webapp response contains "-1"
jetty.assertResponseContains("/foo/info","FooServlet-1");
System.out.println("Updating war files");
jetty.copyContext("foo.xml","foo.xml"); // essentially "touch" the context xml
jetty.copyWebapp("foo-webapp-2.war","foo.war");
// This should result in the existing foo.war being replaced with the new foo.war
jetty.waitForDirectoryScan();
jetty.waitForDirectoryScan();
jetty.assertWebAppContextsExists("/foo");
// Test that webapp response contains "-2"
jetty.assertResponseContains("/foo/info","FooServlet-2");
}
}

View File

@ -0,0 +1,62 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy.providers;
import org.eclipse.jetty.deploy.test.XmlConfiguredJetty;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* Tests {@link MonitoredDirAppProvider} as it starts up for the first time.
*/
public class MonitoredDirAppProviderStartupTest
{
private static XmlConfiguredJetty jetty;
@BeforeClass
public static void setupEnvironment() throws Exception
{
jetty = new XmlConfiguredJetty();
jetty.addConfiguration("jetty.xml");
jetty.addConfiguration("jetty-deploymgr-contexts.xml");
// Setup initial context
jetty.copyContext("foo.xml","foo.xml");
jetty.copyWebapp("foo-webapp-1.war","foo.war");
// Should not throw an Exception
jetty.load();
// Start it
jetty.start();
}
@AfterClass
public static void teardownEnvironment() throws Exception
{
// Stop jetty.
jetty.stop();
}
@Test
public void testStartupContext()
{
// Check Server for Handlers
jetty.printHandlers(System.out);
jetty.assertWebAppContextsExists("/foo");
}
}

View File

@ -0,0 +1,219 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy.test;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import junit.framework.TestCase;
import org.eclipse.jetty.util.IO;
/**
* Common utility methods for working with JUnit tests cases in a maven friendly way.
*/
public class MavenTestingUtils
{
private static File basedir;
private static File testResourcesDir;
private static File targetDir;
// private static Boolean surefireRunning;
public static File getBasedir()
{
if (basedir == null)
{
String cwd = System.getProperty("basedir");
if (cwd == null)
{
cwd = System.getProperty("user.dir");
}
basedir = new File(cwd);
}
return basedir;
}
/**
* Get the directory to the /target directory for this project.
*
* @return the directory path to the target directory.
*/
public static File getTargetDir()
{
if (targetDir == null)
{
targetDir = new File(getBasedir(),"target");
PathAssert.assertDirExists("Target Dir",targetDir);
}
return targetDir;
}
/**
* Create a {@link File} object for a path in the /target directory.
*
* @param path
* the path desired, no validation of existence is performed.
* @return the File to the path.
*/
public static File getTargetFile(String path)
{
return new File(getTargetDir(),path.replace("/",File.separator));
}
public static File getTargetTestingDir()
{
File dir = new File(getTargetDir(),"testing");
if (!dir.exists())
{
dir.mkdirs();
}
return dir;
}
/**
* Get a dir in /target/ that uses the JUnit 3.x {@link TestCase#getName()} to make itself unique.
*
* @param test
* the junit 3.x testcase to base this new directory on.
* @return
*/
public static File getTargetTestingDir(TestCase test)
{
return getTargetTestingDir(test.getName());
}
/**
* Get a dir in /target/ that uses the an arbitrary name.
*
* @param testname
* the testname to create directory against.
* @return
*/
public static File getTargetTestingDir(String testname)
{
File dir = new File(getTargetDir(),"test-" + testname);
if (!dir.exists())
{
dir.mkdirs();
}
return dir;
}
/**
* Get a dir from the src/test/resource directory.
*
* @param name
* the name of the path to get (it must exist as a dir)
* @return the dir in src/test/resource
*/
public static File getTestResourceDir(String name)
{
File dir = new File(getTestResourcesDir(),name);
PathAssert.assertDirExists("Test Resource Dir",dir);
return dir;
}
/**
* Get a file from the src/test/resource directory.
*
* @param name
* the name of the path to get (it must exist as a file)
* @return the file in src/test/resource
*/
public static File getTestResourceFile(String name)
{
File file = new File(getTestResourcesDir(),name);
PathAssert.assertFileExists("Test Resource File",file);
return file;
}
/**
* Get a path resource (File or Dir) from the src/test/resource directory.
*
* @param name
* the name of the path to get (it must exist)
* @return the path in src/test/resource
*/
public static File getTestResourcePath(String name)
{
File path = new File(getTestResourcesDir(),name);
PathAssert.assertExists("Test Resource Path",path);
return path;
}
/**
* Get the directory to the src/test/resource directory
*
* @return the directory {@link File} to the src/test/resources directory
*/
public static File getTestResourcesDir()
{
if (testResourcesDir == null)
{
testResourcesDir = new File(basedir,"src/test/resources".replace("/",File.separator));
PathAssert.assertDirExists("Test Resources Dir",testResourcesDir);
}
return testResourcesDir;
}
/**
* Read the contents of a file into a String and return it.
*
* @param file
* the file to read.
* @return the contents of the file.
* @throws IOException
* if unable to read the file.
*/
public static String readToString(File file) throws IOException
{
FileReader reader = null;
try
{
reader = new FileReader(file);
return IO.toString(reader);
}
finally
{
IO.close(reader);
}
}
/*
public static boolean isSurefireExecuting()
{
if (surefireRunning == null)
{
String val = System.getProperty("surefire.test.class.path");
if (val != null)
{
surefireRunning = Boolean.TRUE;
}
else
{
surefireRunning = Boolean.FALSE;
}
}
return surefireRunning;
}
*/
}

View File

@ -0,0 +1,40 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy.test;
import java.io.File;
import org.junit.Assert;
public class PathAssert
{
public static void assertDirExists(String msg, File path)
{
assertExists(msg,path);
Assert.assertTrue(msg + " path should be a Dir : " + path.getAbsolutePath(),path.isDirectory());
}
public static void assertFileExists(String msg, File path)
{
assertExists(msg,path);
Assert.assertTrue(msg + " path should be a File : " + path.getAbsolutePath(),path.isFile());
}
public static void assertExists(String msg, File path)
{
Assert.assertTrue(msg + " path should exist: " + path.getAbsolutePath(),path.exists());
}
}

View File

@ -0,0 +1,441 @@
// ========================================================================
// Copyright (c) Webtide LLC
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
package org.eclipse.jetty.deploy.test;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.http.HttpSchemes;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.xml.XmlConfiguration;
import org.junit.Assert;
/**
* Allows for setting up a Jetty server for testing based on XML configuration files.
*/
public class XmlConfiguredJetty
{
private List<URL> xmlConfigurations;
private Properties properties = new Properties();
private Server server;
private int serverPort;
private String scheme = HttpSchemes.HTTP;
private File jettyHome;
public XmlConfiguredJetty() throws IOException
{
String testname = new Throwable().getStackTrace()[1].getClassName();
xmlConfigurations = new ArrayList<URL>();
properties = new Properties();
jettyHome = MavenTestingUtils.getTargetTestingDir(testname);
deleteContents(jettyHome); // Ensure that we are working with a pristene directory
// Prepare Jetty.Home (Test) dir
jettyHome.mkdirs();
File logsDir = new File(jettyHome,"logs");
logsDir.mkdirs();
File etcDir = new File(jettyHome,"etc");
etcDir.mkdirs();
IO.copyFile(MavenTestingUtils.getTestResourceFile("etc/realm.properties"),new File(etcDir,"realm.properties"));
IO.copyFile(MavenTestingUtils.getTestResourceFile("etc/webdefault.xml"),new File(etcDir,"webdefault.xml"));
File contextsDir = new File(jettyHome,"contexts");
if (contextsDir.exists())
{
deleteContents(contextsDir);
}
contextsDir.mkdirs();
File webappsDir = new File(jettyHome,"webapps");
if (webappsDir.exists())
{
deleteContents(webappsDir);
}
webappsDir.mkdirs();
File tmpDir = new File(jettyHome,"tmp");
tmpDir.mkdirs();
// Setup properties
System.setProperty("java.io.tmpdir",tmpDir.getAbsolutePath());
properties.setProperty("jetty.home",jettyHome.getAbsolutePath());
System.setProperty("jetty.home",jettyHome.getAbsolutePath());
properties.setProperty("test.basedir",MavenTestingUtils.getBasedir().getAbsolutePath());
properties.setProperty("test.resourcesdir",MavenTestingUtils.getTestResourcesDir().getAbsolutePath());
properties.setProperty("test.webapps",webappsDir.getAbsolutePath());
properties.setProperty("test.targetdir",MavenTestingUtils.getTargetDir().getAbsolutePath());
// Write out configuration for use by ConfigurationManager.
File testConfig = MavenTestingUtils.getTargetFile("xml-configured-jetty.properties");
FileOutputStream out = new FileOutputStream(testConfig);
properties.store(out,"Generated by " + XmlConfiguredJetty.class.getName());
}
public void addConfiguration(File xmlConfigFile) throws MalformedURLException
{
xmlConfigurations.add(xmlConfigFile.toURI().toURL());
}
public void addConfiguration(String testConfigName) throws MalformedURLException
{
addConfiguration(MavenTestingUtils.getTestResourceFile(testConfigName));
}
public void addConfiguration(URL xmlConfig)
{
xmlConfigurations.add(xmlConfig);
}
public void assertNoWebAppContexts()
{
List<WebAppContext> contexts = getWebAppContexts();
if (contexts.size() > 0)
{
for (WebAppContext context : contexts)
{
System.out.println("WebAppContext should not exist:\n" + toString(context));
}
Assert.assertEquals("Contexts.size",0,contexts.size());
}
}
public String getResponse(String path) throws IOException
{
URI destUri = getServerURI().resolve(path);
URL url = destUri.toURL();
URLConnection conn = url.openConnection();
InputStream in = null;
try
{
in = conn.getInputStream();
return IO.toString(in);
}
finally
{
IO.close(in);
}
}
public void assertResponseContains(String path, String needle) throws IOException
{
System.out.println("Issuing request to " + path);
String content = getResponse(path);
Assert.assertTrue("Content should contain <" + needle + ">, instead got <" + content + ">",content.contains(needle));
}
public void assertWebAppContextsExists(String... expectedContextPaths)
{
List<WebAppContext> contexts = getWebAppContexts();
if (expectedContextPaths.length != contexts.size())
{
System.out.println("## Expected Contexts");
for (String expected : expectedContextPaths)
{
System.out.println(expected);
}
System.out.println("## Actual Contexts");
for (WebAppContext context : contexts)
{
System.out.printf("%s ## %s%n",context.getContextPath(),context);
}
Assert.assertEquals("Contexts.size",expectedContextPaths.length,contexts.size());
}
for (String expectedPath : expectedContextPaths)
{
boolean found = false;
for (WebAppContext context : contexts)
{
if (context.getContextPath().equals(expectedPath))
{
found = true;
break;
}
}
Assert.assertTrue("Did not find Expected Context Path " + expectedPath,found);
}
}
public void copyContext(String srcName, String destName) throws IOException
{
System.out.printf("Copying Context: %s -> %s%n",srcName,destName);
File srcDir = MavenTestingUtils.getTestResourceDir("contexts");
File destDir = new File(jettyHome,"contexts");
File srcFile = new File(srcDir,srcName);
File destFile = new File(destDir,destName);
copyFile("Context",srcFile,destFile);
}
private void copyFile(String type, File srcFile, File destFile) throws IOException
{
PathAssert.assertFileExists(type + " File",srcFile);
IO.copyFile(srcFile,destFile);
PathAssert.assertFileExists(type + " File",destFile);
System.out.printf("Copy %s: %s%n To %s: %s%n",type,srcFile,type,destFile);
System.out.printf("Destination Exists: %s - %s%n",destFile.exists(),destFile);
}
public void copyWebapp(String srcName, String destName) throws IOException
{
System.out.printf("Copying Webapp: %s -> %s%n",srcName,destName);
File srcDir = MavenTestingUtils.getTestResourceDir("webapps");
File destDir = new File(jettyHome,"webapps");
File srcFile = new File(srcDir,srcName);
File destFile = new File(destDir,destName);
copyFile("Webapp",srcFile,destFile);
}
private void deleteContents(File dir)
{
System.out.printf("Delete (dir) %s/%n",dir);
for (File file : dir.listFiles())
{
// Safety measure. only recursively delete within target directory.
if (file.isDirectory() && file.getAbsolutePath().contains("target" + File.separator))
{
deleteContents(file);
Assert.assertTrue("Delete failed: " + file.getAbsolutePath(),file.delete());
}
else
{
System.out.printf("Delete (file) %s%n",file);
Assert.assertTrue("Delete failed: " + file.getAbsolutePath(),file.delete());
}
}
}
public DeploymentManager getActiveDeploymentManager()
{
List<DeploymentManager> depmans = server.getBeans(DeploymentManager.class);
Assert.assertEquals("DeploymentManager bean count",1,depmans.size());
return depmans.get(0);
}
public File getJettyDir(String name)
{
return new File(jettyHome,name);
}
public File getJettyHome()
{
return jettyHome;
}
public String getScheme()
{
return scheme;
}
public Server getServer()
{
return server;
}
public int getServerPort()
{
return serverPort;
}
public URI getServerURI() throws UnknownHostException
{
StringBuffer uri = new StringBuffer();
uri.append(this.scheme).append("://");
uri.append(InetAddress.getLocalHost().getHostAddress());
uri.append(":").append(this.serverPort);
return URI.create(uri.toString());
}
public List<WebAppContext> getWebAppContexts()
{
List<WebAppContext> contexts = new ArrayList<WebAppContext>();
HandlerCollection handlers = (HandlerCollection)server.getHandler();
System.out.println(server.dump());
Handler children[] = handlers.getChildHandlers();
for (Handler handler : children)
{
if (handler instanceof WebAppContext)
{
WebAppContext context = (WebAppContext)handler;
contexts.add(context);
}
}
return contexts;
}
@SuppressWarnings("unchecked")
public void load() throws Exception
{
XmlConfiguration last = null;
Object[] obj = new Object[this.xmlConfigurations.size()];
// Configure everything
for (int i = 0; i < this.xmlConfigurations.size(); i++)
{
URL configURL = this.xmlConfigurations.get(i);
XmlConfiguration configuration = new XmlConfiguration(configURL);
if (last != null)
{
configuration.getIdMap().putAll(last.getIdMap());
}
configuration.setProperties(properties);
obj[i] = configuration.configure();
last = configuration;
}
// Test for Server Instance.
Server foundServer = null;
int serverCount = 0;
for (int i = 0; i < this.xmlConfigurations.size(); i++)
{
if (obj[i] instanceof Server)
{
if (obj[i].equals(foundServer))
{
// Identical server instance found
break;
}
foundServer = (Server)obj[i];
serverCount++;
}
}
if (serverCount <= 0)
{
throw new Exception("Load failed to configure a " + Server.class.getName());
}
Assert.assertEquals("Server load count",1,serverCount);
this.server = foundServer;
this.server.setGracefulShutdown(10);
}
public void printHandlers(PrintStream out)
{
Handler handler = server.getHandler();
out.println(toString(handler));
}
public void removeContext(String name)
{
File destDir = new File(jettyHome,"contexts");
File contextFile = new File(destDir,name);
if (contextFile.exists())
{
Assert.assertTrue("Delete of Context file: " + contextFile.getAbsolutePath(),contextFile.delete());
}
}
public void setProperty(String key, String value)
{
properties.setProperty(key,value);
}
public void setScheme(String scheme)
{
this.scheme = scheme;
}
public void start() throws Exception
{
Assert.assertNotNull("Server should not be null (failed load?)",server);
server.start();
// Find the active server port.
this.serverPort = (-1);
Connector connectors[] = server.getConnectors();
for (int i = 0; i < connectors.length; i++)
{
Connector connector = connectors[i];
if (connector.getLocalPort() > 0)
{
this.serverPort = connector.getLocalPort();
break;
}
}
Assert.assertTrue("Server Port is between 1 and 65535. Actually <" + serverPort + ">",(1 <= this.serverPort) && (this.serverPort <= 65535));
// Uncomment to have server start and continue to run (without exiting)
// System.out.printf("Listening to port %d%n",this.serverPort);
// server.join();
}
public void stop() throws Exception
{
server.stop();
}
public String toString(Handler handler)
{
if (handler instanceof HandlerCollection)
{
return ((HandlerCollection)handler).dump();
}
if (handler instanceof AbstractHandler)
{
return ((AbstractHandler)handler).dump();
}
return handler.toString();
}
public void waitForDirectoryScan()
{
int ms = 2000;
System.out.printf("Waiting %d milliseconds for AppProvider to process directory scan ...%n",ms);
try
{
Thread.sleep(ms);
}
catch (InterruptedException ignore)
{
/* ignore */
}
}
}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/foo</Set>
<Set name="war">
<Property name="test.webapps" default="." />/foo.war
</Set>
</Configure>

View File

@ -0,0 +1,21 @@
#
# This file defines users passwords and roles for a HashUserRealm
#
# The format is
# <username>: <password>[,<rolename> ...]
#
# Passwords may be clear text, obfuscated or checksummed. The class
# org.eclipse.util.Password should be used to generate obfuscated
# passwords or password checksums
#
# If DIGEST Authentication is used, the password must be in a recoverable
# format, either plain text or OBF:.
#
jetty: MD5:164c88b302622e17050af52c89945d44,user
admin: CRYPT:adpexzg3FUZAk,server-administrator,content-administrator,admin
other: OBF:1xmk1w261u9r1w1c1xmq,user
plain: plain,user
user: password,user
# This entry is for digest auth. The credential is a MD5 hash of username:realmname:password
digest: MD5:6e120743ad67abfbc385bc2bb754e297,user

View File

@ -0,0 +1,404 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- ===================================================================== -->
<!-- This file contains the default descriptor for web applications. -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- The intent of this descriptor is to include jetty specific or common -->
<!-- configuration for all webapps. If a context has a webdefault.xml -->
<!-- descriptor, it is applied before the contexts own web.xml file -->
<!-- -->
<!-- A context may be assigned a default descriptor by: -->
<!-- + Calling WebApplicationContext.setDefaultsDescriptor -->
<!-- + Passed an arg to addWebApplications -->
<!-- -->
<!-- This file is used both as the resource within the jetty.jar (which is -->
<!-- used as the default if no explicit defaults descriptor is set) and it -->
<!-- is copied to the etc directory of the Jetty distro and explicitly -->
<!-- by the jetty.xml file. -->
<!-- -->
<!-- ===================================================================== -->
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
metadata-complete="true"
version="2.5">
<description>
Default web.xml file.
This file is applied to a Web application before it's own WEB_INF/web.xml file
</description>
<!-- ==================================================================== -->
<!-- Context params to control Session Cookies -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- UNCOMMENT TO ACTIVATE
<context-param>
<param-name>org.eclipse.jetty.servlet.SessionDomain</param-name>
<param-value>127.0.0.1</param-value>
</context-param>
<context-param>
<param-name>org.eclipse.jetty.servlet.SessionPath</param-name>
<param-value>/</param-value>
</context-param>
<context-param>
<param-name>org.eclipse.jetty.servlet.MaxAge</param-name>
<param-value>-1</param-value>
</context-param>
-->
<!-- ==================================================================== -->
<!-- The default servlet. -->
<!-- This servlet, normally mapped to /, provides the handling for static -->
<!-- content, OPTIONS and TRACE methods for the context. -->
<!-- The following initParameters are supported: -->
<!-- -->
<!-- acceptRanges If true, range requests and responses are -->
<!-- supported -->
<!-- -->
<!-- dirAllowed If true, directory listings are returned if no -->
<!-- welcome file is found. Else 403 Forbidden. -->
<!-- -->
<!-- welcomeServlets If true, attempt to dispatch to welcome files -->
<!-- that are servlets, if no matching static -->
<!-- resources can be found. -->
<!-- -->
<!-- redirectWelcome If true, redirect welcome file requests -->
<!-- else use request dispatcher forwards -->
<!-- -->
<!-- gzip If set to true, then static content will be served-->
<!-- as gzip content encoded if a matching resource is -->
<!-- found ending with ".gz" -->
<!-- -->
<!-- resoureBase Can be set to replace the context resource base -->
<!-- -->
<!-- relativeResourceBase -->
<!-- Set with a pathname relative to the base of the -->
<!-- servlet context root. Useful for only serving -->
<!-- static content from only specific subdirectories. -->
<!-- -->
<!-- useFileMappedBuffer -->
<!-- If set to true (the default), a memory mapped -->
<!-- file buffer will be used to serve static content -->
<!-- when using an NIO connector. Setting this value -->
<!-- to false means that a direct buffer will be used -->
<!-- instead. If you are having trouble with Windows -->
<!-- file locking, set this to false. -->
<!-- -->
<!-- cacheControl If set, all static content will have this value -->
<!-- set as the cache-control header. -->
<!-- -->
<!-- maxCacheSize Maximum size of the static resource cache -->
<!-- -->
<!-- maxCachedFileSize Maximum size of any single file in the cache -->
<!-- -->
<!-- maxCachedFiles Maximum number of files in the cache -->
<!-- -->
<!-- cacheType "nio", "bio" or "both" to determine the type(s) -->
<!-- of resource cache. A bio cached buffer may be used-->
<!-- by nio but is not as efficient as a nio buffer. -->
<!-- An nio cached buffer may not be used by bio. -->
<!-- -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
<init-param>
<param-name>acceptRanges</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>dirAllowed</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>welcomeServlets</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>redirectWelcome</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>maxCacheSize</param-name>
<param-value>256000000</param-value>
</init-param>
<init-param>
<param-name>maxCachedFileSize</param-name>
<param-value>10000000</param-value>
</init-param>
<init-param>
<param-name>maxCachedFiles</param-name>
<param-value>1000</param-value>
</init-param>
<init-param>
<param-name>cacheType</param-name>
<param-value>both</param-value>
</init-param>
<init-param>
<param-name>gzip</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>useFileMappedBuffer</param-name>
<param-value>true</param-value>
</init-param>
<!--
<init-param>
<param-name>cacheControl</param-name>
<param-value>max-age=3600,public</param-value>
</init-param>
-->
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
<!-- ==================================================================== -->
<!-- JSP Servlet -->
<!-- This is the jasper JSP servlet from the jakarta project -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- The JSP page compiler and execution servlet, which is the mechanism -->
<!-- used by Glassfish to support JSP pages. Traditionally, this servlet -->
<!-- is mapped to URL patterh "*.jsp". This servlet supports the -->
<!-- following initialization parameters (default values are in square -->
<!-- brackets): -->
<!-- -->
<!-- checkInterval If development is false and reloading is true, -->
<!-- background compiles are enabled. checkInterval -->
<!-- is the time in seconds between checks to see -->
<!-- if a JSP page needs to be recompiled. [300] -->
<!-- -->
<!-- compiler Which compiler Ant should use to compile JSP -->
<!-- pages. See the Ant documenation for more -->
<!-- information. [javac] -->
<!-- -->
<!-- classdebuginfo Should the class file be compiled with -->
<!-- debugging information? [true] -->
<!-- -->
<!-- classpath What class path should I use while compiling -->
<!-- generated servlets? [Created dynamically -->
<!-- based on the current web application] -->
<!-- Set to ? to make the container explicitly set -->
<!-- this parameter. -->
<!-- -->
<!-- development Is Jasper used in development mode (will check -->
<!-- for JSP modification on every access)? [true] -->
<!-- -->
<!-- enablePooling Determines whether tag handler pooling is -->
<!-- enabled [true] -->
<!-- -->
<!-- fork Tell Ant to fork compiles of JSP pages so that -->
<!-- a separate JVM is used for JSP page compiles -->
<!-- from the one Tomcat is running in. [true] -->
<!-- -->
<!-- ieClassId The class-id value to be sent to Internet -->
<!-- Explorer when using <jsp:plugin> tags. -->
<!-- [clsid:8AD9C840-044E-11D1-B3E9-00805F499D93] -->
<!-- -->
<!-- javaEncoding Java file encoding to use for generating java -->
<!-- source files. [UTF-8] -->
<!-- -->
<!-- keepgenerated Should we keep the generated Java source code -->
<!-- for each page instead of deleting it? [true] -->
<!-- -->
<!-- logVerbosityLevel The level of detailed messages to be produced -->
<!-- by this servlet. Increasing levels cause the -->
<!-- generation of more messages. Valid values are -->
<!-- FATAL, ERROR, WARNING, INFORMATION, and DEBUG. -->
<!-- [WARNING] -->
<!-- -->
<!-- mappedfile Should we generate static content with one -->
<!-- print statement per input line, to ease -->
<!-- debugging? [false] -->
<!-- -->
<!-- -->
<!-- reloading Should Jasper check for modified JSPs? [true] -->
<!-- -->
<!-- suppressSmap Should the generation of SMAP info for JSR45 -->
<!-- debugging be suppressed? [false] -->
<!-- -->
<!-- dumpSmap Should the SMAP info for JSR45 debugging be -->
<!-- dumped to a file? [false] -->
<!-- False if suppressSmap is true -->
<!-- -->
<!-- scratchdir What scratch directory should we use when -->
<!-- compiling JSP pages? [default work directory -->
<!-- for the current web application] -->
<!-- -->
<!-- tagpoolMaxSize The maximum tag handler pool size [5] -->
<!-- -->
<!-- xpoweredBy Determines whether X-Powered-By response -->
<!-- header is added by generated servlet [false] -->
<!-- -->
<!-- If you wish to use Jikes to compile JSP pages: -->
<!-- Set the init parameter "compiler" to "jikes". Define -->
<!-- the property "-Dbuild.compiler.emacs=true" when starting Jetty -->
<!-- to cause Jikes to emit error messages in a format compatible with -->
<!-- Jasper. -->
<!-- If you get an error reporting that jikes can't use UTF-8 encoding, -->
<!-- try setting the init parameter "javaEncoding" to "ISO-8859-1". -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<servlet id="jsp">
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>logVerbosityLevel</param-name>
<param-value>DEBUG</param-value>
</init-param>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<!--
<init-param>
<param-name>classpath</param-name>
<param-value>?</param-value>
</init-param>
-->
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.jsp</url-pattern>
<url-pattern>*.jspf</url-pattern>
<url-pattern>*.jspx</url-pattern>
<url-pattern>*.xsp</url-pattern>
<url-pattern>*.JSP</url-pattern>
<url-pattern>*.JSPF</url-pattern>
<url-pattern>*.JSPX</url-pattern>
<url-pattern>*.XSP</url-pattern>
</servlet-mapping>
<!-- ==================================================================== -->
<!-- Dynamic Servlet Invoker. -->
<!-- This servlet invokes anonymous servlets that have not been defined -->
<!-- in the web.xml or by other means. The first element of the pathInfo -->
<!-- of a request passed to the envoker is treated as a servlet name for -->
<!-- an existing servlet, or as a class name of a new servlet. -->
<!-- This servlet is normally mapped to /servlet/* -->
<!-- This servlet support the following initParams: -->
<!-- -->
<!-- nonContextServlets If false, the invoker can only load -->
<!-- servlets from the contexts classloader. -->
<!-- This is false by default and setting this -->
<!-- to true may have security implications. -->
<!-- -->
<!-- verbose If true, log dynamic loads -->
<!-- -->
<!-- * All other parameters are copied to the -->
<!-- each dynamic servlet as init parameters -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- Uncomment for dynamic invocation
<servlet>
<servlet-name>invoker</servlet-name>
<servlet-class>org.eclipse.jetty.servlet.Invoker</servlet-class>
<init-param>
<param-name>verbose</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>nonContextServlets</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>dynamicParam</param-name>
<param-value>anyValue</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping> <servlet-name>invoker</servlet-name> <url-pattern>/servlet/*</url-pattern> </servlet-mapping>
-->
<!-- ==================================================================== -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<!-- ==================================================================== -->
<!-- Default MIME mappings -->
<!-- The default MIME mappings are provided by the mime.properties -->
<!-- resource in the org.eclipse.jetty.server.jar file. Additional or modified -->
<!-- mappings may be specified here -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- UNCOMMENT TO ACTIVATE
<mime-mapping>
<extension>mysuffix</extension>
<mime-type>mymime/type</mime-type>
</mime-mapping>
-->
<!-- ==================================================================== -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- ==================================================================== -->
<locale-encoding-mapping-list>
<locale-encoding-mapping><locale>ar</locale><encoding>ISO-8859-6</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>be</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>bg</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>ca</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>cs</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>da</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>de</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>el</locale><encoding>ISO-8859-7</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>en</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>es</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>et</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>fi</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>fr</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>hr</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>hu</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>is</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>it</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>iw</locale><encoding>ISO-8859-8</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>ja</locale><encoding>Shift_JIS</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>ko</locale><encoding>EUC-KR</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>lt</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>lv</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>mk</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>nl</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>no</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>pl</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>pt</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>ro</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>ru</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>sh</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>sk</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>sl</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>sq</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>sr</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>sv</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>tr</locale><encoding>ISO-8859-9</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>uk</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>zh</locale><encoding>GB2312</encoding></locale-encoding-mapping>
<locale-encoding-mapping><locale>zh_TW</locale><encoding>Big5</encoding></locale-encoding-mapping>
</locale-encoding-mapping-list>
<security-constraint>
<web-resource-collection>
<web-resource-name>Disable TRACE</web-resource-name>
<url-pattern>/</url-pattern>
<http-method>TRACE</http-method>
</web-resource-collection>
<auth-constraint/>
</security-constraint>
</web-app>

View File

@ -0,0 +1,36 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call name="addLifeCycle">
<Arg>
<New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
<Set name="contexts">
<Ref id="Contexts" />
</Set>
<Set name="configurationManager">
<New class="org.eclipse.jetty.deploy.support.FileConfigurationManager">
<Set name="file">
<Property name="test.targetdir" default="target" />/xml-configured-jetty.properties
</Set>
</New>
</Set>
<!-- Providers of Apps -->
<Call name="addAppProvider">
<Arg>
<New class="org.eclipse.jetty.deploy.providers.MonitoredDirAppProvider">
<Set name="monitoredDir">
<Property name="jetty.home" />/contexts
</Set>
<Set name="scanInterval">1</Set>
<Set name="recursive">true</Set>
</New>
</Arg>
</Call>
</New>
</Arg>
</Call>
</Configure>

View File

@ -0,0 +1,139 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<!-- =============================================================== -->
<!-- Configure the Jetty Server -->
<!-- -->
<!-- Documentation of this file format can be found at: -->
<!-- http://docs.codehaus.org/display/JETTY/jetty.xml -->
<!-- -->
<!-- =============================================================== -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Server Thread Pool -->
<!-- =========================================================== -->
<Set name="ThreadPool">
<!-- Default queued blocking threadpool
-->
<New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
<Set name="minThreads">10</Set>
<Set name="maxThreads">200</Set>
</New>
<!-- Optional Java 5 bounded threadpool with job queue
<New class="org.eclipse.thread.concurrent.ThreadPool">
<Set name="corePoolSize">50</Set>
<Set name="maximumPoolSize">50</Set>
</New>
-->
</Set>
<!-- =========================================================== -->
<!-- Set connectors -->
<!-- =========================================================== -->
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
<Set name="host"></Set>
<Set name="port">0</Set>
<Set name="maxIdleTime">300000</Set>
<Set name="Acceptors">2</Set>
<Set name="statsOn">false</Set>
<Set name="confidentialPort">8443</Set>
<Set name="lowResourcesConnections">20000</Set>
<Set name="lowResourcesMaxIdleTime">5000</Set>
</New>
</Arg>
</Call>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- To add a HTTPS SSL connector -->
<!-- mixin jetty-ssl.xml: -->
<!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- To add a HTTP blocking connector -->
<!-- mixin jetty-bio.xml: -->
<!-- java -jar start.jar etc/jetty.xml etc/jetty-bio.xml -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- To allow Jetty to be started from xinetd -->
<!-- mixin jetty-xinetd.xml: -->
<!-- java -jar start.jar etc/jetty.xml etc/jetty-xinetd.xml -->
<!-- -->
<!-- See jetty-xinetd.xml for further instructions. -->
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- =========================================================== -->
<!-- Set handler Collection Structure -->
<!-- =========================================================== -->
<Set name="handler">
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<Set name="handlers">
<Array type="org.eclipse.jetty.server.Handler">
<Item>
<New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
</Item>
<Item>
<New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
</Item>
<Item>
<New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler"/>
</Item>
</Array>
</Set>
</New>
</Set>
<!-- =========================================================== -->
<!-- Configure Authentication Login Service -->
<!-- Realms may be configured for the entire server here, or -->
<!-- they can be configured for a specific web app in a context -->
<!-- configuration (see $(jetty.home)/contexts/test.xml for an -->
<!-- example). -->
<!-- =========================================================== -->
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.security.HashLoginService">
<Set name="name">Test Realm</Set>
<Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
<Set name="refreshInterval">0</Set>
</New>
</Arg>
</Call>
<!-- =========================================================== -->
<!-- Configure Request Log -->
<!-- Request logs may be configured for the entire server here, -->
<!-- or they can be configured for a specific web app in a -->
<!-- contexts configuration (see $(jetty.home)/contexts/test.xml -->
<!-- for an example). -->
<!-- =========================================================== -->
<Ref id="RequestLog">
<Set name="requestLog">
<New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
<Set name="filename"><SystemProperty name="jetty.home" default="."/>/logs/yyyy_mm_dd.request.log</Set>
<Set name="filenameDateFormat">yyyy_MM_dd</Set>
<Set name="retainDays">90</Set>
<Set name="append">true</Set>
<Set name="extended">false</Set>
<Set name="logCookies">false</Set>
<Set name="LogTimeZone">GMT</Set>
</New>
</Set>
</Ref>
<!-- =========================================================== -->
<!-- extra options -->
<!-- =========================================================== -->
<Set name="stopAtShutdown">true</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">true</Set>
<Set name="gracefulShutdown">1000</Set>
</Configure>

Binary file not shown.