KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > mq > server > jmx > DestinationManager


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.mq.server.jmx;
23
24 import java.util.ArrayList JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.Map JavaDoc;
28 import java.util.StringTokenizer JavaDoc;
29
30 import javax.management.Attribute JavaDoc;
31 import javax.management.MBeanServer JavaDoc;
32 import javax.management.MalformedObjectNameException JavaDoc;
33 import javax.management.ObjectName JavaDoc;
34 import javax.transaction.xa.Xid JavaDoc;
35
36 import org.jboss.mq.MessageStatistics;
37 import org.jboss.mq.pm.PersistenceManager;
38 import org.jboss.mq.pm.TxManager;
39 import org.jboss.mq.server.BasicQueueParameters;
40 import org.jboss.mq.server.JMSDestinationManager;
41 import org.jboss.mq.server.JMSServerInterceptor;
42 import org.jboss.mq.server.MessageCache;
43 import org.jboss.mq.server.MessageCounter;
44 import org.jboss.mq.server.Receivers;
45 import org.jboss.mq.sm.StateManager;
46 import org.jboss.mx.util.MBeanProxyExt;
47 import org.jboss.system.ServiceControllerMBean;
48 import org.jboss.system.ServiceMBeanSupport;
49 import org.jboss.util.JBossStringBuilder;
50 import org.jboss.util.threadpool.BasicThreadPool;
51 import org.jboss.util.threadpool.ThreadPool;
52
53 /**
54  * JMX MBean implementation for JBossMQ.
55  *
56  * @jmx:mbean extends="org.jboss.mq.server.jmx.InterceptorMBean"
57  * @author Vincent Sheffer (vsheffer@telkel.com)
58  * @author <a HREF="mailto:jplindfo@helsinki.fi">Juha Lindfors</a>
59  * @author <a HREF="hiram.chirino@jboss.org">Hiram Chirino</a>
60  * @version $Revision: 45317 $
61  */

