1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.jmx;
15
16 import java.io.IOException;
17 import java.util.ArrayList;
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Set;
23 import java.util.WeakHashMap;
24 import javax.management.MBeanServer;
25 import javax.management.ObjectInstance;
26 import javax.management.ObjectName;
27
28 import org.eclipse.jetty.util.MultiMap;
29 import org.eclipse.jetty.util.component.AbstractLifeCycle;
30 import org.eclipse.jetty.util.component.AggregateLifeCycle;
31 import org.eclipse.jetty.util.component.Container;
32 import org.eclipse.jetty.util.component.Container.Relationship;
33 import org.eclipse.jetty.util.component.Dumpable;
34 import org.eclipse.jetty.util.log.Log;
35 import org.eclipse.jetty.util.thread.ShutdownThread;
36
37
38
39
40
41
42 public class MBeanContainer extends AbstractLifeCycle implements Container.Listener, Dumpable
43 {
44 private final MBeanServer _server;
45 private final WeakHashMap<Object, ObjectName> _beans = new WeakHashMap<Object, ObjectName>();
46 private final HashMap<String, Integer> _unique = new HashMap<String, Integer>();
47 private final MultiMap<ObjectName> _relations = new MultiMap<ObjectName>();
48 private String _domain = null;
49
50
51
52
53
54
55
56
57 public synchronized ObjectName findMBean(Object object)
58 {
59 ObjectName bean = (ObjectName)_beans.get(object);
60 return bean==null?null:bean;
61 }
62
63
64
65
66
67
68
69
70 public synchronized Object findBean(ObjectName oname)
71 {
72 for (Map.Entry<Object, ObjectName> entry : _beans.entrySet())
73 {
74 ObjectName bean = (ObjectName)entry.getValue();
75 if (bean.equals(oname))
76 return entry.getKey();
77 }
78 return null;
79 }
80
81
82
83
84
85
86
87 public MBeanContainer(MBeanServer server)
88 {
89 _server = server;
90
91 try
92 {
93 start();
94 }
95 catch (Exception e)
96 {
97 Log.ignore(e);
98 }
99 }
100
101
102
103
104
105
106
107 public MBeanServer getMBeanServer()
108 {
109 return _server;
110 }
111
112
113
114
115
116
117
118 public void setDomain (String domain)
119 {
120 _domain = domain;
121 }
122
123
124
125
126
127
128
129 public String getDomain()
130 {
131 return _domain;
132 }
133
134
135
136
137
138
139
140 public synchronized void add(Relationship relationship)
141 {
142 ObjectName parent=(ObjectName)_beans.get(relationship.getParent());
143 if (parent==null)
144 {
145 addBean(relationship.getParent());
146 parent=(ObjectName)_beans.get(relationship.getParent());
147 }
148
149 ObjectName child=(ObjectName)_beans.get(relationship.getChild());
150 if (child==null)
151 {
152 addBean(relationship.getChild());
153 child=(ObjectName)_beans.get(relationship.getChild());
154 }
155
156 if (parent!=null && child!=null)
157 _relations.add(parent,relationship);
158 }
159
160
161
162
163
164
165
166 public synchronized void remove(Relationship relationship)
167 {
168 ObjectName parent=(ObjectName)_beans.get(relationship.getParent());
169 ObjectName child=(ObjectName)_beans.get(relationship.getChild());
170 if (parent!=null && child!=null)
171 _relations.removeValue(parent,relationship);
172 }
173
174
175
176
177
178
179
180 public synchronized void removeBean(Object obj)
181 {
182 ObjectName bean=(ObjectName)_beans.remove(obj);
183
184 if (bean!=null)
185 {
186 List<?> beanRelations = _relations.getValues(bean);
187 if (beanRelations!=null && beanRelations.size()>0)
188 {
189 Log.debug("Unregister {}", beanRelations);
190 List<?> removeList = new ArrayList<Object>(beanRelations);
191 for (Object r : removeList)
192 {
193 Container.Relationship relation = (Relationship)r;
194 relation.getContainer().update(relation.getParent(),relation.getChild(),null,relation.getRelationship(),true);
195 }
196 }
197
198 try
199 {
200 _server.unregisterMBean(bean);
201 Log.debug("Unregistered {}", bean);
202 }
203 catch (javax.management.InstanceNotFoundException e)
204 {
205 Log.ignore(e);
206 }
207 catch (Exception e)
208 {
209 Log.warn(e);
210 }
211 }
212 }
213
214
215
216
217
218
219
220 public synchronized void addBean(Object obj)
221 {
222 try
223 {
224 if (obj == null || _beans.containsKey(obj))
225 return;
226
227 Object mbean = ObjectMBean.mbeanFor(obj);
228 if (mbean == null)
229 return;
230
231 ObjectName oname = null;
232 if (mbean instanceof ObjectMBean)
233 {
234 ((ObjectMBean) mbean).setMBeanContainer(this);
235 oname = ((ObjectMBean)mbean).getObjectName();
236 }
237
238
239 if (oname == null)
240 {
241 String type=obj.getClass().getName().toLowerCase();
242 int dot = type.lastIndexOf('.');
243 if (dot >= 0)
244 type = type.substring(dot + 1);
245
246 String name=null;
247 if (mbean instanceof ObjectMBean)
248 {
249 name = ((ObjectMBean)mbean).getObjectNameBasis();
250 if (name!=null)
251 {
252 name=name.replace('\\','/');
253 if (name.endsWith("/"))
254 name=name.substring(0,name.length()-1);
255
256 int slash=name.lastIndexOf('/',name.length()-1);
257 if (slash>0)
258 name=name.substring(slash+1);
259 dot=name.lastIndexOf('.');
260 if (dot>0)
261 name=name.substring(0,dot);
262
263 name=name.replace(':','_').replace('*','_').replace('?','_').replace('=','_').replace(',','_').replace(' ','_');
264 }
265 }
266
267 String basis=(name!=null&&name.length()>1)?("type="+type+",name="+name):("type="+type);
268
269 Integer count = (Integer) _unique.get(basis);
270 count = count == null ? 0 : 1 + count;
271 _unique.put(basis, count);
272
273
274 String domain = _domain;
275 if (domain==null)
276 domain = obj.getClass().getPackage().getName();
277
278 oname = ObjectName.getInstance(domain+":"+basis+",id="+count);
279 }
280
281 ObjectInstance oinstance = _server.registerMBean(mbean, oname);
282 Log.debug("Registered {}" , oinstance.getObjectName());
283 _beans.put(obj, oinstance.getObjectName());
284
285 }
286 catch (Exception e)
287 {
288 Log.warn("bean: "+obj,e);
289 }
290 }
291
292
293
294
295
296
297
298 public void doStart()
299 {
300 ShutdownThread.register(this);
301 }
302
303
304
305
306
307
308
309 public void doStop()
310 {
311 Set<Object> removeSet = new HashSet<Object>(_beans.keySet());
312 for (Object removeObj : removeSet)
313 {
314 removeBean(removeObj);
315 }
316 }
317
318
319 public void dump(Appendable out, String indent) throws IOException
320 {
321 out.append(toString()).append("\n");
322 AggregateLifeCycle.dump(out,indent,_beans.entrySet());
323 }
324
325
326 public String dump()
327 {
328 return AggregateLifeCycle.dump(this);
329 }
330 }