KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > fractal > jmx > agent > Agent


1 /***
2  * Fractal JMX
3  * Copyright (C) 2003 France Telecom R&D
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Contact: fractal@objectweb.org
20  */

21 package org.objectweb.fractal.jmx.agent;
22
23 import org.objectweb.fractal.api.Component;
24 import org.objectweb.fractal.api.NoSuchInterfaceException;
25 import org.objectweb.fractal.api.type.ComponentType;
26 import org.objectweb.fractal.api.type.InterfaceType;
27 import org.objectweb.fractal.api.control.ContentController;
28 import org.objectweb.fractal.api.control.LifeCycleController;
29 import org.objectweb.fractal.api.control.BindingController;
30 import org.objectweb.fractal.api.control.SuperController;
31 import org.objectweb.fractal.api.control.NameController;
32 import org.objectweb.fractal.util.Fractal;
33
34 import javax.management.ObjectName JavaDoc;
35 import javax.management.MBeanServer JavaDoc;
36 import javax.management.MBeanServerFactory JavaDoc;
37 import javax.management.NotificationListener JavaDoc;
38 import javax.management.NotificationFilter JavaDoc;
39 import javax.management.Notification JavaDoc;
40 import javax.management.JMException JavaDoc;
41 import javax.management.AttributeNotFoundException JavaDoc;
42 import javax.management.JMRuntimeException JavaDoc;
43 import javax.management.modelmbean.ModelMBean JavaDoc;
44 import javax.management.modelmbean.InvalidTargetObjectTypeException JavaDoc;
45 import javax.management.monitor.MonitorNotification JavaDoc;
46
47 import java.util.*;
48
49 /**
50  * A component representing the JMX agent level.
51  * This component encapsulates a JMX {@link javax.management.MBeanServer MBeanServer} and
52  * allows MBean manipulation by implementing the {@link Admin} interface for registering MBeans,
53  * and the {@link AdminAttributes} interface for filtering MBeans.
54  * Where the MBeans represent component server interfaces or JMX
55  * {@link javax.management.monitor.MonitorMBean monitors} for observing component attributes.
56  *
57  * <p>The binding controller part of this component sets the [required] listener component
58  * that handles JMX notifications sent out by the {@link javax.management.monitor.MonitorMBean monitors}.
59  * The life-cycle controller part bootstraps this component by registering two MBeans representing
60  * its {@link Admin} and {@link AdminAttributes} interfaces.
61  * These two interfaces are identified respectively in the agent by the {@link ObjectName}:
62  * <pre>
63  * Agent:itf=admin
64  * Agent:itf=attribute-controller
65  * </pre>
66  *
67  * <p>The naming convention used for the MBeans representing component server interfaces is defined in {@link Admin}.
68  * The {@link javax.management.monitor.MonitorMBean monitors} are identified by the {@link ObjectName}:
69  * <pre>
70  * AgentService:type=<i>monitorType</i>,monitor=<i>index</i>[,attributeType=<i>attType</i>]
71  * </pre>
72  * where:
73  * <UL>
74  * <LI><I>monitorType</I>: is the type of the JMX monitor (counter, gauge or string).
75  * <LI><I>index</I>: represents the position at which the monitor is specified, for a given filter of the
76  * {@link AdminAttributes} interface.
77  * <LI><I>attType</I>: is the type of the attribute being observed (for counter and gauge
78  * monitors only, since they handle several integer or floating-point attribute types).
79  * </UL>
80  *
81  * @version 0.1
82  */

