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