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