![[z/OS]](../images/ngzos.gif)
Ejemplo: MBean SampleStateMBean
Utilice este ejemplo como orientación para el desarrollo de MBeans de usuario que sirvan para WebSphere Application Server en plataformas distribuidas y en la plataforma z/OS. El ejemplo utiliza todos los manejadores especiales para mostrar las responsabilidades y posibilidades del proxy de MBeans dinámico. El ejemplo SampleStateMBean hace un seguimiento de su estado y genera sucesos de cambio de estado al invocar métodos setter.
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="El nombre del MBean."
name="mbeanName" type="java.lang.String"/>
<parameter description="El estado inicial del 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>
Implementación de SampleState
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;
}
}
Implementación de SampleStateAggregationHandler
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() + "!";
}
}