KickJava   Java API By Example, From Geeks To Geeks.

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


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

8
9 package com.sleepycat.je.jmx;
10
11 import java.io.File JavaDoc;
12 import java.lang.reflect.Constructor JavaDoc;
13 import java.util.List JavaDoc;
14
15 import javax.management.Attribute JavaDoc;
16 import javax.management.AttributeList JavaDoc;
17 import javax.management.AttributeNotFoundException JavaDoc;
18 import javax.management.DynamicMBean JavaDoc;
19 import javax.management.InvalidAttributeValueException JavaDoc;
20 import javax.management.MBeanAttributeInfo JavaDoc;
21 import javax.management.MBeanConstructorInfo JavaDoc;
22 import javax.management.MBeanException JavaDoc;
23 import javax.management.MBeanInfo JavaDoc;
24 import javax.management.MBeanNotificationInfo JavaDoc;
25 import javax.management.MBeanOperationInfo JavaDoc;
26
27 import com.sleepycat.je.DatabaseException;
28 import com.sleepycat.je.Environment;
29
30 /**
31  * JEMonitor is a JMX MBean which manages a JE environment.
32  * The MBean may be installed as is, or used as a starting point for building
33  * a MBean which includes JE support. JEMonitor expects another component in
34  * the JVM to configure and open the JE environment; it will only access a JE
35  * environment that is already active. It is intended for these use cases:
36  * <ul>
37  * <li>
38  * The application wants to add database monitoring with minimal effort and
39  * little knowledge of JMX. Configuring JEMonitor within the JMX container
40  * provides monitoring without requiring application code changes. </li>
41  * </li>
42    <li>
43  * An application already supports JMX and wants to add database monitoring
44  * without modifying its existing MBean. The user can configure JEMonitor in
45  * the JMX container in conjunction with other application MBeans that are
46  * non-overlapping with JE monitoring. No application code changes are
47  * required. </li>
48  * </ul>
49  * <p>
50  * In this MBean, JE management is divided between the JEMonitor class and
51  * JEMBeanHelper class. JEMonitor contains an instance of JEMBeanHelper, which
52  * knows about JE attributes, operations and notifications. JEMonitor itself
53  * has the responsibility of obtaining a temporary handle for the JE
54  * environment.
55  * <p>
56  * The key implementation choice for a JE MBean is the approach taken for
57  * accessing the JE environment. Some of the salient considerations are:
58  * <ul>
59  * <li>Applications may open one or many Environment objects per process
60  * against a given environment.</li>
61  *
62  * <li>All Environment handles reference the same underlying JE environment
63  * implementation object.</li>
64
65  * <li> The first Environment object instantiated in the process does the real
66  * work of configuring and opening the environment. Follow-on instantiations of
67  * Environment merely increment a reference count. Likewise,
68  * Environment.close() only does real work when it's called by the last
69  * Environment object in the process. </li>
70  * </ul>
71  * <p>
72  * Because of these considerations, JEMonitor avoids holding a JE environment
73  * handle in order to not impact the environment lifetime. Any environment
74  * handles used are held temporarily.
75  */

