Extension du système d'administration WebSphere Application Server avec des MBeans personnalisés
Vous pouvez étendre le système d'administration WebSphere Application Server en fournissant et en enregistrant de nouveaux Mbeans JMX (Java™ Management Extensions) (pour plus de détails, voir la spécification JMX 1.x) dans l'un des processus WebSphere.
Pourquoi et quand exécuter cette tâche
Les MBeans JMX représentent l'interface de gestion pour une partie spécifique de la logique. Toutes les ressources gérées figurant dans l'infrastructure du produit standard, sont représentées sous la forme de MBeans JMX. Il existe différentes façons de créer vos propres MBeans et de les enregistrer auprès du MBeanServer JMX s'exécutant dans n'importe quel processus WebSphere. Pour plus d'informations, voir la documentation sur l'API (Application Programming Interface) Java MBean. Dans le centre de documentation, cliquez sur .
Procédure
Résultats
Quelle que soit l'approche utilisée pour créer et enregistrer votre MBean, vous devez configurer les droits d'accès de sécurité Java 2 pour le code de votre nouveau MBean. AdminService et MBeanServer de WebSphere sont étroitement protégés à l'aide des droits d'accès de sécurité Java 2 et, si vous n'octroyez pas explicitement les droits d'accès à votre code, des exceptions de sécurité sont générées lorsque vous essayez d'appeler les méthodes de ces classes. Si vous fournissez votre MBean dans le cadre de votre application, vous pouvez définir les droits d'accès dans le fichier was.policy que vous fournissez avec les métadonnées de votre application. Si vous utilisez une interface CustomService ou un autre code qui n'est pas fourni en tant qu'application, vous pouvez éditer le fichier library.policy dans la configuration du noeud, ou encore le fichier server.policy situé dans le répertoire properties pour une installation spécifique.
![[z/OS]](../images/ngzos.gif)
Exemple : Le MBean SampleStateMBean
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,
// 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]
//
// From these methods, the only one 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() + "!";
}
}