KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > cache > interceptors > CacheMgmtInterceptor


1 /*
2  * JBoss, Home of Professional Open Source
3  * Copyright 2005, JBoss Inc., and individual contributors as indicated
4  * by the @authors tag. See the copyright.txt in the distribution for a
5  * full listing of individual contributors.
6  *
7  * This is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * This software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this software; if not, write to the Free
19  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21  */

22 package org.jboss.cache.interceptors;
23
24 import org.jboss.cache.CacheListener;
25 import org.jboss.cache.CacheSPI;
26 import org.jboss.cache.Fqn;
27 import org.jboss.cache.marshall.MethodCall;
28 import org.jboss.cache.marshall.MethodDeclarations;
29 import org.jgroups.View;
30
31 import javax.management.ListenerNotFoundException JavaDoc;
32 import javax.management.MBeanNotificationInfo JavaDoc;
33 import javax.management.Notification JavaDoc;
34 import javax.management.NotificationBroadcaster JavaDoc;
35 import javax.management.NotificationBroadcasterSupport JavaDoc;
36 import javax.management.NotificationFilter JavaDoc;
37 import javax.management.NotificationListener JavaDoc;
38 import java.util.HashMap JavaDoc;
39 import java.util.Map JavaDoc;
40 import java.util.concurrent.atomic.AtomicLong JavaDoc;
41
42 /**
43  * Captures cache management statistics
44  *
45  * @author Jerry Gauthier
46  * @version $Id: CacheMgmtInterceptor.java,v 1.27 2007/01/03 17:50:31 msurtani Exp $
47  */