76 public class JEMonitor implements DynamicMBean JavaDoc {
77
78     private static final String JavaDoc DESCRIPTION =
79         "Monitor an open Berkeley DB, Java Edition environment.";
80     
81     private MBeanInfo JavaDoc mbeanInfo; // this MBean's visible interface.
82
private JEMBeanHelper jeHelper; // gets JE management interface.
83

84     /**
85      * Instantiate a JEMonitor
86      *
87      * @param environmentHome home directory of the target JE environment.
88      */

89     public JEMonitor(String JavaDoc environmentHome)
90         throws MBeanException JavaDoc {
91
92         File JavaDoc environmentDirectory = new File JavaDoc(environmentHome);
93         jeHelper = new JEMBeanHelper(environmentDirectory, false);
94
95         Environment targetEnv = getEnvironmentIfOpen();
96         try {
97             resetMBeanInfo(targetEnv);
98         } finally {
99             closeEnvironment(targetEnv);
100         }
101     }
102
103     /**
104      * @see DynamicMBean#getAttribute
105      */

106     public Object JavaDoc getAttribute(String JavaDoc attributeName)
107         throws AttributeNotFoundException JavaDoc,
108                MBeanException JavaDoc {
109
110         Object JavaDoc result = null;
111         Environment targetEnv = getEnvironmentIfOpen();
112         try {
113             result = jeHelper.getAttribute(targetEnv, attributeName);
114             targetEnv = checkForMBeanReset(targetEnv);
115         } finally {
116             /* release resource. */
117             closeEnvironment(targetEnv);
118         }
119
120         return result;
121     }
122
123     /**
124      * @see DynamicMBean#setAttribute
125      */

126     public void setAttribute(Attribute JavaDoc attribute)
127         throws AttributeNotFoundException JavaDoc,
128                InvalidAttributeValueException JavaDoc,
129                MBeanException JavaDoc {
130
131         Environment targetEnv = getEnvironmentIfOpen();
132         try {
133             jeHelper.setAttribute(targetEnv, attribute);
134         } finally {
135             /* release resources. */
136             closeEnvironment(targetEnv);
137         }
138     }
139
140     /**
141      * @see DynamicMBean#getAttributes
142      */

143     public AttributeList JavaDoc getAttributes(String JavaDoc[] attributes) {
144
145         /* Sanity checking. */
146     if (attributes == null) {
147         throw new IllegalArgumentException JavaDoc("Attributes cannot be null");
148     }
149
150         /* Get each requested attribute. */
151         AttributeList JavaDoc results = new AttributeList JavaDoc();
152         Environment targetEnv = getEnvironmentIfOpen();
153
154         try {
155             for (int i = 0; i < attributes.length; i++) {
156                 try {
157                     String JavaDoc name = attributes[i];
158                     Object JavaDoc value = jeHelper.getAttribute(targetEnv, name);
159                     
160                     /*
161                      * jeHelper may notice that the environment state has
162                      * changed. If so, this mbean must update its interface.
163                      */

164                     targetEnv = checkForMBeanReset(targetEnv);
165
166                     results.add(new Attribute JavaDoc(name, value));
167                 } catch (Exception JavaDoc e) {
168                     e.printStackTrace();
169                 }
170             }
171             return results;
172         } finally {
173             try {
174                 /* release resources. */
175                 closeEnvironment(targetEnv);
176             } catch (MBeanException JavaDoc ignore) {
177                 /* ignore */
178             }
179         }
180     }
181
182     /**
183      * @see DynamicMBean#setAttributes
184      */

185     public AttributeList JavaDoc setAttributes(AttributeList JavaDoc attributes) {
186
187         /* Sanity checking. */
188     if (attributes == null) {
189         throw new IllegalArgumentException JavaDoc("attribute list can't be null");
190     }
191
192         /* Set each attribute specified. */
193     AttributeList JavaDoc results = new AttributeList JavaDoc();
194         Environment targetEnv = getEnvironmentIfOpen();
195
196         try {
197             for (int i = 0; i < attributes.size(); i++) {
198                 Attribute JavaDoc attr = (Attribute JavaDoc) attributes.get(i);
199                 try {
200                     /* Set new value. */
201                     jeHelper.setAttribute(targetEnv, attr);
202
203                     /*
204                      * Add the name and new value to the result list. Be sure
205                      * to ask the MBean for the new value, rather than simply
206                      * using attr.getValue(), because the new value may not
207                      * be same if it is modified according to the JE
208                      * implementation.
209                      */

210                     String JavaDoc name = attr.getName();
211                     Object JavaDoc newValue = jeHelper.getAttribute(targetEnv, name);
212                     results.add(new Attribute JavaDoc(name, newValue));
213                 } catch (Exception JavaDoc e) {
214                     e.printStackTrace();
215                 }
216             }
217             return results;
218         } finally {
219             try {
220                 /* release resources. */
221                 closeEnvironment(targetEnv);
222             } catch (MBeanException JavaDoc ignore) {
223                 /* ignore */
224             }
225         }
226     }
227
228     /**
229      * @see DynamicMBean#invoke
230      */

231     public Object JavaDoc invoke(String JavaDoc actionName,
232                          Object JavaDoc[] params,
233                          String JavaDoc[] signature)
234         throws MBeanException JavaDoc {
235
236         Object JavaDoc result = null;
237         Environment targetEnv = getEnvironmentIfOpen();
238         try {
239             result = jeHelper.invoke(targetEnv, actionName,
240                                      params, signature);
241         } finally {
242             /* release resources. */
243             closeEnvironment(targetEnv);
244         }
245
246         return result;
247     }
248
249     /**
250      * @see DynamicMBean#getMBeanInfo
251      */

252     public MBeanInfo JavaDoc getMBeanInfo() {
253
254     return mbeanInfo;
255     }
256
257     /**
258      * The JEHelper may detect a change in environment attributes that
259      * results in a change in management functionality. Reset the
260      * MBeanInfo if needed and refresh the temporary environment handle.
261      *
262      * @param targetEnv the temporary JE environment handle
263      * @return new environment handle to replace targetEnv. Must be released
264      * by the caller.
265      */

266     private Environment checkForMBeanReset(Environment targetEnv)
267         throws MBeanException JavaDoc {
268
269         Environment env = targetEnv;
270         if (jeHelper.getNeedReset()) {
271
272             /* Refresh the environmen handle. */
273             closeEnvironment(env);
274             env = getEnvironmentIfOpen();
275             resetMBeanInfo(env);
276         }
277         return env;
278     }
279
280     /**
281      * Create the available management interface for this environment.
282      * The attributes and operations available vary according to
283      * environment configuration.
284      *
285      * @param targetEnv an open environment handle for the
286      * targetted application.
287      */

288     private void resetMBeanInfo(Environment targetEnv) {
289         
290         /*
291          * Get JE attributes, operation and notification information
292          * from JEMBeanHelper. An application may choose to add functionality
293          * of its own when constructing the MBeanInfo.
294          */

295         
296         /* Attributes. */
297         List JavaDoc attributeList = jeHelper.getAttributeList(targetEnv);
298         MBeanAttributeInfo JavaDoc [] attributeInfo =
299             new MBeanAttributeInfo JavaDoc[attributeList.size()];
300         attributeList.toArray(attributeInfo);
301
302         /* Constructors. */
303         Constructor JavaDoc [] constructors = this.getClass().getConstructors();
304         MBeanConstructorInfo JavaDoc [] constructorInfo =
305             new MBeanConstructorInfo JavaDoc[constructors.length];
306         for (int i = 0; i < constructors.length; i++) {
307             constructorInfo[i] =
308                 new MBeanConstructorInfo JavaDoc(this.getClass().getName(),
309                                          constructors[i]);
310         }
311
312         /* Operations. */
313         List JavaDoc operationList = jeHelper.getOperationList(targetEnv);
314         MBeanOperationInfo JavaDoc [] operationInfo =
315             new MBeanOperationInfo JavaDoc[operationList.size()];
316         operationList.toArray(operationInfo);
317
318         /* Notifications. */
319         MBeanNotificationInfo JavaDoc [] notificationInfo =
320             jeHelper.getNotificationInfo(targetEnv);
321
322         /* Generate the MBean description. */
323         mbeanInfo = new MBeanInfo JavaDoc(this.getClass().getName(),
324                                   DESCRIPTION,
325                                   attributeInfo,
326                                   constructorInfo,
327                                   operationInfo,
328                                   notificationInfo);
329     }
330
331     /**
332      * This MBean has the policy of only accessing an environment when
333      * it has already been configured and opened by other
334      * application threads.
335      *
336      * @return a valid Environment or null if the environment is not open
337      */

338     protected Environment getEnvironmentIfOpen() {
339
340         return jeHelper.getEnvironmentIfOpen();
341     }
342
343     /**
344      * Be sure to close Environments when they are no longer used, because
345      * they pin down resources.
346      *
347      * @param targetEnv the open environment. May be null.
348      */

349     protected void closeEnvironment(Environment targetEnv)
350         throws MBeanException JavaDoc {
351
352         try {
353             if (targetEnv != null) {
354                 targetEnv.close();
355             }
356         } catch (DatabaseException e) {
357             throw new MBeanException JavaDoc(e);
358         }
359     }
360 }
361
Popular Tags