KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > cache > multiplexer > MultiplexerTestHelper


1 /*
2  * JBoss, Home of Professional Open Source.
3  * Copyright 2006, Red Hat Middleware LLC, and individual contributors
4  * as indicated by the @author tags. See the copyright.txt file in the
5  * distribution for a 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.multiplexer;
23
24 import java.util.Collections JavaDoc;
25 import java.util.HashSet JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.Set JavaDoc;
28 import java.util.StringTokenizer JavaDoc;
29
30 import javax.management.MBeanServer JavaDoc;
31 import javax.management.MBeanServerFactory JavaDoc;
32 import javax.management.ObjectName JavaDoc;
33 import javax.xml.parsers.DocumentBuilder JavaDoc;
34 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
35
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38 import org.jboss.cache.Cache;
39 import org.jgroups.JChannel;
40 import org.jgroups.JChannelFactory;
41 import org.jgroups.jmx.JChannelFactoryMBean;
42 import org.w3c.dom.Document JavaDoc;
43 import org.w3c.dom.Element JavaDoc;
44
45 /**
46  * Utility class that can associate a cache with a JMX server and a
47  * a JGroups JChannelFactory.
48  *
49  * @author <a HREF="brian.stansberry@jboss.com">Brian Stansberry</a>
50  * @version $Revision: 1.2 $
51  */

