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