83 public class Agent implements BindingController, LifeCycleController, AdminAttributes, Admin {
84     private MBeanServer JavaDoc _server = MBeanServerFactory.newMBeanServer("Fractal");
85     private int _depth = -1;
86     private String JavaDoc _itfPatterns = "*:*";
87     private String JavaDoc _stringMonitors = "";
88     private String JavaDoc _counterMonitors = "";
89     private String JavaDoc _gaugeMonitors = "";
90     private String JavaDoc _periodicMonitors = "";
91     private Component _myId = null;
92     private NotificationListener JavaDoc _listener = null;
93     private AgentContext _ctx = new AgentContext();
94
95     // -------------------------------------------------------------------------
96
// implements Binding controller
97
// -------------------------------------------------------------------------
98
public String JavaDoc[] listFc() {
99         return new String JavaDoc[] { "listener" };
100     }
101
102     public Object JavaDoc lookupFc(final String JavaDoc itfName) {
103         if (itfName.equals("listener")) {
104             return _listener;
105         } else
106             return null;
107     }
108
109     public void bindFc(final String JavaDoc itfName, final Object JavaDoc itfValue) {
110         if (itfName.equals("component")) {
111             _myId = (Component) itfValue;
112         } else if (itfName.equals("listener")) {
113             _listener = (NotificationListener JavaDoc) itfValue;
114         }
115     }
116
117     public void unbindFc(final String JavaDoc itfName) {
118         if (itfName.equals("listener")) {
119             _listener = null;
120         }
121     }
122
123     // -------------------------------------------------------------------------
124
// implements LifeCycle controller
125
// -------------------------------------------------------------------------
126
public String JavaDoc getFcState() {
127         return null;
128     }
129
130     public void startFc() {
131         try {
132             ObjectName JavaDoc oName = new ObjectName JavaDoc(CONST.ADMIN + ":itf=admin");
133             exposeFcItf(_myId, oName, "admin");
134             oName = new ObjectName JavaDoc(CONST.ADMIN + ":itf=attribute-controller");
135             exposeFcItf(_myId, oName, "attribute-controller");
136         } catch (JMException JavaDoc e) {
137             throw new JMRuntimeException JavaDoc(e.toString());
138         }
139     }
140
141     public void stopFc() {}
142
143     // -------------------------------------------------------------------------
144
// implements Attribute controller
145
// -------------------------------------------------------------------------
146
/*public int getDepth() {
147         return _depth;
148     }
149     
150     public void setDepth(final int depth) {
151         this._depth = depth;
152     }*/

153
154     public String JavaDoc getItfPatterns() {
155         return _itfPatterns;
156     }
157
158     public void setItfPatterns(final String JavaDoc str) {
159         this._itfPatterns = (str == null) ? "" : str;
160     }
161
162     public String JavaDoc getMonitorStringPatterns() {
163         return _stringMonitors;
164     }
165
166     public void setMonitorStringPatterns(final String JavaDoc str) {
167         this._stringMonitors = (str == null) ? "" : str;
168     }
169
170     public String JavaDoc getMonitorCounterPatterns() {
171         return _counterMonitors;
172     }
173
174     public void setMonitorCounterPatterns(final String JavaDoc counters) {
175         this._counterMonitors = (counters == null) ? "" : counters;
176     }
177
178     public String JavaDoc getMonitorGaugePatterns() {
179         return _gaugeMonitors;
180     }
181
182     public void setMonitorGaugePatterns(final String JavaDoc gauges) {
183         this._gaugeMonitors = (gauges == null) ? "" : gauges;
184     }
185
186     public String JavaDoc getMonitorPeriodicPatterns() {
187         return _periodicMonitors;
188     }
189
190     public void setMonitorPeriodicPatterns(final String JavaDoc periodic) {
191         this._periodicMonitors = (periodic == null) ? "" : periodic;
192     }
193
194     public MBeanServer JavaDoc getRawMBeanServer() {
195         return _server;
196     }
197
198     public void setRawMBeanServer(final MBeanServer JavaDoc srv) {
199         throw new UnsupportedOperationException JavaDoc();
200     }
201
202     // -------------------------------------------------------------------------
203
// implements Admin
204
// -------------------------------------------------------------------------
205
/*public MBeanServer rawAdmin() {
206         return server;
207     }*/

208
209     public void expose() throws JMException JavaDoc {
210         try {
211             // clean
212
unregisterMBean(CONST.FC + "*:*");
213             unregisterMBean(CONST.MONITOR + "*:*");
214             // reset agent context
215
_ctx.reset(_itfPatterns, _stringMonitors, _counterMonitors, _gaugeMonitors, _periodicMonitors);
216             // expose components
217
Component ids[] = (Component[]) exposeSuper(_myId, new HashSet()).toArray(new Component[0]);
218             exposeSub(ids, 0);
219             // starts monitors
220
startMonitors(_ctx.getMonitors());
221         } catch (RuntimeException JavaDoc e) {
222             //e.printStackTrace();
223
throw new JMException JavaDoc(e.toString());
224         }
225     }
226
227     // -------------------------------------------------------------------------
228
// expose methods
229
// -------------------------------------------------------------------------
230
private Set exposeSuper(Component id, Set set) {
231         try {
232             SuperController supCtrl = Fractal.getSuperController(id);
233             Component ids[] = supCtrl.getFcSuperComponents();
234             if (ids.length == 0){
235                 set.add(id);
236             }
237             else for (int j = 0; j < ids.length; j++) {
238                 try{
239                     ids[j].getFcInterface("admin");
240                     exposeSuper(ids[j], set);
241                 } catch (NoSuchInterfaceException e) { set.add(ids[j]);}
242             }
243         } catch (NoSuchInterfaceException e) { set.add(id);}
244         return set;
245     }
246
247     private void exposeSub(Component ids[], int crtDepth) throws JMException JavaDoc {
248         if (_depth >= 0 && crtDepth > _depth)
249             return;
250         for (int i = 0; i < ids.length; i++) {
251             // register subcomponents
252
try {
253                 ContentController cCtrl = Fractal.getContentController(ids[i]);
254                 exposeSub(cCtrl.getFcSubComponents(), crtDepth + 1);
255             } catch (NoSuchInterfaceException ignored) {}
256             // register component infos
257
String JavaDoc[] names = getFullFCName(ids[i]);
258             for (int j = 0; j < names.length; j++) {
259                 exposeFCinfos(ids[i], "/" + names[j] + '@' + Integer.toHexString(ids[i].hashCode()));
260             }
261         }
262     }
263
264     private void exposeFCinfos(Component id, String JavaDoc name) throws JMException JavaDoc {
265         InterfaceType[] itfts = ((ComponentType) id.getFcType()).getFcInterfaceTypes();
266         String JavaDoc domain = CONST.FC + name + (isShared(id) ? "-shared" : "");
267         for (int j = 0; j < itfts.length; j++) {
268             ObjectName JavaDoc oName = new ObjectName JavaDoc(domain + ":itf=" + itfts[j].getFcItfName());
269             if (!itfts[j].isFcClientItf() && (_ctx.matchItfPatterns(oName) || _ctx.matchMonitorPatterns(oName))) {
270                 exposeFcItf(id, oName, itfts[j].getFcItfName());
271                 boolean ret = setObservers(oName, _ctx.getMonitors());
272                 if (!(_ctx.matchItfPatterns(oName) || ret))
273                     _server.unregisterMBean(oName);
274             }
275         }
276     }
277
278     private boolean exposeFcItf(Component cid, ObjectName JavaDoc oname, String JavaDoc itfName) throws JMException JavaDoc {
279         boolean ret = false;
280         try {
281             if (_server.isRegistered(oname))
282                 return true;
283             // itf signature
284
InterfaceType itfType = ((ComponentType) cid.getFcType()).getFcInterfaceType(itfName);
285             String JavaDoc signature = itfType.getFcItfSignature();
286             // introspect & register
287
ModelMBean JavaDoc rmBean = Introspector.createMBean(cid.getFcInterface(itfName), Class.forName(signature));
288             _server.registerMBean(rmBean, oname);
289             ret = true;
290         } catch (NoSuchInterfaceException ignored) {} catch (InvalidTargetObjectTypeException JavaDoc e) {
291             throw new IllegalStateException JavaDoc(e.toString());
292         } catch (ClassNotFoundException JavaDoc e) {
293             throw new IllegalStateException JavaDoc(e.toString());
294         }
295         return ret;
296     }
297
298     private boolean setObservers(ObjectName JavaDoc oName, AgentMonitorMBean[] monitors) throws JMException JavaDoc {
299         boolean ret = false;
300         for (int i = 0; i < monitors.length; i++) {
301             try {
302                 Class JavaDoc c = _server.getAttribute(oName, monitors[i].getObservedAttribute()).getClass();
303                 //if (monitors[i].getPattern().apply(oName) && c.equals(monitors[i].getAttributeType())) {
304
if (monitors[i].getPattern().apply(oName) && monitors[i].getAttributeType().isAssignableFrom(c)) {
305                     monitors[i].addObservedObject(oName);
306                     ret = true;
307                 }
308             } catch (AttributeNotFoundException JavaDoc ignored) {}
309         }
310         return ret;
311     }
312
313     private void startMonitors(AgentMonitorMBean[] monitors) throws JMException JavaDoc {
314         if (_listener == null)
315             return;
316         for (int i = 0; i < monitors.length; i++) {
317             ObjectName JavaDoc[] oNames = monitors[i].getObservedObjects();
318             if (oNames.length == 0)
319                 continue;
320             ObjectName JavaDoc monitorName = _server.registerMBean(monitors[i], null).getObjectName();
321             for (int j = 0; j < oNames.length; j++)
322                 _server.addNotificationListener(monitorName, _listener, new Filter JavaDoc(oNames[j]), oNames[j]);
323             monitors[i].start();
324         }
325     }
326
327     class Filter implements NotificationFilter JavaDoc {
328         ObjectName JavaDoc observedObject;
329         Filter(ObjectName JavaDoc observedObject) {
330             this.observedObject = observedObject;
331         }
332
333         public boolean isNotificationEnabled(Notification JavaDoc n) {
334             MonitorNotification JavaDoc notif = (MonitorNotification JavaDoc) n;
335             if (observedObject.equals(notif.getObservedObject()))
336                 return true;
337             return false;
338         }
339     }
340
341     // -------------------------------------------------------------------------
342
// JMX utils
343
// -------------------------------------------------------------------------
344
private void unregisterMBean(String JavaDoc pattern) throws JMException JavaDoc {
345         ObjectName JavaDoc o = new ObjectName JavaDoc(pattern);
346         Set s = _server.queryNames(o, null);
347         for (Iterator i = s.iterator(); i.hasNext();)
348             _server.unregisterMBean((ObjectName JavaDoc) i.next());
349     }
350
351     // -------------------------------------------------------------------------
352
// Fractal utils
353
// -------------------------------------------------------------------------
354
private boolean isShared(Component id) {
355         boolean shared = false;
356         try {
357             Component ids[] = Fractal.getSuperController(id).getFcSuperComponents();
358             if (ids.length > 1)
359                 shared = true;
360             else if (ids.length > 1)
361                 shared = isShared(ids[0]);
362         } catch (NoSuchInterfaceException ignored) {}
363         return shared;
364     }
365
366     private String JavaDoc[] getFullFCName(Component id) {
367         String JavaDoc[] names = null;
368         try {
369             Component ids[] = Fractal.getSuperController(id).getFcSuperComponents();
370             List l = new ArrayList();
371             for (int i = 0; i < ids.length; i++) {
372                 String JavaDoc[] tmp = getFullFCName(ids[i]);
373                 for (int j = 0; j < tmp.length; j++)
374                     tmp[j] += "/" + getFCName(id);
375                 l.addAll(Arrays.asList(tmp));
376             }
377             names = (String JavaDoc[]) l.toArray(new String JavaDoc[l.size()]);
378         } catch (NoSuchInterfaceException ignored) {}
379         if (names == null || names.length == 0) {
380             names = new String JavaDoc[1];
381             names[0] = getFCName(id);
382         }
383         return names;
384     }
385
386     private String JavaDoc getFCName(Component id) {
387         try {
388             NameController nc = Fractal.getNameController(id);
389             return nc.getFcName();
390         } catch (NoSuchInterfaceException e) {
391             throw new IllegalStateException JavaDoc("NameController required");
392         }
393     }
394 }
395
Popular Tags