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