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  
29  /**
30   * The lifecycle of an App in the {@link DeploymentManager}.
31   * 
32   * Setups a the default {@link Graph}, and manages the bindings to the life cycle via the {@link AppLifeCycle.Binding}
33   * annotation.
34   * <p>
35   * <img src="doc-files/AppLifeCycle.png">
36   */
37  public class AppLifeCycle extends Graph
38  {
39      private static final String ALL_NODES = "*";
40  
41      public static interface Binding
42      {
43          /**
44           * Get a list of targets that this implementation should bind to.
45           * 
46           * @return the array of String node names to bind to. (use <code>"*"</code> to bind to all known node names)
47           */
48          String[] getBindingTargets();
49  
50          /**
51           * Event called to process a {@link AppLifeCycle} binding.
52           * 
53           * @param node
54           *            the node being processed
55           * @param app
56           *            the app being processed
57           * @throws Exception
58           *             if any problem severe enough to halt the AppLifeCycle processing
59           */
60          void processBinding(Node node, App app) throws Exception;
61      }
62  
63      // Well known existing lifecycle Nodes
64      public static final String UNDEPLOYED = "undeployed";
65      public static final String DEPLOYING = "deploying";
66      public static final String DEPLOYED = "deployed";
67      public static final String STARTING = "starting";
68      public static final String STARTED = "started";
69      public static final String STOPPING = "stopping";
70      public static final String UNDEPLOYING = "undeploying";
71      
72      
73      private Map<String, List<Binding>> lifecyclebindings = new HashMap<String, List<Binding>>();
74  
75      public AppLifeCycle()
76      {
77          // Define Default Graph
78  
79          // undeployed -> deployed
80          addEdge(UNDEPLOYED,DEPLOYING);
81          addEdge(DEPLOYING,DEPLOYED);
82  
83          // deployed -> started
84          addEdge(DEPLOYED,STARTING);
85          addEdge(STARTING,STARTED);
86  
87          // started -> deployed
88          addEdge(STARTED,STOPPING);
89          addEdge(STOPPING,DEPLOYED);
90  
91          // deployed -> undeployed
92          addEdge(DEPLOYED,UNDEPLOYING);
93          addEdge(UNDEPLOYING,UNDEPLOYED);
94      }
95  
96      public void addBinding(AppLifeCycle.Binding binding)
97      {
98          for (String nodeName : binding.getBindingTargets())
99          {
100             List<Binding> bindings = lifecyclebindings.get(nodeName);
101             if (bindings == null)
102             {
103                 bindings = new ArrayList<Binding>();
104             }
105             bindings.add(binding);
106 
107             lifecyclebindings.put(nodeName,bindings);
108         }
109     }
110     
111     public void removeBinding(AppLifeCycle.Binding binding)
112     {
113         for (String nodeName : binding.getBindingTargets())
114         {
115             List<Binding> bindings = lifecyclebindings.get(nodeName);
116             if (bindings != null)
117                 bindings.remove(binding);
118         }
119     }
120 
121     /**
122      * Get all {@link Node} bound objects.
123      * 
124      * @return Set of Object(s) for all lifecycle bindings. never null.
125      */
126     public Set<AppLifeCycle.Binding> getBindings()
127     {
128         Set<Binding> boundset = new HashSet<Binding>();
129 
130         for (List<Binding> bindings : lifecyclebindings.values())
131         {
132             boundset.addAll(bindings);
133         }
134 
135         return boundset;
136     }
137 
138     /**
139      * Get all objects bound to a specific {@link Node}
140      * 
141      * @return Set of Object(s) for specific lifecycle bindings. never null.
142      */
143     public Set<AppLifeCycle.Binding> getBindings(Node node)
144     {
145         return getBindings(node.getName());
146     }
147 
148     /**
149      * Get all objects bound to a specific {@link Node}
150      * 
151      * @return Set of Object(s) for specific lifecycle bindings. never null.
152      */
153     public Set<AppLifeCycle.Binding> getBindings(String nodeName)
154     {
155         Set<Binding> boundset = new HashSet<Binding>();
156 
157         // Specific node binding
158         List<Binding> bindings = lifecyclebindings.get(nodeName);
159         if (bindings != null)
160         {
161             boundset.addAll(bindings);
162         }
163 
164         // Special 'all nodes' binding
165         bindings = lifecyclebindings.get(ALL_NODES);
166         if (bindings != null)
167         {
168             boundset.addAll(bindings);
169         }
170 
171         return boundset;
172     }
173 
174     public void runBindings(Node node, App app, DeploymentManager deploymentManager) throws Throwable
175     {
176         for (Binding binding : getBindings(node))
177         {
178             if (Log.isDebugEnabled())
179                 Log.debug("Calling " + binding.getClass().getName()+" for "+app);
180             binding.processBinding(node,app);
181         }
182     }
183 }