View Javadoc

1   // ========================================================================
2   // Copyright (c) Webtide LLC
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   //
8   // The Eclipse Public License is available at 
9   // http://www.eclipse.org/legal/epl-v10.html
10  //
11  // The Apache License v2.0 is available at
12  // http://www.apache.org/licenses/LICENSE-2.0.txt
13  //
14  // You may elect to redistribute this code under either of these licenses. 
15  // ========================================================================
16  package org.eclipse.jetty.deploy;
17  
18  import java.util.ArrayList;
19  import java.util.HashMap;
20  import java.util.HashSet;
21  import java.util.List;
22  import java.util.Map;
23  import java.util.Set;
24  
25  import org.eclipse.jetty.deploy.graph.Graph;
26  import org.eclipse.jetty.deploy.graph.Node;
27  import org.eclipse.jetty.util.log.Log;
28  import org.eclipse.jetty.util.log.Logger;
29  
30  /**
31   * The lifecycle of an App in the {@link DeploymentManager}.
32   * 
33   * Setups a the default {@link Graph}, and manages the bindings to the life cycle via the {@link AppLifeCycle.Binding}
34   * annotation.
35   * <p>
36   * <img src="doc-files/AppLifeCycle.png">
37   */
38  public class AppLifeCycle extends Graph
39  {
40      private static final Logger LOG = Log.getLogger(AppLifeCycle.class);
41  
42      private static final String ALL_NODES = "*";
43  
44      public static interface Binding
45      {
46          /**
47           * Get a list of targets that this implementation should bind to.
48           * 
49           * @return the array of String node names to bind to. (use <code>"*"</code> to bind to all known node names)
50           */
51          String[] getBindingTargets();
52  
53          /**
54           * Event called to process a {@link AppLifeCycle} binding.
55           * 
56           * @param node
57           *            the node being processed
58           * @param app
59           *            the app being processed
60           * @throws Exception
61           *             if any problem severe enough to halt the AppLifeCycle processing
62           */
63          void processBinding(Node node, App app) throws Exception;
64      }
65  
66      // Well known existing lifecycle Nodes
67      public static final String UNDEPLOYED = "undeployed";
68      public static final String DEPLOYING = "deploying";
69      public static final String DEPLOYED = "deployed";
70      public static final String STARTING = "starting";
71      public static final String STARTED = "started";
72      public static final String STOPPING = "stopping";
73      public static final String UNDEPLOYING = "undeploying";
74      
75      
76      private Map<String, List<Binding>> lifecyclebindings = new HashMap<String, List<Binding>>();
77  
78      public AppLifeCycle()
79      {
80          // Define Default Graph
81  
82          // undeployed -> deployed
83          addEdge(UNDEPLOYED,DEPLOYING);
84          addEdge(DEPLOYING,DEPLOYED);
85  
86          // deployed -> started
87          addEdge(DEPLOYED,STARTING);
88          addEdge(STARTING,STARTED);
89  
90          // started -> deployed
91          addEdge(STARTED,STOPPING);
92          addEdge(STOPPING,DEPLOYED);
93  
94          // deployed -> undeployed
95          addEdge(DEPLOYED,UNDEPLOYING);
96          addEdge(UNDEPLOYING,UNDEPLOYED);
97      }
98  
99      public void addBinding(AppLifeCycle.Binding binding)
100     {
101         for (String nodeName : binding.getBindingTargets())
102         {
103             List<Binding> bindings = lifecyclebindings.get(nodeName);
104             if (bindings == null)
105             {
106                 bindings = new ArrayList<Binding>();
107             }
108             bindings.add(binding);
109 
110             lifecyclebindings.put(nodeName,bindings);
111         }
112     }
113     
114     public void removeBinding(AppLifeCycle.Binding binding)
115     {
116         for (String nodeName : binding.getBindingTargets())
117         {
118             List<Binding> bindings = lifecyclebindings.get(nodeName);
119             if (bindings != null)
120                 bindings.remove(binding);
121         }
122     }
123 
124     /**
125      * Get all {@link Node} bound objects.
126      * 
127      * @return Set of Object(s) for all lifecycle bindings. never null.
128      */
129     public Set<AppLifeCycle.Binding> getBindings()
130     {
131         Set<Binding> boundset = new HashSet<Binding>();
132 
133         for (List<Binding> bindings : lifecyclebindings.values())
134         {
135             boundset.addAll(bindings);
136         }
137 
138         return boundset;
139     }
140 
141     /**
142      * Get all objects bound to a specific {@link Node}
143      * 
144      * @return Set of Object(s) for specific lifecycle bindings. never null.
145      */
146     public Set<AppLifeCycle.Binding> getBindings(Node node)
147     {
148         return getBindings(node.getName());
149     }
150 
151     /**
152      * Get all objects bound to a specific {@link Node}
153      * 
154      * @return Set of Object(s) for specific lifecycle bindings. never null.
155      */
156     public Set<AppLifeCycle.Binding> getBindings(String nodeName)
157     {
158         Set<Binding> boundset = new HashSet<Binding>();
159 
160         // Specific node binding
161         List<Binding> bindings = lifecyclebindings.get(nodeName);
162         if (bindings != null)
163         {
164             boundset.addAll(bindings);
165         }
166 
167         // Special 'all nodes' binding
168         bindings = lifecyclebindings.get(ALL_NODES);
169         if (bindings != null)
170         {
171             boundset.addAll(bindings);
172         }
173 
174         return boundset;
175     }
176 
177     public void runBindings(Node node, App app, DeploymentManager deploymentManager) throws Throwable
178     {
179         for (Binding binding : getBindings(node))
180         {
181             if (LOG.isDebugEnabled())
182                 LOG.debug("Calling " + binding.getClass().getName()+" for "+app);
183             binding.processBinding(node,app);
184         }
185     }
186 }