KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jk > common > ModJkMX


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.jk.common;
18
19 import java.io.IOException JavaDoc;
20 import java.io.BufferedReader JavaDoc;
21 import java.io.InputStreamReader JavaDoc;
22 import java.net.URLConnection JavaDoc;
23 import java.net.URL JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import javax.management.MBeanServer JavaDoc;
29 import javax.management.AttributeNotFoundException JavaDoc;
30 import javax.management.MBeanException JavaDoc;
31 import javax.management.ReflectionException JavaDoc;
32 import javax.management.Attribute JavaDoc;
33 import javax.management.ObjectName JavaDoc;
34
35 import org.apache.jk.core.JkHandler;
36 import org.apache.commons.modeler.Registry;
37 import org.apache.commons.modeler.BaseModelMBean;
38 import org.apache.commons.modeler.ManagedBean;
39 import org.apache.commons.modeler.AttributeInfo;
40 import org.apache.commons.modeler.OperationInfo;
41 import org.apache.commons.logging.Log;
42 import org.apache.commons.logging.LogFactory;
43
44 /**
45  * A small mbean that will act as a proxy for mod_jk2.
46  *
47  * For efficiency, it'll get bulk results and cache them - you
48  * can force an update by calling the refreshAttributes and refreshMetadata
49  * operations on this mbean.
50  *
51  * TODO: implement the user/pass auth ( right now you must use IP based security )
52  * TODO: eventually support https
53  * TODO: support for metadata ( mbean-descriptors ) for description and type conversions
54  * TODO: filter out trivial components ( mutexes, etc )
55  *
56  * @author Costin Manolache
57  */

