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 (_useStandardBindings)
221 {
222 LOG.debug("DeploymentManager using standard bindings");
223 addLifeCycleBinding(new StandardDeployer());
224 addLifeCycleBinding(new StandardStarter());
225 addLifeCycleBinding(new StandardStopper());
226 addLifeCycleBinding(new StandardUndeployer());
227 }
228
229
230 for (AppProvider provider : _providers)
231 {
232 startAppProvider(provider);
233 }
234 super.doStart();
235 }
236
237 @Override
238 protected void doStop() throws Exception
239 {
240
241 for (AppProvider provider : _providers)
242 {
243 try
244 {
245 provider.stop();
246 }
247 catch (Exception e)
248 {
249 LOG.warn("Unable to start AppProvider",e);
250 }
251 }
252 super.doStop();
253 }
254
255 private AppEntry findAppByOriginId(String originId)
256 {
257 if (originId == null)
258 {
259 return null;
260 }
261
262 for (AppEntry entry : _apps)
263 {
264 if (originId.equals(entry.app.getOriginId()))
265 {
266 return entry;
267 }
268 }
269 return null;
270 }
271
272 public App getAppByOriginId(String originId)
273 {
274 AppEntry entry = findAppByOriginId(originId);
275 if (entry == null)
276 {
277 return null;
278 }
279 return entry.app;
280 }
281
282 public Collection<AppEntry> getAppEntries()
283 {
284 return _apps;
285 }
286
287 @ManagedAttribute("Deployed Apps")
288 public Collection<App> getApps()
289 {
290 List<App> ret = new ArrayList<App>();
291 for (AppEntry entry : _apps)
292 {
293 ret.add(entry.app);
294 }
295 return ret;
296 }
297
298
299
300
301
302
303
304
305 public Collection<App> getApps(Node node)
306 {
307 List<App> ret = new ArrayList<App>();
308 for (AppEntry entry : _apps)
309 {
310 if (entry.lifecyleNode == node)
311 {
312 ret.add(entry.app);
313 }
314 }
315 return ret;
316 }
317
318 public List<App> getAppsWithSameContext(App app)
319 {
320 List<App> ret = new ArrayList<App>();
321 if (app == null)
322 {
323 return ret;
324 }
325
326 String contextId = app.getContextPath();
327 if (contextId == null)
328 {
329
330 return ret;
331 }
332
333 for (AppEntry entry : _apps)
334 {
335 if (entry.app.equals(app))
336 {
337
338
339 continue;
340 }
341
342 if (contextId.equals(entry.app.getContextPath()))
343 {
344 ret.add(entry.app);
345 }
346 }
347 return ret;
348 }
349
350
351
352
353
354
355
356 public Object getContextAttribute(String name)
357 {
358 return _contextAttributes.getAttribute(name);
359 }
360
361 public AttributesMap getContextAttributes()
362 {
363 return _contextAttributes;
364 }
365
366 @ManagedAttribute("Deployed Contexts")
367 public ContextHandlerCollection getContexts()
368 {
369 return _contexts;
370 }
371
372 public String getDefaultLifeCycleGoal()
373 {
374 return _defaultLifeCycleGoal;
375 }
376
377 public AppLifeCycle getLifeCycle()
378 {
379 return _lifecycle;
380 }
381
382 public Server getServer()
383 {
384 if (_contexts == null)
385 {
386 return null;
387 }
388 return _contexts.getServer();
389 }
390
391
392
393
394
395
396
397 public void removeApp(App app)
398 {
399 Iterator<AppEntry> it = _apps.iterator();
400 while (it.hasNext())
401 {
402 AppEntry entry = it.next();
403 if (entry.app.equals(app))
404 {
405 if (! AppLifeCycle.UNDEPLOYED.equals(entry.lifecyleNode.getName()))
406 requestAppGoal(entry.app,AppLifeCycle.UNDEPLOYED);
407 it.remove();
408 LOG.debug("Deployable removed: {}",entry.app);
409 }
410 }
411 }
412
413 public void removeAppProvider(AppProvider provider)
414 {
415 if(_providers.remove(provider))
416 removeBean(provider);
417
418 try
419 {
420 provider.stop();
421 }
422 catch (Exception e)
423 {
424 LOG.warn("Unable to stop Provider",e);
425 }
426 }
427
428
429
430
431
432
433 public void removeContextAttribute(String name)
434 {
435 _contextAttributes.removeAttribute(name);
436 }
437
438
439
440
441
442
443
444
445
446
447 public void requestAppGoal(App app, String nodeName)
448 {
449 AppEntry appentry = findAppByOriginId(app.getOriginId());
450 if (appentry == null)
451 {
452 throw new IllegalStateException("App not being tracked by Deployment Manager: " + app);
453 }
454
455 requestAppGoal(appentry,nodeName);
456 }
457
458
459
460
461
462
463
464
465
466
467 private void requestAppGoal(AppEntry appentry, String nodeName)
468 {
469 Node destinationNode = _lifecycle.getNodeByName(nodeName);
470 if (destinationNode == null)
471 {
472 throw new IllegalStateException("Node not present in Deployment Manager: " + nodeName);
473 }
474
475 Path path = _lifecycle.getPath(appentry.lifecyleNode,destinationNode);
476 if (path.isEmpty())
477 {
478
479 return;
480 }
481
482
483 try
484 {
485 Iterator<Node> it = path.getNodes().iterator();
486 if (it.hasNext())
487 {
488
489
490 it.next();
491 while (it.hasNext())
492 {
493 Node node = it.next();
494 LOG.debug("Executing Node {}",node);
495 _lifecycle.runBindings(node,appentry.app,this);
496 appentry.setLifeCycleNode(node);
497 }
498 }
499 }
500 catch (Throwable t)
501 {
502 LOG.warn("Unable to reach node goal: " + nodeName,t);
503 }
504 }
505
506
507
508
509
510
511
512
513
514
515 @ManagedOperation(value="request the app to be moved to the specified lifecycle node", impact="ACTION")
516 public void requestAppGoal(@Name("appId") String appId, @Name("nodeName") String nodeName)
517 {
518 AppEntry appentry = findAppByOriginId(appId);
519 if (appentry == null)
520 {
521 throw new IllegalStateException("App not being tracked by Deployment Manager: " + appId);
522 }
523 requestAppGoal(appentry,nodeName);
524 }
525
526
527
528
529
530
531
532 public void setContextAttribute(String name, Object value)
533 {
534 _contextAttributes.setAttribute(name,value);
535 }
536
537 public void setContextAttributes(AttributesMap contextAttributes)
538 {
539 this._contextAttributes = contextAttributes;
540 }
541
542 public void setContexts(ContextHandlerCollection contexts)
543 {
544 this._contexts = contexts;
545 }
546
547 public void setDefaultLifeCycleGoal(String defaultLifeCycleState)
548 {
549 this._defaultLifeCycleGoal = defaultLifeCycleState;
550 }
551
552 private void startAppProvider(AppProvider provider)
553 {
554 try
555 {
556 provider.setDeploymentManager(this);
557 provider.start();
558 }
559 catch (Exception e)
560 {
561 LOG.warn("Unable to start AppProvider",e);
562 }
563 }
564
565 public void undeployAll()
566 {
567 LOG.debug("Undeploy All");
568 for (AppEntry appentry : _apps)
569 {
570 requestAppGoal(appentry,"undeployed");
571 }
572 }
573
574 public boolean isUseStandardBindings()
575 {
576 return _useStandardBindings;
577 }
578
579 public void setUseStandardBindings(boolean useStandardBindings)
580 {
581 this._useStandardBindings = useStandardBindings;
582 }
583
584 public Collection<Node> getNodes()
585 {
586 return _lifecycle.getNodes();
587 }
588
589 @ManagedOperation(value="list apps that are located at specified App LifeCycle nodes", impact="ACTION")
590 public Collection<App> getApps(@Name("nodeName") String nodeName)
591 {
592 return getApps(_lifecycle.getNodeByName(nodeName));
593 }
594 }