1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.eclipse.jetty.deploy;
17
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Queue;
26 import java.util.concurrent.ConcurrentLinkedQueue;
27
28 import org.eclipse.jetty.deploy.bindings.StandardDeployer;
29 import org.eclipse.jetty.deploy.bindings.StandardStarter;
30 import org.eclipse.jetty.deploy.bindings.StandardStopper;
31 import org.eclipse.jetty.deploy.bindings.StandardUndeployer;
32 import org.eclipse.jetty.deploy.graph.Edge;
33 import org.eclipse.jetty.deploy.graph.Node;
34 import org.eclipse.jetty.deploy.graph.Path;
35 import org.eclipse.jetty.server.Server;
36 import org.eclipse.jetty.server.handler.ContextHandlerCollection;
37 import org.eclipse.jetty.util.AttributesMap;
38 import org.eclipse.jetty.util.component.AggregateLifeCycle;
39 import org.eclipse.jetty.util.log.Log;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class DeploymentManager extends AggregateLifeCycle
56 {
57
58
59
60 public class AppEntry
61 {
62
63
64
65
66
67 private int version;
68
69
70
71
72 private App app;
73
74
75
76
77 private Node lifecyleNode;
78
79
80
81
82 private Map<Node, Long> stateTimestamps = new HashMap<Node, Long>();
83
84 public App getApp()
85 {
86 return app;
87 }
88
89 public Node getLifecyleNode()
90 {
91 return lifecyleNode;
92 }
93
94 public Map<Node, Long> getStateTimestamps()
95 {
96 return stateTimestamps;
97 }
98
99 public int getVersion()
100 {
101 return version;
102 }
103
104 void setLifeCycleNode(Node node)
105 {
106 this.lifecyleNode = node;
107 this.stateTimestamps.put(node,Long.valueOf(System.currentTimeMillis()));
108 }
109 }
110
111 private final List<AppProvider> _providers = new ArrayList<AppProvider>();
112 private final AppLifeCycle _lifecycle = new AppLifeCycle();
113 private final Queue<AppEntry> _apps = new ConcurrentLinkedQueue<AppEntry>();
114 private AttributesMap _contextAttributes = new AttributesMap();
115 private ContextHandlerCollection _contexts;
116 private boolean _useStandardBindings = true;
117 private String _defaultLifeCycleGoal = AppLifeCycle.STARTED;
118
119
120
121
122
123
124 public void addApp(App app)
125 {
126 Log.info("Deployable added: " + app.getOriginId());
127 AppEntry entry = new AppEntry();
128 entry.app = app;
129 entry.setLifeCycleNode(_lifecycle.getNodeByName("undeployed"));
130 _apps.add(entry);
131
132 if (isRunning() && _defaultLifeCycleGoal != null)
133 {
134
135 this.requestAppGoal(entry,_defaultLifeCycleGoal);
136 }
137 }
138
139 public void setAppProviders(Collection<AppProvider> providers)
140 {
141 if (isRunning())
142 throw new IllegalStateException();
143
144 _providers.clear();
145 removeBeans();
146 for (AppProvider provider:providers)
147 if (_providers.add(provider))
148 addBean(provider);
149 }
150
151 public Collection<AppProvider> getAppProviders()
152 {
153 return Collections.unmodifiableList(_providers);
154 }
155
156 public void addAppProvider(AppProvider provider)
157 {
158 if (isRunning())
159 throw new IllegalStateException();
160
161 List<AppProvider> old = new ArrayList<AppProvider>(_providers);
162 if (_providers.add(provider) && getServer()!=null)
163 getServer().getContainer().update(this, null, provider, "provider");
164
165 addBean(provider);
166 }
167
168 public void setLifeCycleBindings(Collection<AppLifeCycle.Binding> bindings)
169 {
170 if (isRunning())
171 throw new IllegalStateException();
172 for (AppLifeCycle.Binding b : _lifecycle.getBindings())
173 _lifecycle.removeBinding(b);
174 for (AppLifeCycle.Binding b : bindings)
175 _lifecycle.addBinding(b);
176 }
177
178 public Collection<AppLifeCycle.Binding> getLifeCycleBindings()
179 {
180 return Collections.unmodifiableSet(_lifecycle.getBindings());
181 }
182
183 public void addLifeCycleBinding(AppLifeCycle.Binding binding)
184 {
185 _lifecycle.addBinding(binding);
186 }
187
188
189
190
191
192
193
194
195 public void insertLifeCycleNode(String existingFromNodeName, String existingToNodeName, String insertedNodeName)
196 {
197 Node fromNode = _lifecycle.getNodeByName(existingFromNodeName);
198 Node toNode = _lifecycle.getNodeByName(existingToNodeName);
199 Edge edge = new Edge(fromNode,toNode);
200 _lifecycle.insertNode(edge,insertedNodeName);
201 }
202
203 @Override
204 protected void doStart() throws Exception
205 {
206 if (_useStandardBindings)
207 {
208 Log.debug("DeploymentManager using standard bindings");
209 addLifeCycleBinding(new StandardDeployer());
210 addLifeCycleBinding(new StandardStarter());
211 addLifeCycleBinding(new StandardStopper());
212 addLifeCycleBinding(new StandardUndeployer());
213 }
214
215
216 for (AppProvider provider : _providers)
217 {
218 startAppProvider(provider);
219 }
220 super.doStart();
221 }
222
223 @Override
224 protected void doStop() throws Exception
225 {
226
227 for (AppProvider provider : _providers)
228 {
229 try
230 {
231 provider.stop();
232 }
233 catch (Exception e)
234 {
235 Log.warn("Unable to start AppProvider",e);
236 }
237 }
238 super.doStop();
239 }
240
241 private AppEntry findAppByOriginId(String originId)
242 {
243 if (originId == null)
244 {
245 return null;
246 }
247
248 for (AppEntry entry : _apps)
249 {
250 if (originId.equals(entry.app.getOriginId()))
251 {
252 return entry;
253 }
254 }
255 return null;
256 }
257
258 public App getAppByOriginId(String originId)
259 {
260 AppEntry entry = findAppByOriginId(originId);
261 if (entry == null)
262 {
263 return null;
264 }
265 return entry.app;
266 }
267
268 public Collection<AppEntry> getAppEntries()
269 {
270 return _apps;
271 }
272
273 public Collection<App> getApps()
274 {
275 List<App> ret = new ArrayList<App>();
276 for (AppEntry entry : _apps)
277 {
278 ret.add(entry.app);
279 }
280 return ret;
281 }
282
283
284
285
286
287
288
289
290 public Collection<App> getApps(Node node)
291 {
292 List<App> ret = new ArrayList<App>();
293 for (AppEntry entry : _apps)
294 {
295 if (entry.lifecyleNode == node)
296 {
297 ret.add(entry.app);
298 }
299 }
300 return ret;
301 }
302
303 public List<App> getAppsWithSameContext(App app)
304 {
305 List<App> ret = new ArrayList<App>();
306 if (app == null)
307 {
308 return ret;
309 }
310
311 String contextId = app.getContextPath();
312 if (contextId == null)
313 {
314
315 return ret;
316 }
317
318 for (AppEntry entry : _apps)
319 {
320 if (entry.app.equals(app))
321 {
322
323
324 continue;
325 }
326
327 if (contextId.equals(entry.app.getContextPath()))
328 {
329 ret.add(entry.app);
330 }
331 }
332 return ret;
333 }
334
335
336
337
338
339
340
341 public Object getContextAttribute(String name)
342 {
343 return _contextAttributes.getAttribute(name);
344 }
345
346 public AttributesMap getContextAttributes()
347 {
348 return _contextAttributes;
349 }
350
351 public ContextHandlerCollection getContexts()
352 {
353 return _contexts;
354 }
355
356 public String getDefaultLifeCycleGoal()
357 {
358 return _defaultLifeCycleGoal;
359 }
360
361 public AppLifeCycle getLifeCycle()
362 {
363 return _lifecycle;
364 }
365
366 public Server getServer()
367 {
368 if (_contexts == null)
369 {
370 return null;
371 }
372 return _contexts.getServer();
373 }
374
375
376
377
378
379
380
381 public void removeApp(App app)
382 {
383 Iterator<AppEntry> it = _apps.iterator();
384 while (it.hasNext())
385 {
386 AppEntry entry = it.next();
387 if (entry.app.equals(app))
388 {
389 if (! AppLifeCycle.UNDEPLOYED.equals(entry.lifecyleNode.getName()))
390 requestAppGoal(entry.app,AppLifeCycle.UNDEPLOYED);
391 it.remove();
392 Log.info("Deployable removed: " + entry.app);
393 }
394 }
395 }
396
397 public void removeAppProvider(AppProvider provider)
398 {
399 if(_providers.remove(provider))
400 {
401 removeBean(provider);
402 if (getServer()!=null)
403 getServer().getContainer().update(this, provider,null, "provider");
404 }
405 try
406 {
407 provider.stop();
408 }
409 catch (Exception e)
410 {
411 Log.warn("Unable to stop Provider",e);
412 }
413 }
414
415
416
417
418
419
420 public void removeContextAttribute(String name)
421 {
422 _contextAttributes.removeAttribute(name);
423 }
424
425
426
427
428
429
430
431
432
433
434 public void requestAppGoal(App app, String nodeName)
435 {
436 AppEntry appentry = findAppByOriginId(app.getOriginId());
437 if (appentry == null)
438 {
439 throw new IllegalStateException("App not being tracked by Deployment Manager: " + app);
440 }
441
442 requestAppGoal(appentry,nodeName);
443 }
444
445
446
447
448
449
450
451
452
453
454 private void requestAppGoal(AppEntry appentry, String nodeName)
455 {
456 Node destinationNode = _lifecycle.getNodeByName(nodeName);
457 if (destinationNode == null)
458 {
459 throw new IllegalStateException("Node not present in Deployment Manager: " + nodeName);
460 }
461
462 Path path = _lifecycle.getPath(appentry.lifecyleNode,destinationNode);
463 if (path.isEmpty())
464 {
465
466 return;
467 }
468
469
470 try
471 {
472 Iterator<Node> it = path.getNodes().iterator();
473 if (it.hasNext())
474 {
475
476
477 it.next();
478 while (it.hasNext())
479 {
480 Node node = it.next();
481 Log.debug("Executing Node: " + node);
482 _lifecycle.runBindings(node,appentry.app,this);
483 appentry.setLifeCycleNode(node);
484 }
485 }
486 }
487 catch (Throwable t)
488 {
489 Log.warn("Unable to reach node goal: " + nodeName,t);
490 }
491 }
492
493
494
495
496
497
498
499
500
501
502 public void requestAppGoal(String appId, String nodeName)
503 {
504 AppEntry appentry = findAppByOriginId(appId);
505 if (appentry == null)
506 {
507 throw new IllegalStateException("App not being tracked by Deployment Manager: " + appId);
508 }
509 requestAppGoal(appentry,nodeName);
510 }
511
512
513
514
515
516
517
518 public void setContextAttribute(String name, Object value)
519 {
520 _contextAttributes.setAttribute(name,value);
521 }
522
523 public void setContextAttributes(AttributesMap contextAttributes)
524 {
525 this._contextAttributes = contextAttributes;
526 }
527
528 public void setContexts(ContextHandlerCollection contexts)
529 {
530 this._contexts = contexts;
531 }
532
533 public void setDefaultLifeCycleGoal(String defaultLifeCycleState)
534 {
535 this._defaultLifeCycleGoal = defaultLifeCycleState;
536 }
537
538 private void startAppProvider(AppProvider provider)
539 {
540 try
541 {
542 provider.setDeploymentManager(this);
543 provider.start();
544 }
545 catch (Exception e)
546 {
547 Log.warn("Unable to start AppProvider",e);
548 }
549 }
550
551 public void undeployAll()
552 {
553 Log.info("Undeploy All");
554 for (AppEntry appentry : _apps)
555 {
556 requestAppGoal(appentry,"undeployed");
557 }
558 }
559
560 public boolean isUseStandardBindings()
561 {
562 return _useStandardBindings;
563 }
564
565 public void setUseStandardBindings(boolean useStandardBindings)
566 {
567 this._useStandardBindings = useStandardBindings;
568 }
569
570 public Collection<Node> getNodes()
571 {
572 return _lifecycle.getNodes();
573 }
574
575 public Collection<App> getApps(String nodeName)
576 {
577 return getApps(_lifecycle.getNodeByName(nodeName));
578 }
579 }