52 public class MultiplexerTestHelper
53 {
54    private static final Log log = LogFactory.getLog(MultiplexerTestHelper.class);
55    
56    public static final String JavaDoc MUX_STACK = "jbc-test";
57    private static final String JavaDoc FACTORY_OBJECT_NAME_BASE = "jboss.cache:service=MuxChannelFactory,count=";
58    
59    private MBeanServer JavaDoc mbeanServer;
60    private final Set JavaDoc factories = Collections.synchronizedSet(new HashSet JavaDoc());
61    private final Set JavaDoc caches = Collections.synchronizedSet(new HashSet JavaDoc());
62
63    
64    public MultiplexerTestHelper()
65    {
66       mbeanServer =
67          MBeanServerFactory.createMBeanServer();
68    }
69    
70    /**
71     * Configures the given cache to get its JChannel from a
72     * multiplexer-enabled JChannelFactory. The JChannelFactory will
73     * produce MuxChannels configured with the same protocol stack as
74     * whatever the provided cache is configured with.
75     *
76     * @param cache
77     * @throws Exception
78     */

79    public void configureCacheForMux(Cache cache) throws Exception JavaDoc
80    {
81       synchronized (caches)
82       {
83          ObjectName JavaDoc on = createMuxChannelFactory(cache);
84          cache.getConfiguration().setMultiplexerService(on.getCanonicalName());
85          cache.getConfiguration().setMultiplexerStack(MUX_STACK);
86          cache.getConfiguration().getRuntimeConfig().setMbeanServer(mbeanServer);
87 // ObjectName cacheON = new ObjectName("jboss.cache:service=TestCache,count=" + caches.size());
88
// mbeanServer.registerMBean(cache, cacheON);
89
// caches.add(cacheON);
90
}
91    }
92    
93    /**
94     * Configures the given cache to get its JChannel from a
95     * multiplexer-enabled JChannelFactory. The JChannelFactory will
96     * produce MuxChannels configured with the same protocol stack as
97     * whatever the provided cache is configured with.
98     *
99     * @param cache
100     * @throws Exception
101     */

102    public void configureCacheForMuxViaDirectInjection(Cache cache) throws Exception JavaDoc
103    {
104       synchronized (caches)
105       {
106          String JavaDoc props = getChannelProperties(cache);
107          
108          JChannelFactoryMBean mbean = (JChannelFactoryMBean) createMuxChannelFactory(props, false);
109          cache.getConfiguration().getRuntimeConfig().setMuxChannelFactory(mbean);
110          cache.getConfiguration().setMultiplexerStack(MUX_STACK);
111       }
112    }
113    
114    /**
115     * Creates a JChannelFactory and binds it to this object's
116     * internal MBeanServer. The JChannelFactory will
117     * produce MuxChannels configured with the same protocol stack as
118     * whatever the provided cache is configured with.
119     *
120     * @param cache the cache from which the protocol stack config should
121     * be obtained
122     *
123     * @return the ObjectName of the channel factory.
124     * @throws Exception
125     */

126    public ObjectName JavaDoc createMuxChannelFactory(Cache cache) throws Exception JavaDoc
127    {
128       return createMuxChannelFactory(getChannelProperties(cache));
129    }
130    
131    private String JavaDoc getChannelProperties(Cache cache)
132    {
133       String JavaDoc props = cache.getConfiguration().getClusterConfig();
134       return (props == null ? JChannel.DEFAULT_PROTOCOL_STACK : props);
135    }
136    
137    /**
138     * Creates a JChannelFactory and binds it to this object's
139     * internal MBeanServer. The JChannelFactory will
140     * produce MuxChannels configured with according to the given
141     * protocol stack(s).
142     *
143     * @param muxConfig Element that looks like the root element
144     * of a multiplexer stacks.xml file.
145     *
146     * @return the ObjectName of the channel factory.
147     * @throws Exception
148     */

149    public ObjectName JavaDoc createMuxChannelFactory(String JavaDoc muxConfig) throws Exception JavaDoc
150    {
151       return (ObjectName JavaDoc) createMuxChannelFactory(muxConfig, true);
152    }
153    
154    private Object JavaDoc createMuxChannelFactory(String JavaDoc muxConfig, boolean returnObjectName)
155          throws Exception JavaDoc
156    {
157       synchronized (factories)
158       {
159          JChannelFactory factory = new JChannelFactory();
160          factory.setDomain("jbc.mux.test");
161          factory.setExposeChannels(false);
162          factory.setMultiplexerConfig(getClusterConfigElement(muxConfig));
163             
164          JChannelFactoryMBean muxFactory = new org.jgroups.jmx.JChannelFactory(factory);
165          // Give the factory a unique ObjectName
166
ObjectName JavaDoc on = new ObjectName JavaDoc(FACTORY_OBJECT_NAME_BASE + factories.size());
167          mbeanServer.registerMBean(muxFactory, on);
168          
169          factories.add(on);
170          
171          muxFactory.create();
172          muxFactory.start();
173          
174          return returnObjectName ? on : muxFactory;
175       }
176    }
177    
178    /**
179     * Converts an old-style JGroups protocol stack config string to an Element
180     * that looks like the root element of a multiplexer stacks.xml file.
181     *
182     * @param clusterConfig
183     * @return
184     * @throws Exception
185     */

186    public static Element JavaDoc getClusterConfigElement(String JavaDoc clusterConfig) throws Exception JavaDoc
187    {
188       clusterConfig = clusterConfig.trim();
189       DocumentBuilder JavaDoc db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
190       Document JavaDoc doc = db.newDocument();
191       Element JavaDoc top = doc.createElement("protocol_stacks");
192       doc.appendChild(top);
193       Element JavaDoc stack = doc.createElement("stack");
194       stack.setAttribute("name", MUX_STACK);
195       top.appendChild(stack);
196       Element JavaDoc config = doc.createElement("config");
197       
198       StringTokenizer JavaDoc outer = new StringTokenizer JavaDoc(clusterConfig, ":");
199       while (outer.hasMoreTokens())
200       {
201          String JavaDoc protocol = outer.nextToken();
202          String JavaDoc protName = protocol;
203          String JavaDoc attribs = null;
204          int nameEnd = protocol.indexOf('(');
205          if (nameEnd > 0)
206          {
207             protName = protocol.substring(0, nameEnd);
208             attribs = protocol.substring(nameEnd + 1, protocol.length() -1);
209          }
210          Element JavaDoc element = doc.createElement(protName);
211          if (attribs != null && attribs.length() > 0)
212          {
213             StringTokenizer JavaDoc inner = new StringTokenizer JavaDoc(attribs, ";");
214             while (inner.hasMoreTokens())
215             {
216                String JavaDoc attrib = inner.nextToken();
217                int eq = attrib.indexOf('=');
218                String JavaDoc name = attrib.substring(0, eq);
219                String JavaDoc value = attrib.substring(eq +1);
220                element.setAttribute(name, value);
221             }
222          }
223          config.appendChild(element);
224       }
225
226       stack.appendChild(config);
227       return top;
228    }
229
230    /**
231     * Performs cleanup work, most importantly unregistering the
232     * internal MBeanServer. Once this method is invoked, this
233     * object should no longer be used.
234     */

235    public void tearDown()
236    {
237       try
238       {
239          for (Iterator JavaDoc it = caches.iterator(); it.hasNext(); )
240          {
241             try
242             {
243                mbeanServer.unregisterMBean((ObjectName JavaDoc) it.next());
244             }
245             catch (Exception JavaDoc e)
246             {
247                log.error(e);
248             }
249          }
250          
251          for (Iterator JavaDoc it = factories.iterator(); it.hasNext(); )
252          {
253             try
254             {
255                mbeanServer.unregisterMBean((ObjectName JavaDoc) it.next());
256             }
257             catch (Exception JavaDoc e)
258             {
259                log.error(e);
260             }
261          }
262       }
263       catch (Exception JavaDoc e)
264       {
265          log.error(e);
266       }
267       finally
268       {
269          factories.clear();
270          caches.clear();
271          
272          if (mbeanServer != null)
273          {
274             MBeanServerFactory.releaseMBeanServer(mbeanServer);
275             mbeanServer = null;
276          }
277          
278          
279       }
280    }
281    
282    /**
283     * Makes sure the internal MBeanServer is unregistered.
284     */

285    protected void finalize() throws Throwable JavaDoc
286    {
287       if (mbeanServer != null)
288       {
289          MBeanServerFactory.releaseMBeanServer(mbeanServer);
290       }
291       super.finalize();
292    }
293
294    /**
295     * Tests creation of a channel factory.
296     *
297     * @param args
298     */

299    public static void main(String JavaDoc[] args)
300    {
301       MultiplexerTestHelper helper = new MultiplexerTestHelper();
302       try
303       {
304          helper.createMuxChannelFactory(JChannel.DEFAULT_PROTOCOL_STACK);
305       }
306       catch (Exception JavaDoc e)
307       {
308          e.printStackTrace();
309       }
310       finally
311       {
312          helper.tearDown();
313       }
314    }
315 }
316
Popular Tags