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           * @param deploymentManager
58           *            the {@link DeploymentManager} tracking the {@link AppLifeCycle} and {@link App}
59           * @throws Exception
60           *             if any problem severe enough to halt the AppLifeCycle processing
61           */
62          void processBinding(Node node, App app) throws Exception;
63      }
64  
65      // Well known existing lifecycle Nodes
66      public static final String UNDEPLOYED = "undeployed";
67      public static final String DEPLOYING = "deploying";
68      public static final String DEPLOYED = "deployed";
69      public static final String STARTING = "starting";
70      public static final String STARTED = "started";
71      public static final String STOPPING = "stopping";
72      public static final String UNDEPLOYING = "undeploying";
73      
74      
75      private Map<String, List<Binding>> lifecyclebindings = new HashMap<String, List<Binding>>();
76  
77      public AppLifeCycle()
78      {
79          // Define Default Graph
80  
81          // undeployed -> deployed
82          addEdge(UNDEPLOYED,DEPLOYING);
83          addEdge(DEPLOYING,DEPLOYED);
84  
85          // deployed -> started
86          addEdge(DEPLOYED,STARTING);
87          addEdge(STARTING,STARTED);
88  
89          // started -> deployed
90          addEdge(STARTED,STOPPING);
91          addEdge(STOPPING,DEPLOYED);
92  
93          // deployed -> undeployed
94          addEdge(DEPLOYED,UNDEPLOYING);
95          addEdge(UNDEPLOYING,UNDEPLOYED);
96      }
97  
98      public void addBinding(AppLifeCycle.Binding binding)
99      {
100         for (String nodeName : binding.getBindingTargets())
101         {
102             List<Binding> bindings = lifecyclebindings.get(nodeName);
103             if (bindings == null)
104             {
105                 bindings = new ArrayList<Binding>();
106             }
107             bindings.add(binding);
108 
109             lifecyclebindings.put(nodeName,bindings);
110         }
111     }
112     
113     public void removeBinding(AppLifeCycle.Binding binding)
114     {
115         for (String nodeName : binding.getBindingTargets())
116         {
117             List<Binding> bindings = lifecyclebindings.get(nodeName);
118             if (bindings != null)
119                 bindings.remove(binding);
120         }
121     }
122 
123     /**
124      * Get all {@link Node} bound objects.
125      * 
126      * @return Set of Object(s) for all lifecycle bindings. never null.
127      */
128     public Set<AppLifeCycle.Binding> getBindings()
129     {
130         Set<Binding> boundset = new HashSet<Binding>();
131 
132         for (List<Binding> bindings : lifecyclebindings.values())
133         {
134             boundset.addAll(bindings);
135         }
136 
137         return boundset;
138     }
139 
140     /**
141      * Get all objects bound to a specific {@link Node}
142      * 
143      * @return Set of Object(s) for specific lifecycle bindings. never null.
144      */
145     public Set<AppLifeCycle.Binding> getBindings(Node node)
146     {
147         return getBindings(node.getName());
148     }
149 
150     /**
151      * Get all objects bound to a specific {@link Node}
152      * 
153      * @return Set of Object(s) for specific lifecycle bindings. never null.
154      */
155     public Set<AppLifeCycle.Binding> getBindings(String nodeName)
156     {
157         Set<Binding> boundset = new HashSet<Binding>();
158 
159         // Specific node binding
160         List<Binding> bindings = lifecyclebindings.get(nodeName);
161         if (bindings != null)
162         {
163             boundset.addAll(bindings);
164         }
165 
166         // Special 'all nodes' binding
167         bindings = lifecyclebindings.get(ALL_NODES);
168         if (bindings != null)
169         {
170             boundset.addAll(bindings);
171         }
172 
173         return boundset;
174     }
175 
176     public void runBindings(Node node, App app, DeploymentManager deploymentManager) throws Throwable
177     {
178         for (Binding binding : getBindings(node))
179         {
180             if (Log.isDebugEnabled())
181                 Log.debug("Calling " + binding.getClass().getName()+" for "+app);
182             binding.processBinding(node,app);
183         }
184     }
185 }