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