KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > jmx > MBeanTest


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: MBeanTest.java,v 1.14 2006/10/30 21:14:45 bostic Exp $
7  */

8
9 package com.sleepycat.je.jmx;
10
11 import java.io.ByteArrayOutputStream JavaDoc;
12 import java.io.File JavaDoc;
13 import java.io.IOException JavaDoc;
14 import java.io.ObjectOutputStream JavaDoc;
15 import java.io.Serializable JavaDoc;
16 import java.lang.reflect.Method JavaDoc;
17 import java.util.Arrays JavaDoc;
18 import java.util.List JavaDoc;
19
20 import javax.management.Attribute JavaDoc;
21 import javax.management.DynamicMBean JavaDoc;
22 import javax.management.JMException JavaDoc;
23 import javax.management.MBeanAttributeInfo JavaDoc;
24 import javax.management.MBeanConstructorInfo JavaDoc;
25 import javax.management.MBeanException JavaDoc;
26 import javax.management.MBeanInfo JavaDoc;
27 import javax.management.MBeanNotificationInfo JavaDoc;
28 import javax.management.MBeanOperationInfo JavaDoc;
29 import javax.management.MBeanParameterInfo JavaDoc;
30
31 import jmx.JEApplicationMBean;
32 import junit.framework.TestCase;
33
34 import com.sleepycat.bind.tuple.IntegerBinding;
35 import com.sleepycat.je.BtreeStats;
36 import com.sleepycat.je.Database;
37 import com.sleepycat.je.DatabaseConfig;
38 import com.sleepycat.je.DatabaseEntry;
39 import com.sleepycat.je.DatabaseException;
40 import com.sleepycat.je.DbInternal;
41 import com.sleepycat.je.Environment;
42 import com.sleepycat.je.EnvironmentConfig;
43 import com.sleepycat.je.util.TestUtils;
44
45 /**
46  * Instantiate and exercise the JEMonitor.
47  */