58 public class ModJkMX extends JkHandler
59 {
60     private static Log log = LogFactory.getLog(ModJkMX.class);
61
62     MBeanServer JavaDoc mserver;
63     String JavaDoc webServerHost="localhost";
64     int webServerPort=80;
65     String JavaDoc statusPath="/jkstatus";
66     String JavaDoc user;
67     String JavaDoc pass;
68     Registry reg;
69
70     HashMap JavaDoc mbeans=new HashMap JavaDoc();
71     long lastRefresh=0;
72     long updateInterval=5000; // 5 sec - it's min time between updates
73

74     public ModJkMX()
75     {
76     }
77
78     /* -------------------- Public methods -------------------- */
79
80     public String JavaDoc getWebServerHost() {
81         return webServerHost;
82     }
83
84     public void setWebServerHost(String JavaDoc webServerHost) {
85         this.webServerHost = webServerHost;
86     }
87
88     public int getWebServerPort() {
89         return webServerPort;
90     }
91
92     public void setWebServerPort(int webServerPort) {
93         this.webServerPort = webServerPort;
94     }
95
96     public long getUpdateInterval() {
97         return updateInterval;
98     }
99
100     public void setUpdateInterval(long updateInterval) {
101         this.updateInterval = updateInterval;
102     }
103
104     public String JavaDoc getUser() {
105         return user;
106     }
107
108     public void setUser(String JavaDoc user) {
109         this.user = user;
110     }
111
112     public String JavaDoc getPass() {
113         return pass;
114     }
115
116     public void setPass(String JavaDoc pass) {
117         this.pass = pass;
118     }
119
120     public String JavaDoc getStatusPath() {
121         return statusPath;
122     }
123
124     public void setStatusPath(String JavaDoc statusPath) {
125         this.statusPath = statusPath;
126     }
127     /* ==================== Start/stop ==================== */
128
129     public void destroy() {
130         try {
131             // We should keep track of loaded beans and call stop.
132
// Modeler should do it...
133
Iterator JavaDoc mbeansIt=mbeans.values().iterator();
134             MBeanServer JavaDoc mbserver = Registry.getRegistry(null, null).getMBeanServer();
135             while( mbeansIt.hasNext()) {
136                 MBeanProxy proxy=(MBeanProxy)mbeansIt.next();
137                 Object JavaDoc ooname = proxy.getObjectName();
138                 if( ooname != null ) {
139                     ObjectName JavaDoc oname = null;
140                     if(ooname instanceof ObjectName JavaDoc) {
141                         oname = (ObjectName JavaDoc)ooname;
142                     } else if(ooname instanceof String JavaDoc) {
143                         oname = new ObjectName JavaDoc((String JavaDoc)ooname);
144                     }
145                     if( oname != null ) {
146                         mbserver.unregisterMBean(oname);
147                     }
148                 }
149             }
150         } catch( Throwable JavaDoc t ) {
151             log.error( "Destroy error", t );
152         }
153     }
154
155     public void init() throws IOException JavaDoc {
156         try {
157             //if( log.isDebugEnabled() )
158
log.info("init " + webServerHost + " " + webServerPort);
159             reg=Registry.getRegistry(null, null);
160             refreshMetadata();
161             refreshAttributes();
162         } catch( Throwable JavaDoc t ) {
163             log.error( "Init error", t );
164         }
165     }
166
167     public void start() throws IOException JavaDoc {
168         if( reg==null)
169             init();
170     }
171
172     /** Refresh the proxies, if updateInterval passed
173      *
174      */

175     public void refresh() {
176         long time=System.currentTimeMillis();
177         if( time - lastRefresh < updateInterval ) {
178             return;
179         }
180         lastRefresh=time;
181         refreshMetadata();
182         refreshAttributes();
183     }
184
185     public void refreshAttributes() {
186         try {
187             int cnt=0;
188             // connect to apache, get a list of mbeans
189
BufferedReader JavaDoc is=getStream( "dmp=*");
190             if( is==null ) return;
191
192             String JavaDoc name=null;
193             String JavaDoc att=null;
194             String JavaDoc val=null;
195             while(true) {
196                 String JavaDoc line=is.readLine();
197                 if( line==null ) break;
198                 line=line.trim();
199                 if( "".equals(line) || line.startsWith("#") ) continue;
200
201                 // for each mbean, create a proxy
202
if(log.isDebugEnabled())
203                     log.debug("Read " + line);
204
205                 if(line.startsWith( "[")) {
206                     name=line.substring(1);
207                     if( name.endsWith("]")) {
208                         name=name.substring(0, name.length()-1);
209                     }
210                 }
211                 // Name/value pair
212
int idx=line.indexOf('=');
213                 if( idx < 0 ) continue;
214                 att=line.substring(0, idx );
215                 val=line.substring(idx+1);
216
217                 if( log.isDebugEnabled())
218                     log.debug("name: " + name + " att=" + att +
219                             " val=" + val);
220
221                 MBeanProxy proxy=(MBeanProxy)mbeans.get(name);
222                 if( proxy==null ) {
223                     log.info( "Unknown object " + name);
224                 } else {
225                     proxy.update(att, val);
226                     cnt++;
227                 }
228             }
229             log.info( "Refreshing attributes " + cnt);
230         } catch( Exception JavaDoc ex ) {
231             log.info("Error ", ex);
232         }
233     }
234
235     /** connect to apache, get a list of mbeans
236       */

237     BufferedReader JavaDoc getStream(String JavaDoc qry) throws Exception JavaDoc {
238         try {
239             String JavaDoc path=statusPath + "?" + qry;
240             URL JavaDoc url=new URL JavaDoc( "http", webServerHost, webServerPort, path);
241             URLConnection JavaDoc urlc=url.openConnection();
242             BufferedReader JavaDoc is=new BufferedReader JavaDoc(new InputStreamReader JavaDoc(urlc.getInputStream()));
243             return is;
244         } catch (IOException JavaDoc e) {
245             log.info( "Can't connect to jkstatus " + webServerHost + ":" + webServerPort
246             + " " + e.toString());
247             return null;
248         }
249     }
250
251     public void refreshMetadata() {
252         try {
253             int cnt=0;
254             int newCnt=0;
255             BufferedReader JavaDoc is=getStream("lst=*");
256             if( is==null ) return;
257             String JavaDoc name=null;
258             String JavaDoc type=null;
259             ArrayList JavaDoc getters=new ArrayList JavaDoc();
260             ArrayList JavaDoc setters=new ArrayList JavaDoc();
261             ArrayList JavaDoc methods=new ArrayList JavaDoc();
262             while(true) {
263                 String JavaDoc line=is.readLine();
264                 if( log.isDebugEnabled())
265                     log.debug("Read " + line);
266
267                 // end of section
268
if( line == null || line.startsWith("[") ) {
269                     if( name != null ) {
270                         cnt++;
271                         if( mbeans.get( name ) ==null ) {
272                             // New component
273
newCnt++;
274                             MBeanProxy mproxy=new MBeanProxy(this);
275                             mproxy.init( name, getters, setters, methods);
276                             mbeans.put( name, mproxy );
277                         }
278                         if( log.isDebugEnabled())
279                             log.debug("mbean name: " + name + " type=" + type);
280
281                         getters.clear();
282                         setters.clear();
283                         methods.clear();
284                     }
285                 }
286                 // end of data
287
if( line==null ) break;
288
289                 line=line.trim();
290                 if( "".equals( line ) || line.startsWith("#")) continue;
291
292                 // for each mbean, create a proxy
293

294                 if(line.startsWith( "[") && line.endsWith("]")) {
295                     name=line.substring(1, line.length()-1);
296                 }
297                 if(line.startsWith( "T=")) {
298                     type=line.substring(2);
299                 }
300                 if( line.startsWith("G=")) {
301                     getters.add(line.substring(2));
302                 }
303                 if( line.startsWith("S=")) {
304                     setters.add(line.substring(2));
305                 }
306                 if( line.startsWith("M=")) {
307                     methods.add(line.substring(2));
308                 }
309             }
310             log.info( "Refreshing metadata " + cnt + " " + newCnt);
311         } catch( Exception JavaDoc ex ) {
312             log.info("Error ", ex);
313         }
314     }
315
316     /** Use the same metadata, except that we replace the attribute
317      * get/set methods.
318      */

319     static class MBeanProxy extends BaseModelMBean {
320         private static Log log = LogFactory.getLog(MBeanProxy.class);
321
322         String JavaDoc jkName;
323         List JavaDoc getAttNames;
324         List JavaDoc setAttNames;
325         HashMap JavaDoc atts=new HashMap JavaDoc();
326         ModJkMX jkmx;
327
328         public MBeanProxy(ModJkMX jkmx) throws Exception JavaDoc {
329             this.jkmx=jkmx;
330         }
331
332         void init( String JavaDoc name, List JavaDoc getters, List JavaDoc setters, List JavaDoc methods )
333             throws Exception JavaDoc
334         {
335             if(log.isDebugEnabled())
336                 log.debug("Register " + name );
337             int col=name.indexOf( ':' );
338             this.jkName=name;
339             String JavaDoc type=name.substring(0, col );
340             String JavaDoc id=name.substring(col+1);
341             id=id.replace('*','%');
342             id=id.replace(':', '%');
343             if( id.length() == 0 ) {
344                 id="default";
345             }
346             ManagedBean mbean= new ManagedBean();
347
348             AttributeInfo ai=new AttributeInfo();
349             ai.setName( "jkName" );
350             ai.setType( "java.lang.String");
351             ai.setWriteable(false);
352             mbean.addAttribute(ai);
353
354             for( int i=0; i<getters.size(); i++ ) {
355                 String JavaDoc att=(String JavaDoc)getters.get(i);
356                 // Register metadata
357
ai=new AttributeInfo();
358                 ai.setName( att );
359                 ai.setType( "java.lang.String");
360                 if( ! setters.contains(att))
361                     ai.setWriteable(false);
362                 mbean.addAttribute(ai);
363             }
364             for( int i=0; i<setters.size(); i++ ) {
365                 String JavaDoc att=(String JavaDoc)setters.get(i);
366                 if( getters.contains(att))
367                     continue;
368                 // Register metadata
369
ai=new AttributeInfo();
370                 ai.setName( att );
371                 ai.setType( "java.lang.String");
372                 ai.setReadable(false);
373                 mbean.addAttribute(ai);
374             }
375             for( int i=0; i<methods.size(); i++ ) {
376                 String JavaDoc att=(String JavaDoc)methods.get(i);
377                 // Register metadata
378
OperationInfo oi=new OperationInfo();
379                 oi.setName( att );
380                 oi.setReturnType("void");
381                 mbean.addOperation(oi);
382             }
383
384             this.setModelMBeanInfo(mbean.createMBeanInfo());
385
386             MBeanServer JavaDoc mserver=Registry.getRegistry(null, null).getMBeanServer();
387             oname=new ObjectName JavaDoc("apache:type=" + type + ",id=" + id);
388             mserver.registerMBean(this, oname);
389         }
390
391         private void update( String JavaDoc name, String JavaDoc val ) {
392             log.debug( "Updating " + jkName + " " + name + " " + val);
393             atts.put( name, val);
394         }
395
396         public Object JavaDoc getAttribute(String JavaDoc name)
397             throws AttributeNotFoundException JavaDoc, MBeanException JavaDoc,
398                 ReflectionException JavaDoc {
399             if( "jkName".equals( name )) {
400                 return jkName;
401             }
402             jkmx.refresh();
403             return atts.get(name);
404         }
405
406         public void setAttribute(Attribute JavaDoc attribute)
407             throws AttributeNotFoundException JavaDoc, MBeanException JavaDoc,
408             ReflectionException JavaDoc
409         {
410             try {
411                 // we support only string values
412
String JavaDoc val=(String JavaDoc)attribute.getValue();
413                 String JavaDoc name=attribute.getName();
414                 BufferedReader JavaDoc is=jkmx.getStream("set=" + jkName + "|" +
415                         name + "|" + val);
416                 if( is==null ) return;
417                 String JavaDoc res=is.readLine();
418                 if( log.isDebugEnabled())
419                     log.debug( "Setting " + jkName + " " + name + " result " + res);
420
421                 jkmx.refreshMetadata();
422                 jkmx.refreshAttributes();
423             } catch( Exception JavaDoc ex ) {
424                 throw new MBeanException JavaDoc(ex);
425             }
426         }
427
428         public Object JavaDoc invoke(String JavaDoc name, Object JavaDoc params[], String JavaDoc signature[])
429             throws MBeanException JavaDoc, ReflectionException JavaDoc {
430             try {
431                 // we support only string values
432
BufferedReader JavaDoc is=jkmx.getStream("inv=" + jkName + "|" +
433                         name );
434                 if( is==null ) return null;
435                 String JavaDoc res=is.readLine();
436                 if( log.isDebugEnabled())
437                     log.debug( "Invoking " + jkName + " " + name + " result " + res);
438
439                 jkmx.refreshMetadata();
440                 jkmx.refreshAttributes();
441             } catch( Exception JavaDoc ex ) {
442                 throw new MBeanException JavaDoc(ex);
443             }
444             return null;
445         }
446
447     }
448
449
450 }
451
452
Popular Tags