You can extend the WebSphere® Application Server administration system by supplying and registering new Java™ Management Extensions (JMX) MBeans (see JMX 1.x Specification for details) in one of the WebSphere processes.
MBeanDescriptor
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE MBean SYSTEM "MbeanDescriptor.dtd"> <MBean type="SampleStateMBean" aggregationHandlerClass="com.ibm.ws390.sample.SampleStateAggregationHandler" eventHandlerClass="com.ibm.ws390.sample.SampleStateEventHandler" invocationHandlerClass="com.ibm.ws390.sample.SampleStateInvocationHandler" stateObjectClass="com.ibm.ws390.sample.SampleState" version="6.0" platform="dynamicproxy" description="Sample State MBean for the documentation example."> <attribute description="The name of the MBean." getMethod="getMBeanName" name="mbeanName" type="java.lang.String" proxyInvokeType="unicall"/> <attribute description="The state of the MBean." name="state" getMethod="getState" setMethod="setState" type="java.lang.String" proxyInvokeType="multicall" proxySetterInvokeType="multicall"/> <operation description="Initialize the State MBean." impact="ACTION" name="initializeState" role="operation" targetObjectType="objectReference" type="void" proxyInvokeType="multicall"> <signature> <parameter description="The name of the MBean." name="mbeanName" type="java.lang.String"/> <parameter description="The initial state of the MBean." name="mbeanName" type="java.lang.String"/> </signature> </operation> <notification name="j2ee.state.starting" severity="6" log="false" description="This sample state MBean is in starting state."> <notificationType>j2ee.state.starting</notificationType> </notification> <notification name="j2ee.state.running" severity="6" log="false" description="This sample state MBean is in running state."> <notificationType>j2ee.state.running</notificationType> </notification> <notification name="j2ee.state.stopping" severity="6" log="false" description="This sample state MBean is in stopping state."> <notificationType>j2ee.state.stopping</notificationType> </notification> <notification name="j2ee.state.stopped" severity="6" log="false" description="This sample state MBean is in stopped state."> <notificationType>j2ee.state.stopped</notificationType> </notification> </MBean>
SampleState implementation
package com.ibm.ws390.sample;
import com.ibm.ejs.ras.Tr;
import com.ibm.ejs.ras.TraceComponent;
import java.io.Serializable;
import com.ibm.websphere.management.dynamicproxy.StateObject;
public class SampleState extends StateObject {
private static TraceComponent tc =
Tr.register(SampleState.class,"SampleState",null);
// Package protected STATE constants.
static final String STATE_STARTING = "j2ee.state.starting";
static final String STATE_RUNNING = "j2ee.state.running";
static final String STATE_STOPPING = "j2ee.state.stopping";
static final String STATE_STOPPED = "j2ee.state.stopped";
// Dynamicproxy State is initialized with STOPPED state.
private String state = STATE_STOPPED;
public SampleState() {
if (tc.isEntryEnabled()) Tr.entry(tc,"<init>");
// State is initialized during "state" initialization above,
// but can also be initialized here in the constructor as well.
/*
state = "WebSphere Application Server for z/OS ready for e-business";
*/
if (tc.isEntryEnabled()) Tr.exit(tc,"<init>");
}
public synchronized String getState() {
if (tc.isEntryEnabled()) Tr.entry(tc,"getState");
if (tc.isEntryEnabled()) Tr.exit(tc,"getState",state);
return state;
}
public synchronized void setState(String state) {
if (tc.isEntryEnabled()) Tr.entry(tc,"setState",state);
this.state = state;
if (tc.isEntryEnabled()) Tr.exit(tc,"setState");
}
public synchronized String getStateObjectInfo() {
return state;
}
}
SampleStateAggregationHandler implementation
package com.ibm.ws390.sample; import com.ibm.websphere.management.dynamicproxy.AggregationHandler; import com.ibm.websphere.management.dynamicproxy.StateObject; import com.ibm.ejs.ras.Tr; import com.ibm.ejs.ras.TraceComponent; public class SampleStateAggregationHandler implements AggregationHandler { private static TraceComponent tc = Tr.register(SampleStateAggregationHandler.class,"SampleState",null); /** * Return an aggregated result from a multicall Mbean operation which * compiles through all servant MBeans' results and returns a respective * single return value for an invoked method. * * @param methodName MBean method name * @param params MBean method parameters * @param signatures MBean method signatures * @param servantMBeanResults Result of each servant MBean instances * invoked by the dynamicproxy multicast * invocation. * Note: this value can be "null" OR can be * an array of "null"s in case return value * of the method is "void." Implementation * of this method MUST handle this case to * avoid a <code>NullPointerException</code>. * @param stateObject * MBean provider provided <code>StateObject</code> used by * dynamicproxy MBean in CR to manage its state. Note: this object * MAY BE null if "stateObjectClass" was not specified OR internal * error occurred during initialization of this dynamicproxy MBean. * Implmentation MUST properly handle "null" input. * * @return aggregated result as defined by MBean xml for specified * MBean operation. */ public Object aggregateResults(String methodName, Object[] params, String[] signatures, Object[] servantMBeanResults, StateObject stateObject) { if (tc.isEntryEnabled()) Tr.entry(tc,"aggregateResults",methodName); // As you can see from the MBeanDescriptor of SampleStateMBean, // it declares the following four methods: // 1. String getMBeanName() [proxyInvokeType == unicall] // 2. String getState() [proxyInvokeType == multicall] // 3. void setState(String) [proxyInvokeType == multicall] // 4. void initializeState() [proxyInvokeType == multicall] // // Looking at the above methods, only method that requires aggregation // is #2 getState method which is a multicall MBean operation AND // it returns a value that can be aggregated. // // In this example, we simply take each servants' getState MBean // request result and concatenate them into one long String that // displays each servants' state. if (methodName.equals("getState")) { StringBuffer stateBuf = new StringBuffer(); for (int i=0; i<servantMBeanResults.length; i++) { stateBuf.append("SERVANT #" + i + " state ==|" + servantMBeanResults[i] + "|== "); } return stateBuf.toString(); } // If we also had an example method which returns say an int, // getNumberOfMBeans(), it can take the similar approach // and to add each servants' getNumberOfMBeans() result together here. /* example added for non-existent method: int getNumberOfMBeans() else if (methodName.equals("getNumberOfMBeans")) { int aggregatedResult = 0; for (int i=0; i<servantMBeanResults.length; i++) { aggregatedResult += (int) servantMBeanResults[i]; } return aggregatedResult; } */ return methodName + " is NOT handled by " + getClass().getName() + "!"; } }
In this information ...Subtopics
Related reference
| IBM Redbooks, demos, education, and more(Index) |