mirror of
https://github.com/berkeleydb/je.git
synced 2024-11-15 01:46:24 +00:00
329 lines
11 KiB
Java
329 lines
11 KiB
Java
/*-
|
||
* Copyright (C) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
|
||
*
|
||
* This file was distributed by Oracle as part of a version of Oracle Berkeley
|
||
* DB Java Edition made available at:
|
||
*
|
||
* http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
|
||
*
|
||
* Please see the LICENSE file included in the top-level directory of the
|
||
* appropriate version of Oracle Berkeley DB Java Edition for a copy of the
|
||
* license and additional information.
|
||
*/
|
||
|
||
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);
|
||
}
|
||
}
|
||
}
|