/*- * 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. *

* 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. *

* The approach taken for accessing the environment is an application specific * choice. Some of the salient considerations are: *

*

* 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); } } }