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