blob: 39749e8b0370a7bc18b643dff88419401ca7ae87 [file] [log] [blame]
//
// ========================================================================
// Copyright (c) 1995-2017 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;
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;
import org.eclipse.jetty.util.log.Logger;
/**
* The lifecycle of an App in the {@link DeploymentManager}.
* <p>
* Setups a the default {@link Graph}, and manages the bindings to the life cycle via the {@link AppLifeCycle.Binding}
* annotation.
* <p>
* <img alt="app lifecycle graph" src="doc-files/AppLifeCycle.png">
*/
public class AppLifeCycle extends Graph
{
private static final Logger LOG = Log.getLogger(AppLifeCycle.class);
private static final String ALL_NODES = "*";
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
* @throws Exception
* if any problem severe enough to halt the AppLifeCycle processing
*/
void processBinding(Node node, App app) throws Exception;
}
// Well known existing lifecycle Nodes
public static final String UNDEPLOYED = "undeployed";
public static final String DEPLOYING = "deploying";
public static final String DEPLOYED = "deployed";
public static final String STARTING = "starting";
public static final String STARTED = "started";
public static final String STOPPING = "stopping";
public static final String UNDEPLOYING = "undeploying";
private Map<String, List<Binding>> lifecyclebindings = new HashMap<String, List<Binding>>();
public AppLifeCycle()
{
// Define Default Graph
// undeployed -> deployed
addEdge(UNDEPLOYED,DEPLOYING);
addEdge(DEPLOYING,DEPLOYED);
// deployed -> started
addEdge(DEPLOYED,STARTING);
addEdge(STARTING,STARTED);
// started -> deployed
addEdge(STARTED,STOPPING);
addEdge(STOPPING,DEPLOYED);
// deployed -> undeployed
addEdge(DEPLOYED,UNDEPLOYING);
addEdge(UNDEPLOYING,UNDEPLOYED);
}
public void addBinding(AppLifeCycle.Binding binding)
{
for (String nodeName : binding.getBindingTargets())
{
List<Binding> bindings = lifecyclebindings.get(nodeName);
if (bindings == null)
{
bindings = new ArrayList<Binding>();
}
bindings.add(binding);
lifecyclebindings.put(nodeName,bindings);
}
}
public void removeBinding(AppLifeCycle.Binding binding)
{
for (String nodeName : binding.getBindingTargets())
{
List<Binding> bindings = lifecyclebindings.get(nodeName);
if (bindings != null)
bindings.remove(binding);
}
}
/**
* 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}
*
* @param node the deployment graph node
* @return Set of Object(s) for specific lifecycle bindings. never null.
*/
public Set<AppLifeCycle.Binding> getBindings(Node node)
{
return getBindings(node.getName());
}
/**
* Get all objects bound to a specific {@link Node}
*
* @param nodeName the node name
* @return Set of Object(s) for specific lifecycle bindings. never null.
*/
public Set<AppLifeCycle.Binding> getBindings(String nodeName)
{
Set<Binding> boundset = new HashSet<Binding>();
// Specific node binding
List<Binding> bindings = lifecyclebindings.get(nodeName);
if (bindings != null)
{
boundset.addAll(bindings);
}
// Special 'all nodes' binding
bindings = lifecyclebindings.get(ALL_NODES);
if (bindings != null)
{
boundset.addAll(bindings);
}
return boundset;
}
public void runBindings(Node node, App app, DeploymentManager deploymentManager) throws Throwable
{
for (Binding binding : getBindings(node))
{
if (LOG.isDebugEnabled())
LOG.debug("Calling " + binding.getClass().getName()+" for "+app);
binding.processBinding(node,app);
}
}
}