62 public class DestinationManager extends InterceptorMBeanSupport implements DestinationManagerMBean
63 {
64    public String JavaDoc jndiBindLocation = "java:/JBossMQServer";
65
66    /** A proxy to the service controller. */
67    private ServiceControllerMBean serviceController;
68    /** The JMX ObjectName of this service MBean */
69    private ObjectName JavaDoc mqService;
70    /** The JMS server implementation */
71    protected JMSDestinationManager jmsServer;
72    /** The JMX ObjectName of the configured persistence manager */
73    private ObjectName JavaDoc persistenceManager;
74    /** The JMX ObjectName of the configured state manager */
75    private ObjectName JavaDoc stateManager;
76    /** The JMX ObjectName of the message cache */
77    private ObjectName JavaDoc messageCache;
78    /** The temporary topic/queue parameters */
79    protected BasicQueueParameters tempParameters = new BasicQueueParameters();
80    /** Default thread pool */
81    private ObjectName JavaDoc threadPool;
82    /** Default expiry destination */
83    private ObjectName JavaDoc expiryDestination;
84
85    /**
86     * @jmx:managed-attribute
87     * @return the count of active clients
88     */

89    public int getClientCount()
90    {
91       if (jmsServer == null)
92          return 0;
93       return jmsServer.getClientCount();
94    }
95    /**
96     * @jmx:managed-attribute
97     * @return a Map<ConnectionToken, ClientConsumer> of current clients
98     */

99    public Map JavaDoc getClients()
100    {
101       if (jmsServer == null)
102          return null;
103       return jmsServer.getClients();
104    }
105
106    /**
107     * Get the value of PersistenceManager.
108     *
109     * @jmx:managed-attribute
110     * @return value of PersistenceManager.
111     */

112    public ObjectName JavaDoc getPersistenceManager()
113    {
114       return persistenceManager;
115    }
116
117    /**
118     * Set the value of PersistenceManager.
119     *
120     * @jmx:managed-attribute
121     * @param v Value to assign to PersistenceManager.
122     */

123    public void setPersistenceManager(ObjectName JavaDoc objectName)
124    {
125       this.persistenceManager = objectName;
126    }
127
128    /**
129     * Get the value of StateManager.
130     *
131     * @jmx:managed-attribute
132     * @return value of StateManager.
133     */

134    public ObjectName JavaDoc getStateManager()
135    {
136       return stateManager;
137    }
138
139    /**
140     * Set the value of StateManager.
141     *
142     * @jmx:managed-attribute
143     * @param v Value to assign to StateManager.
144     */

145    public void setStateManager(ObjectName JavaDoc objectName)
146    {
147       this.stateManager = objectName;
148    }
149
150    /**
151     * Get the value of MessageCache.
152     *
153     * @jmx:managed-attribute
154     * @return value of MessageCache.
155     */

156    public ObjectName JavaDoc getMessageCache()
157    {
158       return messageCache;
159    }
160
161    /**
162     * Set the value of MessageCache.
163     *
164     * @jmx:managed-attribute
165     * @param v Value to assign to MessageCache.
166     */

167    public void setMessageCache(ObjectName JavaDoc objectName)
168    {
169       this.messageCache = objectName;
170    }
171
172    /**
173     * Retrieve the temporary topic/queue max depth
174     * @return the maximum depth
175     * @jmx:managed-attribute
176     */

177    public int getTemporaryMaxDepth()
178    {
179       return tempParameters.maxDepth;
180    }
181
182    /**
183     * Set the temporary topic/queue max depth
184     * @param depth the maximum depth
185     * @jmx:managed-attribute
186     */

187    public void setTemporaryMaxDepth(int depth)
188    {
189       tempParameters.maxDepth = depth;
190    }
191
192    /**
193     * Retrieve the temporary topic/queue in memory mode
194     * @return true for in memory
195     * @jmx:managed-attribute
196     */

197    public boolean getTemporaryInMemory()
198    {
199       return tempParameters.inMemory;
200    }
201
202    /**
203     * Set the temporary topic/queue in memory mode
204     * @param mode true for in memory
205     * @jmx:managed-attribute
206     */

207    public void setTemporaryInMemory(boolean mode)
208    {
209       tempParameters.inMemory = mode;
210    }
211
212    /**
213     * Get the receivers implemenetation
214     *
215     * @return the receivers implementation class
216     * @jmx:managed-attribute
217     */

218    public Class JavaDoc getReceiversImpl()
219    {
220       return tempParameters.receiversImpl;
221    }
222
223    /**
224     * Set the receivers implementation class
225     *
226     * @param clazz the receivers implementation class
227     * @jmx:managed-attribute
228     */

229    public void setReceiversImpl(Class JavaDoc clazz)
230    {
231       if (clazz != null && Receivers.class.isAssignableFrom(clazz) == false)
232          throw new IllegalArgumentException JavaDoc("Class " + clazz.getName() + " is not a Receivers implementation");
233       tempParameters.receiversImpl = clazz;
234    }
235    
236    public int getRecoveryRetries()
237    {
238       return tempParameters.recoveryRetries;
239    }
240
241    public void setRecoveryRetries(int retries)
242    {
243       tempParameters.recoveryRetries = retries;
244    }
245    
246    public ObjectName JavaDoc getThreadPool()
247    {
248       return this.threadPool;
249    }
250
251    public void setThreadPool(ObjectName JavaDoc threadPool)
252    {
253       this.threadPool = threadPool;
254    }
255    
256    public ObjectName JavaDoc getExpiryDestination()
257    {
258       return expiryDestination;
259    }
260
261    public void setExpiryDestination(ObjectName JavaDoc expiryDestination)
262    {
263       this.expiryDestination = expiryDestination;
264    }
265
266    /**
267     * @jmx:managed-operation
268     */

269    public void createQueue(String JavaDoc name) throws Exception JavaDoc
270    {
271       createDestination("org.jboss.mq.server.jmx.Queue", getQueueObjectName(name), null);
272    }
273
274    /**
275     * @jmx:managed-operation
276     */

277    public void createTopic(String JavaDoc name) throws Exception JavaDoc
278    {
279       createDestination("org.jboss.mq.server.jmx.Topic", getTopicObjectName(name), null);
280    }
281
282    /**
283     * @jmx:managed-operation
284     */

285    public void createQueue(String JavaDoc name, String JavaDoc jndiLocation) throws Exception JavaDoc
286    {
287       createDestination("org.jboss.mq.server.jmx.Queue", getQueueObjectName(name), jndiLocation);
288    }
289
290    /**
291     * @jmx:managed-operation
292     */

293    public void createTopic(String JavaDoc name, String JavaDoc jndiLocation) throws Exception JavaDoc
294    {
295       createDestination("org.jboss.mq.server.jmx.Topic", getTopicObjectName(name), jndiLocation);
296    }
297
298    // TODO. Should we add any Kind of security configuration for these
299
// dynamicly created destination. For example en optional URL to
300
// an xml config file.
301
protected void createDestination(String JavaDoc type, ObjectName JavaDoc name, String JavaDoc jndiLocation) throws Exception JavaDoc
302    {
303       log.debug("Attempting to create destination: " + name + "; type=" + type);
304
305       server.createMBean(type, name);
306       server.setAttribute(name, new Attribute JavaDoc("DestinationManager", mqService));
307       if (jndiLocation != null)
308          server.setAttribute(name, new Attribute JavaDoc("JNDIName", jndiLocation));
309
310       // This destination should be stopped when we are stopped
311
ArrayList JavaDoc depends = new ArrayList JavaDoc();
312       depends.add(serviceName);
313
314       serviceController.create(name, depends);
315       serviceController.start(name);
316    }
317
318    /**
319     * @jmx:managed-operation
320     */

321    public void destroyQueue(String JavaDoc name) throws Exception JavaDoc
322    {
323       destroyDestination(getQueueObjectName(name));
324    }
325
326    /**
327     * @jmx:managed-operation
328     */

329    public void destroyTopic(String JavaDoc name) throws Exception JavaDoc
330    {
331       destroyDestination(getTopicObjectName(name));
332    }
333
334    protected void destroyDestination(ObjectName JavaDoc name) throws Exception JavaDoc
335    {
336       if (log.isDebugEnabled())
337       {
338          log.debug("Attempting to destroy destination: " + name);
339       }
340
341       serviceController.stop(name);
342
343       server.invoke(name, "removeAllMessages", new Object JavaDoc[] {
344       }, new String JavaDoc[] {
345       });
346       serviceController.destroy(name);
347       serviceController.remove(name);
348    }
349
350    protected ObjectName JavaDoc getObjectName(MBeanServer JavaDoc server, ObjectName JavaDoc name) throws MalformedObjectNameException JavaDoc
351    {
352       // Save our object name to create destination names based on it
353
mqService = name;
354       return mqService;
355    }
356
357    protected ObjectName JavaDoc getTopicObjectName(String JavaDoc name) throws MalformedObjectNameException JavaDoc
358    {
359       return new ObjectName JavaDoc(mqService.getDomain() + ".destination:service=Topic,name=" + name);
360    }
361
362    protected ObjectName JavaDoc getQueueObjectName(String JavaDoc name) throws MalformedObjectNameException JavaDoc
363    {
364       return new ObjectName JavaDoc(mqService.getDomain() + ".destination:service=Queue,name=" + name);
365    }
366
367    protected ServiceControllerMBean getServiceController()
368    {
369       return serviceController;
370    }
371
372    /**
373     * @see InterceptorMBean#getInterceptor()
374     */

375    public JMSServerInterceptor getInterceptor()
376    {
377       return jmsServer;
378    }
379
380    /**
381     * @see ServiceMBeanSupport#createService()
382     */

383    protected void createService() throws Exception JavaDoc
384    {
385       super.createService();
386       jmsServer = new JMSDestinationManager(tempParameters);
387    }
388
389    protected void startService() throws Exception JavaDoc
390    {
391       // Get a proxy to the service controller
392
serviceController =
393          (ServiceControllerMBean) MBeanProxyExt.create(
394             ServiceControllerMBean.class,
395             ServiceControllerMBean.OBJECT_NAME,
396             server);
397
398       PersistenceManager pm = (PersistenceManager) server.getAttribute(persistenceManager, "Instance");
399       jmsServer.setPersistenceManager(pm);
400
401       StateManager sm = (StateManager) server.getAttribute(stateManager, "Instance");
402       jmsServer.setStateManager(sm);
403
404       // We were either told the message cache or we get it from the
405
// persistence manager
406
MessageCache mc;
407       if (messageCache != null)
408          mc = (MessageCache) server.getAttribute(messageCache, "Instance");
409       else
410          mc = pm.getMessageCacheInstance();
411       jmsServer.setMessageCache(mc);
412
413       ThreadPool tp;
414       ThreadGroup JavaDoc tg;
415       if (threadPool == null)
416       {
417          tg = new ThreadGroup JavaDoc("JBossMQ Server Threads");
418          tp = new BasicThreadPool("JMSThread", tg);
419       }
420       else
421       {
422          tp = (ThreadPool) server.getAttribute(threadPool, "Instance");
423          if (tp instanceof BasicThreadPool)
424            tg = ((BasicThreadPool)tp).getThreadGroup();
425          else
426            tg = new ThreadGroup JavaDoc("JBossMQ Server Threads");
427       }
428       jmsServer.setThreadPool(tp);
429       jmsServer.setThreadGroup(tg);
430
431       jmsServer.startServer();
432
433       super.startService();
434    }
435
436    protected void stopService()
437    {
438       jmsServer.stopServer();
439    }
440
441    protected void destroyService() throws Exception JavaDoc
442    {
443       super.destroyService();
444       jmsServer = null;
445    }
446
447    /**
448     * Sets the destination message counter history day limit
449     * <0: unlimited, =0: disabled, > 0 maximum day count
450     *
451     * @param days maximum day count
452     *
453     * @jmx:managed-attribute
454     */

455    public void setMessageCounterHistoryDayLimit( int days )
456    {
457       if( days < -1 )
458           days = -1;
459
460       tempParameters.messageCounterHistoryDayLimit = days;
461
462    }
463
464    /**
465     * Gets the destination message counter history day limit
466     * @return Maximum day count
467     *
468     * @jmx:managed-attribute
469     */

470    public int getMessageCounterHistoryDayLimit()
471    {
472       return tempParameters.messageCounterHistoryDayLimit;
473    }
474
475    /**
476     * get message counter of all configured destinations
477     *
478     * @jmx:managed-operation
479     */

480    public MessageCounter[] getMessageCounter() throws Exception JavaDoc
481    {
482       if (jmsServer == null)
483          return null;
484       return jmsServer.getMessageCounter();
485    }
486
487    /**
488     * get message stats
489     *
490     * @jmx:managed-operation
491     */

492    public MessageStatistics[] getMessageStatistics() throws Exception JavaDoc
493    {
494       if (jmsServer == null)
495          return null;
496       return MessageCounter.getMessageStatistics(jmsServer.getMessageCounter());
497    }
498
499    /**
500     * List message counter of all configured destinations as HTML table
501     *
502     * @jmx:managed-operation
503     */

504    public String JavaDoc listMessageCounter() throws Exception JavaDoc
505    {
506       if (jmsServer == null)
507          return null;
508       MessageCounter[] counter = jmsServer.getMessageCounter();
509
510       String JavaDoc ret =
511          "<table width=\"100%\" border=\"1\" cellpadding=\"1\" cellspacing=\"1\">"
512             + "<tr>"
513             + "<th>Type</th>"
514             + "<th>Name</th>"
515             + "<th>Subscription</th>"
516             + "<th>Durable</th>"
517             + "<th>Count</th>"
518             + "<th>CountDelta</th>"
519             + "<th>Depth</th>"
520             + "<th>DepthDelta</th>"
521             + "<th>Last Add</th>"
522             + "</tr>";
523
524       String JavaDoc strNameLast = null;
525       String JavaDoc strTypeLast = null;
526       String JavaDoc strDestLast = null;
527
528       String JavaDoc destData = "";
529       int destCount = 0;
530
531       int countTotal = 0;
532       int countDeltaTotal = 0;
533       int depthTotal = 0;
534       int depthDeltaTotal = 0;
535
536       int i = 0; // define outside of for statement, so variable
537
// still exists after for loop, because it is
538
// needed during output of last module data string
539

540       for (i = 0; i < counter.length; i++)
541       {
542          // get counter data
543
StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(counter[i].getCounterAsString(), ",");
544
545          String JavaDoc strType = tokens.nextToken();
546          String JavaDoc strName = tokens.nextToken();
547          String JavaDoc strSub = tokens.nextToken();
548          String JavaDoc strDurable = tokens.nextToken();
549
550          String JavaDoc strDest = strType + "-" + strName;
551
552          String JavaDoc strCount = tokens.nextToken();
553          String JavaDoc strCountDelta = tokens.nextToken();
554          String JavaDoc strDepth = tokens.nextToken();
555          String JavaDoc strDepthDelta = tokens.nextToken();
556          String JavaDoc strDate = tokens.nextToken();
557
558          // update total count / depth values
559
countTotal += Integer.parseInt(strCount);
560          depthTotal += Integer.parseInt(strDepth);
561
562          countDeltaTotal += Integer.parseInt(strCountDelta);
563          depthDeltaTotal += Integer.parseInt(strDepthDelta);
564
565          if (strCountDelta.equalsIgnoreCase("0"))
566             strCountDelta = "-"; // looks better
567

568          if (strDepthDelta.equalsIgnoreCase("0"))
569             strDepthDelta = "-"; // looks better
570

571          // output destination counter data as HTML table row
572
// ( for topics with multiple subscriptions output
573
// type + name field as rowspans, looks better )
574
if (strDestLast != null && strDestLast.equals(strDest))
575          {
576             // still same destination -> append destination subscription data
577
destData += "<tr bgcolor=\"#" + ((i % 2) == 0 ? "FFFFFF" : "F0F0F0") + "\">";
578             destCount += 1;
579          }
580          else
581          {
582             // start new destination data
583
if (strDestLast != null)
584             {
585                // store last destination data string
586
ret += "<tr bgcolor=\"#"
587                   + ((i % 2) == 0 ? "FFFFFF" : "F0F0F0")
588                   + "\"><td rowspan=\""
589                   + destCount
590                   + "\">"
591                   + strTypeLast
592                   + "</td><td rowspan=\""
593                   + destCount
594                   + "\">"
595                   + strNameLast
596                   + "</td>"
597                   + destData;
598
599                destData = "";
600             }
601
602             destCount = 1;
603          }
604
605          // counter data row
606
destData += "<td>"
607             + strSub
608             + "</td>"
609             + "<td>"
610             + strDurable
611             + "</td>"
612             + "<td>"
613             + strCount
614             + "</td>"
615             + "<td>"
616             + strCountDelta
617             + "</td>"
618             + "<td>"
619             + strDepth
620             + "</td>"
621             + "<td>"
622             + strDepthDelta
623             + "</td>"
624             + "<td>"
625             + strDate
626             + "</td>";
627
628          // store current destination data for change detection
629
strTypeLast = strType;
630          strNameLast = strName;
631          strDestLast = strDest;
632       }
633
634       if (strDestLast != null)
635       {
636          // store last module data string
637
ret += "<tr bgcolor=\"#"
638             + ((i % 2) == 0 ? "FFFFFF" : "F0F0F0")
639             + "\"><td rowspan=\""
640             + destCount
641             + "\">"
642             + strTypeLast
643             + "</td><td rowspan=\""
644             + destCount
645             + "\">"
646             + strNameLast
647             + "</td>"
648             + destData;
649       }
650
651       // append summation info
652
ret += "<tr>"
653          + "<td><![CDATA[ ]]></td><td><![CDATA[ ]]></td>"
654          + "<td><![CDATA[ ]]></td><td><![CDATA[ ]]></td><td>"
655          + countTotal
656          + "</td><td>"
657          + (countDeltaTotal == 0 ? "-" : Integer.toString(countDeltaTotal))
658          + "</td><td>"
659          + depthTotal
660          + "</td><td>"
661          + (depthDeltaTotal == 0 ? "-" : Integer.toString(depthDeltaTotal))
662          + "</td><td>Total</td></tr></table>";
663
664       return ret;
665    }
666
667    /**
668     * Reset message counter of all configured destinations
669     *
670     * @jmx:managed-operation
671     */

672    public void resetMessageCounter()
673    {
674       if (jmsServer == null)
675          return;
676       jmsServer.resetMessageCounter();
677    }
678
679    public Map JavaDoc retrievePreparedTransactions()
680    {
681       if (jmsServer == null)
682          return null;
683       Map JavaDoc map = jmsServer.getPersistenceManager().getTxManager().getPreparedTransactions();
684       HashMap JavaDoc result = new HashMap JavaDoc();
685       for (Iterator JavaDoc i = map.entrySet().iterator(); i.hasNext();)
686       {
687          Map.Entry JavaDoc entry = (Map.Entry JavaDoc) i.next();
688          Xid JavaDoc xid = (Xid JavaDoc) entry.getKey();
689          TxManager.PreparedInfo info = (TxManager.PreparedInfo) entry.getValue();
690          if (xid != null && info != null)
691             result.put(xid, Boolean.valueOf(info.isInDoubt()));
692       }
693       return result;
694    }
695
696    public String JavaDoc showPreparedTransactions()
697    {
698       if (jmsServer == null)
699          return null;
700       Map JavaDoc map = jmsServer.getPersistenceManager().getTxManager().getPreparedTransactions();
701       JBossStringBuilder buffer = new JBossStringBuilder();
702       buffer.append("<table width=\"100%\" border=\"1\" cellpadding=\"1\" cellspacing=\"1\">");
703       buffer.append("<tr><th>Xid</th><th>In Doubt</th><th>Local TXIDs</th></tr>");
704       for (Iterator JavaDoc i = map.entrySet().iterator(); i.hasNext();)
705       {
706          Map.Entry JavaDoc entry = (Map.Entry JavaDoc) i.next();
707          Xid JavaDoc xid = (Xid JavaDoc) entry.getKey();
708          TxManager.PreparedInfo info = (TxManager.PreparedInfo) entry.getValue();
709          if (xid != null && info != null)
710          {
711             buffer.append("<tr><td>");
712             buffer.append(xid);
713             buffer.append("</td><td>");
714             buffer.append(info.isInDoubt());
715             buffer.append("</td><td>");
716             buffer.append(info.getTxids());
717             buffer.append("</td></tr>");
718          }
719       }
720       buffer.append("</table>");
721       return buffer.toString();
722    }
723 }
724
Popular Tags