48 public class MBeanTest extends TestCase {
49     
50     private static final boolean DEBUG = true;
51     private File JavaDoc envHome;
52     private String JavaDoc environmentDir;
53
54     public MBeanTest() {
55         environmentDir = System.getProperty(TestUtils.DEST_DIR);
56         envHome = new File JavaDoc(environmentDir);
57     }
58
59     public void setUp()
60         throws IOException JavaDoc {
61
62         TestUtils.removeLogFiles("Setup", envHome, false);
63     }
64     
65     public void tearDown()
66         throws Exception JavaDoc {
67
68         TestUtils.removeLogFiles("tearDown", envHome, true);
69     }
70
71     /**
72      * Test an mbean which is prohibited from configuring and opening an
73      * environment.
74      */

75     public void testNoOpenMBean()
76         throws Throwable JavaDoc {
77         
78         Environment env = null;
79         try {
80             
81             /* Environment is not open, and we can't open. */
82             DynamicMBean JavaDoc mbean = new JEMonitor(environmentDir);
83             validateGetters(mbean, 2);
84             validateOperations(mbean, 0, true, null, null);
85             
86             /* Now open the environment transactionally by other means. */
87             env = openEnv(true);
88             validateGetters(mbean, 2 ); // alas, takes two refreshes to
89
validateGetters(mbean, 9 ); // see the change.
90
validateOperations(mbean, 8, true, null, null);
91
92             /* Close the environment. */
93             env.close();
94             validateGetters(mbean, 2);
95             validateOperations(mbean, 0, true, null, null);
96
97             /*
98              * Try this kind of mbean against an environment that's already
99              * open.
100              */

101             env = openEnv(true);
102             mbean = new JEMonitor(environmentDir);
103             validateGetters(mbean, 9 ); // see the change.
104
validateOperations(mbean, 8, true, null, null);
105
106             /*
107              * Getting database stats against a non-existing db ought to
108              * throw an exception.
109              */

110             try {
111                 validateOperations(mbean, 8, true, "bozo", null);
112                 fail("Should not have run stats on a non-existent db");
113             } catch (MBeanException JavaDoc expected) {
114                 // ignore
115
}
116
117             /*
118              * Make sure the vanilla db open within the helper can open
119              * a db created with a non-default configuration.
120              */

121             DatabaseConfig dbConfig = new DatabaseConfig();
122             dbConfig.setAllowCreate(true);
123             dbConfig.setTransactional(true);
124             Database db = env.openDatabase(null, "bozo", dbConfig);
125
126             /* insert a record. */
127             DatabaseEntry entry = new DatabaseEntry();
128             IntegerBinding.intToEntry(1, entry);
129             db.put(null, entry, entry);
130
131             validateOperations(mbean, 8, true, "bozo", new String JavaDoc [] {"bozo"});
132             db.close();
133
134             env.close();
135             validateGetters(mbean, 2);
136             validateOperations(mbean, 0, true, null, null);
137
138             checkForNoOpenHandles(environmentDir);
139         } catch (Throwable JavaDoc t) {
140             t.printStackTrace();
141             if (env != null) {
142                 env.close();
143             }
144             throw t;
145         }
146     }
147
148     /**
149      * MBean which can configure and open an environment.
150      */

151     public void testOpenableBean()
152         throws Throwable JavaDoc {
153
154         Environment env = null;
155         try {
156             /* Environment is not open, and we can open. */
157             env = openEnv(false);
158             env.close();
159
160             DynamicMBean JavaDoc mbean = new JEApplicationMBean(environmentDir);
161             validateGetters(mbean, 5);
162             validateOperations(mbean, 1, false, null, null); // don't invoke
163

164             /* Open the environment. */
165             mbean.invoke(JEApplicationMBean.OP_OPEN, null, null);
166                          
167             validateGetters(mbean, 7 );
168             validateOperations(mbean, 8, true, null, null);
169
170             /*
171              * The last call to validateOperations ended up closing the
172              * environment.
173              */

174             validateGetters(mbean, 5);
175             validateOperations(mbean, 1, false, null, null);
176
177             /* Should be no open handles. */
178             checkForNoOpenHandles(environmentDir);
179         } catch (Throwable JavaDoc t) {
180             t.printStackTrace();
181             
182             if (env != null) {
183                 env.close();
184             }
185             throw t;
186         }
187     }
188
189     /**
190      * Exercise setters.
191      */

192     public void testMBeanSetters()
193         throws Throwable JavaDoc {
194
195         Environment env = null;
196         try {
197             /* Mimic an application by opening an environment. */
198             env = openEnv(false);
199
200             /* Open an mbean and set the environment home. */
201             DynamicMBean JavaDoc mbean = new JEMonitor(environmentDir);
202             
203             /*
204              * Try setting different attributes. Check against the
205              * initial value, and the value after setting.
206              */

207             EnvironmentConfig config = env.getConfig();
208             Class JavaDoc configClass = config.getClass();
209
210             Method JavaDoc getCacheSize = configClass.getMethod("getCacheSize", (Class JavaDoc []) null);
211             checkAttribute(env,
212                            mbean,
213                            getCacheSize,
214                            JEMBeanHelper.ATT_CACHE_SIZE,
215                            new Long JavaDoc(100000)); // new value
216

217             Method JavaDoc getCachePercent =
218                 configClass.getMethod("getCachePercent", (Class JavaDoc []) null);
219             checkAttribute(env,
220                            mbean,
221                            getCachePercent,
222                            JEMBeanHelper.ATT_CACHE_PERCENT,
223                            new Integer JavaDoc(10));
224             env.close();
225
226             checkForNoOpenHandles(environmentDir);
227         } catch (Throwable JavaDoc t) {
228             t.printStackTrace();
229
230             if (env != null) {
231                 env.close();
232             }
233
234             throw t;
235         }
236     }
237
238     private void checkAttribute(Environment env,
239                                 DynamicMBean JavaDoc mbean,
240                                 Method JavaDoc configMethod,
241                                 String JavaDoc attributeName,
242                                 Object JavaDoc newValue)
243         throws Exception JavaDoc {
244         /* check starting value. */
245         EnvironmentConfig config = env.getConfig();
246         Object JavaDoc result = configMethod.invoke(config, (Object JavaDoc []) null);
247         assertTrue(!result.toString().equals(newValue.toString()));
248
249         /* set through mbean */
250         mbean.setAttribute(new Attribute JavaDoc(attributeName, newValue));
251
252         /* check present environment config. */
253         config = env.getConfig();
254         assertEquals(newValue.toString(),
255                      configMethod.invoke(config, (Object JavaDoc []) null).toString());
256
257         /* check through mbean. */
258         Object JavaDoc mbeanNewValue = mbean.getAttribute(attributeName);
259         assertEquals(newValue.toString(), mbeanNewValue.toString());
260     }
261
262     /*
263      */

264     private void validateGetters(DynamicMBean JavaDoc mbean,
265                                  int numExpectedAttributes)
266         throws Throwable JavaDoc {
267
268         MBeanInfo JavaDoc info = mbean.getMBeanInfo();
269
270         MBeanAttributeInfo JavaDoc [] attrs = info.getAttributes();
271
272         /* test getters. */
273         int attributesWithValues = 0;
274         for (int i = 0; i < attrs.length; i++) {
275             String JavaDoc name = attrs[i].getName();
276             Object JavaDoc result = mbean.getAttribute(name);
277             if (DEBUG) {
278                 System.out.println("Attribute " + i +
279                                    " name=" + name +
280                                    " result=" + result);
281             }
282             if (result != null) {
283                 attributesWithValues++;
284                 checkObjectType
285                     ("Attribute", name, attrs[i].getType(), result);
286             }
287         }
288
289         assertEquals(numExpectedAttributes, attributesWithValues);
290     }
291
292     /*
293      * Check that there are the expected number of operations.
294      * If specified, invoke and check the results.
295      * @param tryInvoke if true, invoke the operations.
296      * @param databaseName if not null, execute the database specific
297      * operations using the database name.
298      */

299     private void validateOperations(DynamicMBean JavaDoc mbean,
300                                     int numExpectedOperations,
301                                     boolean tryInvoke,
302                                     String JavaDoc databaseName,
303                                     String JavaDoc[] expectedDatabases)
304         throws Throwable JavaDoc {
305
306         MBeanInfo JavaDoc info = mbean.getMBeanInfo();
307
308         MBeanOperationInfo JavaDoc [] ops = info.getOperations();
309         if (DEBUG) {
310             for (int i = 0; i < ops.length; i++) {
311                 System.out.println("op: " + ops[i].getName());
312             }
313         }
314         assertEquals(numExpectedOperations, ops.length);
315             
316         if (tryInvoke) {
317             for (int i = 0; i < ops.length; i++) {
318                 String JavaDoc opName = ops[i].getName();
319
320                 /* Try the per-database operations if specified. */
321                 if ((databaseName != null) &&
322                     opName.equals(JEMBeanHelper.OP_DB_STAT)) {
323                     /* invoke with the name of the database. */
324                     Object JavaDoc result = mbean.invoke
325                         (opName,
326                          new Object JavaDoc [] {null, null, databaseName},
327                          null);
328                     assertTrue(result instanceof BtreeStats);
329                     checkObjectType
330                         ("Operation", opName, ops[i].getReturnType(), result);
331                 }
332
333                 if ((expectedDatabases != null) &&
334                     opName.equals(JEMBeanHelper.OP_DB_NAMES)) {
335                     Object JavaDoc result = mbean.invoke(opName, null, null);
336                     List JavaDoc names = (List JavaDoc) result;
337                     assertTrue(Arrays.equals(expectedDatabases,
338                                              names.toArray()));
339                     checkObjectType
340                         ("Operation", opName, ops[i].getReturnType(), result);
341                 }
342
343                 /*
344                  * Also invoke all operations with null params, to sanity
345                  * check.
346                  */

347                 Object JavaDoc result = mbean.invoke(opName, null, null);
348                 if (result != null) {
349                     checkObjectType
350                         ("Operation", opName, ops[i].getReturnType(), result);
351                 }
352             }
353         }
354     }
355
356     /**
357      * Checks that all parameters and return values are Serializable to
358      * support JMX over RMI.
359      */

360     public void testSerializable()
361         throws JMException JavaDoc, DatabaseException {
362
363         /* Create and close the environment. */
364         Environment env = openEnv(false);
365         env.close();
366
367         /* Test without an open environment. */
368         DynamicMBean JavaDoc mbean = new JEApplicationMBean(environmentDir);
369         doTestSerializable(mbean);
370
371         /* Test with an open environment. */
372         mbean.invoke(JEApplicationMBean.OP_OPEN, null, null);
373         doTestSerializable(mbean);
374
375         /* Close. */
376         mbean.invoke(JEApplicationMBean.OP_CLOSE, null, null);
377     }
378
379     /**
380      * Checks that all types for the given mbean are serializable.
381      */

382     private void doTestSerializable(DynamicMBean JavaDoc mbean) {
383
384         MBeanInfo JavaDoc info = mbean.getMBeanInfo();
385
386         MBeanAttributeInfo JavaDoc [] attrs = info.getAttributes();
387         for (int i = 0; i < attrs.length; i++) {
388             checkSerializable
389                 ("Attribute", attrs[i].getName(), attrs[i].getType());
390         }
391
392         MBeanOperationInfo JavaDoc [] ops = info.getOperations();
393         for (int i = 0; i < ops.length; i += 1) {
394             checkSerializable
395                 ("Operation",
396                  ops[i].getName() + " return type",
397                  ops[i].getReturnType());
398             MBeanParameterInfo JavaDoc[] params = ops[i].getSignature();
399             for (int j = 0; j < params.length; j += 1) {
400                 checkSerializable
401                     ("Operation",
402                      ops[i].getName() + " parameter " + j,
403                      params[j].getType());
404             }
405         }
406
407         MBeanConstructorInfo JavaDoc [] ctors = info.getConstructors();
408         for (int i = 0; i < ctors.length; i++) {
409             MBeanParameterInfo JavaDoc[] params = ctors[i].getSignature();
410             for (int j = 0; j < params.length; j += 1) {
411                 checkSerializable
412                     ("Constructor",
413                      ctors[i].getName() + " parameter " + j,
414                      params[j].getType());
415             }
416         }
417
418         MBeanNotificationInfo JavaDoc [] notifs = info.getNotifications();
419         for (int i = 0; i < notifs.length; i++) {
420             String JavaDoc[] types = notifs[i].getNotifTypes();
421             for (int j = 0; j < types.length; j += 1) {
422                 checkSerializable
423                     ("Notification", notifs[i].getName(), types[j]);
424             }
425         }
426     }
427
428     /**
429      * Checks that a given type is serializable.
430      */

431     private void checkSerializable(String JavaDoc identifier,
432                                    String JavaDoc name,
433                                    String JavaDoc type) {
434
435         if ("void".equals(type)) {
436             return;
437         }
438         String JavaDoc msg = identifier + ' ' + name + " is type " + type;
439         try {
440             Class JavaDoc cls = Class.forName(type);
441             if (!Serializable JavaDoc.class.isAssignableFrom(cls)) {
442                 fail(msg + " -- not Serializable");
443             }
444         } catch (Exception JavaDoc e) {
445             fail(msg + " -- " + e);
446         }
447     }
448
449     /**
450      * Checks that an object (parameter or return value) is of the type
451      * specified in the BeanInfo.
452      */

453     private void checkObjectType(String JavaDoc identifier,
454                                  String JavaDoc name,
455                                  String JavaDoc type,
456                                  Object JavaDoc object) {
457
458         String JavaDoc msg = identifier + ' ' + name + " is type " + type;
459         if ("void".equals(type)) {
460             assertNull(msg + "-- should be null", object);
461             return;
462         }
463         try {
464             Class JavaDoc cls = Class.forName(type);
465             assertTrue
466                 (msg + " -- object class is " + object.getClass().getName(),
467                  cls.isAssignableFrom(object.getClass()));
468         } catch (Exception JavaDoc e) {
469             fail(msg + " -- " + e);
470         }
471
472         /*
473          * The true test of serializable is to serialize. This checks the
474          * a elements of a list, for example.
475          */

476         try {
477             ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
478             ObjectOutputStream JavaDoc oos = new ObjectOutputStream JavaDoc(baos);
479             oos.writeObject(object);
480         } catch (Exception JavaDoc e) {
481             fail(msg + " -- " + e);
482         }
483     }
484
485     private void checkForNoOpenHandles(String JavaDoc environmentDir) {
486         File JavaDoc envFile = new File JavaDoc(environmentDir);
487         Environment testEnv = DbInternal.getEnvironmentShell(envFile);
488         assertTrue(testEnv == null);
489     }
490
491     /*
492      * Helper to open an environment.
493      */

494     private Environment openEnv(boolean openTransactionally)
495         throws DatabaseException {
496         
497         EnvironmentConfig envConfig = TestUtils.initEnvConfig();
498         envConfig.setAllowCreate(true);
499         envConfig.setTransactional(openTransactionally);
500         return new Environment(envHome, envConfig);
501     }
502
503 }
504
Popular Tags