1
2
3
4
5
6
7
8
9
10 package org.archive.util;
11
12 import java.lang.reflect.Constructor;
13 import java.util.List;
14
15 import javax.management.Attribute;
16 import javax.management.AttributeList;
17 import javax.management.AttributeNotFoundException;
18 import javax.management.DynamicMBean;
19 import javax.management.InvalidAttributeValueException;
20 import javax.management.MBeanAttributeInfo;
21 import javax.management.MBeanConstructorInfo;
22 import javax.management.MBeanException;
23 import javax.management.MBeanInfo;
24 import javax.management.MBeanNotificationInfo;
25 import javax.management.MBeanOperationInfo;
26
27 import com.sleepycat.je.DatabaseException;
28 import com.sleepycat.je.Environment;
29
30 /***
31 * JEApplicationMBean is an example of how a JE application can incorporate JE
32 * monitoring into its existing MBean. It may be installed as is, or used as a
33 * starting point for building a MBean which includes JE support.
34 * <p>
35 * JE management is divided between the JEApplicationMBean class and
36 * JEMBeanHelper class. JEApplicationMBean contains an instance of
37 * JEMBeanHelper, which knows about JE attributes, operations and
38 * notifications. JEApplicationMBean itself has the responsibility of
39 * configuring, opening and closing the JE environment along with any other
40 * resources used by the application, and maintains a
41 * com.sleepycat.je.Environment handle.
42 * <p>
43 * The approach taken for accessing the environment is an application specific
44 * choice. Some of the salient considerations are:
45 * <ul>
46 * <li>Applications may open one or many Environment objects per process
47 * against a given environment.</li>
48 *
49 * <li>All Environment handles reference the same underlying JE environment
50 * implementation object.</li>
51
52 * <li> The first Environment object instantiated in the process does the real
53 * work of configuring and opening the environment. Follow-on instantiations of
54 * Environment merely increment a reference count. Likewise,
55 * Environment.close() only does real work when it's called by the last
56 * Environment object in the process. </li>
57 * </ul>
58 * <p>
59 * Another MBean approach for environment access can be seen in
60 * com.sleepycat.je.jmx.JEMonitor. That MBean does not take responsibility for
61 * opening and closing environments, and can only operate against already-open
62 * environments.
63 * <p>This bean was copied from bdb je 2.0 source and modified so could pass
64 * in and monitor an environment created externally. Also added toString
65 * versions of the locks and stats calls since the objects don't seem to
66 * make it over the RMI divide (Not serializable. St.Ack
67 */
68
69 public class JEApplicationMBean implements DynamicMBean {
70
71 private static final String DESCRIPTION =
72 "A MBean for an application which uses JE. Provides open and close " +
73 "operations which configure and open a JE environment as part of the "+
74 "applications's resources. Also supports general JE monitoring.";
75
76 private MBeanInfo mbeanInfo;
77 private JEMBeanHelper jeHelper;
78 private Environment targetEnv;
79
80 /***
81 * This MBean provides an open operation to open the JE environment.
82 */
83 public static final String OP_OPEN = "openJE";
84
85 /***
86 * This MBean provides a close operation to release the JE environment.
87 * Note that environments must be closed to release resources.
88 */
89 public static final String OP_CLOSE = "closeJE";
90
91 /***
92 * Instantiate a JEApplicationMBean
93 *
94 * @param env Environment to use. Externally managed.
95 * @throws DatabaseException
96 */
97 public JEApplicationMBean(Environment env) throws DatabaseException {
98 this.targetEnv = env;
99 jeHelper = new JEMBeanHelper(env.getConfig(), env.getHome(), true);
100 resetMBeanInfo();
101 }
102
103 /***
104 * @see DynamicMBean#getAttribute
105 */
106 public Object getAttribute(String attributeName)
107 throws AttributeNotFoundException,
108 MBeanException {
109
110 return jeHelper.getAttribute(targetEnv, attributeName);
111 }
112
113 /***
114 * @see DynamicMBean#setAttribute
115 */
116 public void setAttribute(Attribute attribute)
117 throws AttributeNotFoundException,
118 InvalidAttributeValueException {
119
120 jeHelper.setAttribute(targetEnv, attribute);
121 }
122
123 /***
124 * @see DynamicMBean#getAttributes
125 */
126 public AttributeList getAttributes(String[] attributes) {
127
128
129 if (attributes == null) {
130 throw new IllegalArgumentException("Attributes cannot be null");
131 }
132
133
134 AttributeList results = new AttributeList();
135 for (int i = 0; i < attributes.length; i++) {
136 try {
137 String name = attributes[i];
138 Object value = jeHelper.getAttribute(targetEnv, name);
139 results.add(new Attribute(name, value));
140 } catch (Exception e) {
141 e.printStackTrace();
142 }
143 }
144 return results;
145 }
146
147 /***
148 * @see DynamicMBean#setAttributes
149 */
150 public AttributeList setAttributes(AttributeList attributes) {
151
152
153 if (attributes == null) {
154 throw new IllegalArgumentException("attribute list can't be null");
155 }
156
157
158 AttributeList results = new AttributeList();
159 for (int i = 0; i < attributes.size(); i++) {
160 Attribute attr = (Attribute) attributes.get(i);
161 try {
162
163 jeHelper.setAttribute(targetEnv, attr);
164
165
166
167
168
169
170
171
172 String name = attr.getName();
173 Object newValue = jeHelper.getAttribute(targetEnv, name);
174 results.add(new Attribute(name, newValue));
175 } catch (Exception e) {
176 e.printStackTrace();
177 }
178 }
179 return results;
180 }
181
182 /***
183 * @see DynamicMBean#invoke
184 */
185 public Object invoke(String actionName,
186 Object[] params,
187 String[] signature)
188 throws MBeanException {
189
190 Object result = null;
191
192 if (actionName == null) {
193 throw new IllegalArgumentException("actionName cannot be null");
194 }
195
196
197
198
199
200
201
202
203
204
205 result = jeHelper.invoke(targetEnv, actionName, params, signature);
206
207
208 return result;
209 }
210
211 /***
212 * @see DynamicMBean#getMBeanInfo
213 */
214 public MBeanInfo getMBeanInfo() {
215 return mbeanInfo;
216 }
217
218 /***
219 * Create the available management interface for this environment.
220 * The attributes and operations available vary according to
221 * environment configuration.
222 *
223 */
224 private synchronized void resetMBeanInfo() {
225
226
227
228
229
230
231
232
233 List<MBeanAttributeInfo> attributeList = jeHelper.getAttributeList(targetEnv);
234 MBeanAttributeInfo [] attributeInfo =
235 new MBeanAttributeInfo[attributeList.size()];
236 attributeList.toArray(attributeInfo);
237
238
239 Constructor [] constructors = this.getClass().getConstructors();
240 MBeanConstructorInfo [] constructorInfo =
241 new MBeanConstructorInfo[constructors.length];
242 for (int i = 0; i < constructors.length; i++) {
243 constructorInfo[i] =
244 new MBeanConstructorInfo(this.getClass().getName(),
245 constructors[i]);
246 }
247
248
249
250
251
252
253
254 List<MBeanOperationInfo> operationList = jeHelper.getOperationList(targetEnv);
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273 MBeanOperationInfo [] operationInfo =
274 new MBeanOperationInfo[operationList.size()];
275 operationList.toArray(operationInfo);
276
277
278 MBeanNotificationInfo [] notificationInfo =
279 jeHelper.getNotificationInfo(targetEnv);
280
281
282 mbeanInfo = new MBeanInfo(this.getClass().getName(),
283 DESCRIPTION,
284 attributeInfo,
285 constructorInfo,
286 operationInfo,
287 notificationInfo);
288 }
289
290 /***
291 * Open a JE environment using the configuration specified through
292 * MBean attributes and recorded within the JEMBeanHelper.
293 */
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313 /***
314 * Release the environment handle contained within the MBean to properly
315 * release resources.
316 */
317
318
319
320
321
322
323
324
325
326
327
328
329
330 }