48 public class CacheMgmtInterceptor extends Interceptor implements CacheMgmtInterceptorMBean, NotificationBroadcaster JavaDoc
49 {
50    // Notification Types
51
public static final String JavaDoc
52            NOTIF_CACHE_STARTED = "org.jboss.cache.CacheStarted",
53            NOTIF_CACHE_STOPPED = "org.jboss.cache.CacheStopped",
54            NOTIF_NODE_CREATED = "org.jboss.cache.NodeCreated",
55            NOTIF_NODE_MODIFIED = "org.jboss.cache.NodeModified",
56            NOTIF_NODE_REMOVED = "org.jboss.cache.NodeRemoved",
57            NOTIF_NODE_MOVED = "org.jboss.cache.NodeMoved",
58            NOTIF_NODE_VISITED = "org.jboss.cache.NodeVisited",
59            NOTIF_NODE_EVICTED = "org.jboss.cache.NodeEvicted",
60            NOTIF_NODE_LOADED = "org.jboss.cache.NodeLoaded",
61            NOTIF_NODE_ACTIVATED = "org.jboss.cache.NodeActivated",
62            NOTIF_NODE_PASSIVATED = "org.jboss.cache.NodePassivated",
63            NOTIF_VIEW_CHANGED = "org.jboss.cache.ViewChanged";
64
65    // Notification Messages
66
private static final String JavaDoc MSG_CACHE_STARTED = "Cache has been started.";
67    private static final String JavaDoc MSG_CACHE_STOPPED = "Cache has been stopped.";
68    private static final String JavaDoc MSG_NODE_CREATED = "Node has been created.";
69    private static final String JavaDoc MSG_NODE_MODIFIED = "Node has been modifed.";
70    private static final String JavaDoc MSG_NODE_REMOVED = "Node has been removed.";
71    private static final String JavaDoc MSG_NODE_MOVED = "Node has been moved.";
72    private static final String JavaDoc MSG_NODE_VISITED = "Node has been visited.";
73    private static final String JavaDoc MSG_NODE_EVICTED = "Node has been evicted.";
74    private static final String JavaDoc MSG_NODE_LOADED = "Node has been loaded.";
75    private static final String JavaDoc MSG_NODE_ACTIVATED = "Node has been activated.";
76    private static final String JavaDoc MSG_NODE_PASSIVATED = "Node has been passivated.";
77    private static final String JavaDoc MSG_VIEW_CHANGED = "Cache cluster view has changed.";
78
79    // Notification Info
80
private static final String JavaDoc NOTIFICATION_NAME = Notification JavaDoc.class.getName();
81    private static final String JavaDoc NOTIFICATION_DESCR = "JBossCache event notifications";
82
83    private AtomicLong JavaDoc m_seq = new AtomicLong JavaDoc(0);
84    private int m_listeners = 0;
85    private long m_hit_times = 0;
86    private long m_miss_times = 0;
87    private long m_store_times = 0;
88    private long m_hits = 0;
89    private long m_misses = 0;
90    private long m_stores = 0;
91    private long m_evictions = 0;
92    private long m_start = System.currentTimeMillis();
93    private long m_reset = m_start;
94    private CacheMgmtListener m_listener = new CacheMgmtListener();
95    private NotificationBroadcasterSupport JavaDoc m_broadcaster = null;
96
97    public void setCache(CacheSPI cache)
98    {
99       super.setCache(cache);
100       m_broadcaster = new NotificationBroadcasterSupport JavaDoc();
101    }
102
103    /**
104     * Pass the method on and capture cache statistics
105     *
106     * @return
107     * @throws Throwable
108     */

109    public Object JavaDoc invoke(MethodCall m) throws Throwable JavaDoc
110    {
111       Map JavaDoc attributes;
112       Object JavaDoc[] args = m.getArgs();
113       Object JavaDoc retval;
114
115       // if statistics not enabled, execute the method and return
116
if (!getStatisticsEnabled())
117          return super.invoke(m);
118
119       long t1, t2;
120       switch (m.getMethodId())
121       {
122          case MethodDeclarations.getKeyValueMethodLocal_id:
123             //fqn = (Fqn) args[0];
124
//key = args[1];
125
t1 = System.currentTimeMillis();
126             retval = super.invoke(m);
127             t2 = System.currentTimeMillis();
128             if (retval == null)
129             {
130                m_miss_times = m_miss_times + (t2 - t1);
131                m_misses++;
132             }
133             else
134             {
135                m_hit_times = m_hit_times + (t2 - t1);
136                m_hits++;
137             }
138             break;
139          case MethodDeclarations.putKeyValMethodLocal_id:
140             t1 = System.currentTimeMillis();
141             retval = super.invoke(m);
142             t2 = System.currentTimeMillis();
143             m_store_times = m_store_times + (t2 - t1);
144             m_stores++;
145             break;
146          case MethodDeclarations.putDataMethodLocal_id:
147          case MethodDeclarations.putDataEraseMethodLocal_id:
148             //fqn = (Fqn) args[1];
149
attributes = (Map JavaDoc) args[2];
150             t1 = System.currentTimeMillis();
151             retval = super.invoke(m);
152             t2 = System.currentTimeMillis();
153
154             if (attributes != null && attributes.size() > 0)
155             {
156                m_store_times = m_store_times + (t2 - t1);
157                m_stores = m_stores + attributes.size();
158             }
159             break;
160          case MethodDeclarations.evictNodeMethodLocal_id:
161          case MethodDeclarations.evictVersionedNodeMethodLocal_id:
162             //fqn = (Fqn) args[0];
163
retval = super.invoke(m);
164             m_evictions++;
165             break;
166          default:
167             retval = super.invoke(m);
168             break;
169       }
170
171       return retval;
172    }
173
174    public long getHits()
175    {
176       return m_hits;
177    }
178
179    public long getMisses()
180    {
181       return m_misses;
182    }
183
184    public long getStores()
185    {
186       return m_stores;
187    }
188
189    public long getEvictions()
190    {
191       return m_evictions;
192    }
193
194    public double getHitMissRatio()
195    {
196       double total = m_hits + m_misses;
197       if (total == 0)
198          return 0;
199       return (m_hits / total);
200    }
201
202    public double getReadWriteRatio()
203    {
204       if (m_stores == 0)
205          return 0;
206       return (((double) (m_hits + m_misses) / (double) m_stores));
207    }
208
209    public long getAverageReadTime()
210    {
211       long total = m_hits + m_misses;
212       if (total == 0)
213          return 0;
214       return (m_hit_times + m_miss_times) / total;
215    }
216
217    public long getAverageWriteTime()
218    {
219       if (m_stores == 0)
220          return 0;
221       return (m_store_times) / m_stores;
222    }
223
224    public int getNumberOfAttributes()
225    {
226       return cache.getNumberOfAttributes();
227    }
228
229    public int getNumberOfNodes()
230    {
231       return cache.getNumberOfNodes();
232    }
233
234    public long getElapsedTime()
235    {
236       return (System.currentTimeMillis() - m_start) / 1000;
237    }
238
239    public long getTimeSinceReset()
240    {
241       return (System.currentTimeMillis() - m_reset) / 1000;
242    }
243
244    public Map JavaDoc<String JavaDoc, Object JavaDoc> dumpStatistics()
245    {
246       Map JavaDoc<String JavaDoc, Object JavaDoc> retval = new HashMap JavaDoc<String JavaDoc, Object JavaDoc>();
247       retval.put("Hits", m_hits);
248       retval.put("Misses", m_misses);
249       retval.put("Stores", m_stores);
250       retval.put("Evictions", m_evictions);
251       retval.put("NumberOfAttributes", cache.getNumberOfAttributes());
252       retval.put("NumberOfNodes", cache.getNumberOfNodes());
253       retval.put("ElapsedTime", getElapsedTime());
254       retval.put("TimeSinceReset", getTimeSinceReset());
255       retval.put("AverageReadTime", getAverageReadTime());
256       retval.put("AverageWriteTime", getAverageWriteTime());
257       retval.put("HitMissRatio", getHitMissRatio());
258       retval.put("ReadWriteRatio", getReadWriteRatio());
259       return retval;
260    }
261
262    public void resetStatistics()
263    {
264       m_hits = 0;
265       m_misses = 0;
266       m_stores = 0;
267       m_evictions = 0;
268       m_hit_times = 0;
269       m_miss_times = 0;
270       m_store_times = 0;
271       m_reset = System.currentTimeMillis();
272    }
273
274    private synchronized void emitNotifications(boolean emit)
275    {
276       // This method adds and removes the CacheImpl listener.
277
// The m_listeners counter is used to determine whether
278
// we have any clients who are registered for notifications
279
// from this mbean. When the count is zero, we don't need to
280
// listen to cache events. Note that a client who terminates
281
// without unregistering for notifications will leave the count
282
// greater than zero so we'll still listen in that case.
283
if (emit)
284       {
285          m_listeners++;
286          cache.addCacheListener(m_listener);
287       }
288       else
289       {
290          m_listeners--;
291          if (m_listeners <= 0)
292          {
293             cache.removeCacheListener(m_listener);
294          }
295       }
296    }
297
298    // NotificationBroadcaster interface
299

300    public void removeNotificationListener(NotificationListener JavaDoc listener, NotificationFilter JavaDoc filter, Object JavaDoc handback)
301            throws ListenerNotFoundException JavaDoc
302    {
303       m_broadcaster.removeNotificationListener(listener, filter, handback);
304    }
305
306    public MBeanNotificationInfo JavaDoc[] getNotificationInfo()
307    {
308       String JavaDoc[] types = new String JavaDoc[]
309               {
310                       NOTIF_CACHE_STARTED,
311                       NOTIF_CACHE_STOPPED,
312                       NOTIF_NODE_CREATED,
313                       NOTIF_NODE_EVICTED,
314                       NOTIF_NODE_LOADED,
315                       NOTIF_NODE_MODIFIED,
316                       NOTIF_NODE_ACTIVATED,
317                       NOTIF_NODE_PASSIVATED,
318                       NOTIF_NODE_REMOVED,
319                       NOTIF_NODE_VISITED,
320                       NOTIF_VIEW_CHANGED
321               };
322
323       MBeanNotificationInfo JavaDoc info = new MBeanNotificationInfo JavaDoc(types, NOTIFICATION_NAME, NOTIFICATION_DESCR);
324       return new MBeanNotificationInfo JavaDoc[]{info};
325    }
326
327    public void addNotificationListener(NotificationListener JavaDoc listener, NotificationFilter JavaDoc filter, Object JavaDoc handback)
328            throws IllegalArgumentException JavaDoc
329    {
330       m_broadcaster.addNotificationListener(listener, filter, handback);
331       emitNotifications(true);
332    }
333
334    public void removeNotificationListener(NotificationListener JavaDoc listener)
335            throws ListenerNotFoundException JavaDoc
336    {
337       m_broadcaster.removeNotificationListener(listener);
338       emitNotifications(false);
339    }
340
341    // Handler for CacheImpl events
342
private class CacheMgmtListener implements CacheListener
343    {
344       private long seq()
345       {
346          return m_seq.getAndIncrement();
347       }
348
349       public void cacheStarted(CacheSPI cache)
350       {
351          Notification JavaDoc n = new Notification JavaDoc(NOTIF_CACHE_STARTED, this, seq(), MSG_CACHE_STARTED);
352          n.setUserData(cache.getConfiguration().getServiceName());
353          m_broadcaster.sendNotification(n);
354       }
355
356       public void cacheStopped(CacheSPI cache)
357       {
358          Notification JavaDoc n = new Notification JavaDoc(NOTIF_CACHE_STOPPED, this, seq(), MSG_CACHE_STOPPED);
359          n.setUserData(cache.getConfiguration().getServiceName());
360          m_broadcaster.sendNotification(n);
361       }
362
363       public void nodeCreated(Fqn fqn, boolean pre, boolean isLocal)
364       {
365          Notification JavaDoc n = new Notification JavaDoc(NOTIF_NODE_CREATED, this, seq(), MSG_NODE_CREATED);
366          n.setUserData(new Object JavaDoc[]{fqn.toString(), pre, isLocal});
367          m_broadcaster.sendNotification(n);
368       }
369
370       public void nodeEvicted(Fqn fqn, boolean pre, boolean isLocal)
371       {
372          Notification JavaDoc n = new Notification JavaDoc(NOTIF_NODE_EVICTED, this, seq(), MSG_NODE_EVICTED);
373          n.setUserData(new Object JavaDoc[]{fqn.toString(), pre, isLocal});
374          m_broadcaster.sendNotification(n);
375       }
376
377       public void nodeLoaded(Fqn fqn, boolean pre, Map JavaDoc data)
378       {
379          Notification JavaDoc n = new Notification JavaDoc(NOTIF_NODE_LOADED, this, seq(), MSG_NODE_LOADED);
380          n.setUserData(new Object JavaDoc[]{fqn.toString(), pre});
381          m_broadcaster.sendNotification(n);
382       }
383
384       public void nodeModified(Fqn fqn, boolean pre, boolean isLocal, ModificationType modType, Map JavaDoc data)
385       {
386          Notification JavaDoc n = new Notification JavaDoc(NOTIF_NODE_MODIFIED, this, seq(), MSG_NODE_MODIFIED);
387          n.setUserData(new Object JavaDoc[]{fqn.toString(), pre, isLocal});
388          m_broadcaster.sendNotification(n);
389
390       }
391
392       public void nodeRemoved(Fqn fqn, boolean pre, boolean isLocal, Map JavaDoc data)
393       {
394          Notification JavaDoc n = new Notification JavaDoc(NOTIF_NODE_REMOVED, this, seq(), MSG_NODE_REMOVED);
395          n.setUserData(new Object JavaDoc[]{fqn.toString(), pre, isLocal});
396          m_broadcaster.sendNotification(n);
397       }
398
399       public void nodeMoved(Fqn from, Fqn to, boolean pre, boolean isLocal)
400       {
401          Notification JavaDoc n = new Notification JavaDoc(NOTIF_NODE_MOVED, this, seq(), MSG_NODE_MOVED);
402          n.setUserData(new Object JavaDoc[]{from.toString(), to.toString(), pre});
403          m_broadcaster.sendNotification(n);
404       }
405
406       public void nodeVisited(Fqn fqn, boolean pre)
407       {
408          Notification JavaDoc n = new Notification JavaDoc(NOTIF_NODE_VISITED, this, seq(), MSG_NODE_VISITED);
409          n.setUserData(new Object JavaDoc[]{fqn.toString(), pre});
410          m_broadcaster.sendNotification(n);
411       }
412
413       public void viewChange(View view)
414       {
415          Notification JavaDoc n = new Notification JavaDoc(NOTIF_VIEW_CHANGED, this, seq(), MSG_VIEW_CHANGED);
416          n.setUserData(view.toString());
417          m_broadcaster.sendNotification(n);
418       }
419
420       public void nodeActivated(Fqn fqn, boolean pre)
421       {
422          Notification JavaDoc n = new Notification JavaDoc(NOTIF_NODE_ACTIVATED, this, seq(), MSG_NODE_ACTIVATED);
423          n.setUserData(new Object JavaDoc[]{fqn.toString(), pre});
424          m_broadcaster.sendNotification(n);
425       }
426
427       public void nodePassivated(Fqn fqn, boolean pre)
428       {
429          Notification JavaDoc n = new Notification JavaDoc(NOTIF_NODE_PASSIVATED, this, seq(), MSG_NODE_PASSIVATED);
430          n.setUserData(new Object JavaDoc[]{fqn.toString(), pre});
431          m_broadcaster.sendNotification(n);
432       }
433    }
434 }
435
436
Popular Tags