Estendendo o Sistema Administrativo do WebSphere Application Server com MBeans Customizados
É possível estender o sistema de administração do WebSphere Application Server fornecendo e registrando novos MBeans Java™ Management Extensions (JMX) (consulte a Especificação JMX 1.x para obter detalhes) em um dos processos do WebSphere.
Sobre Esta Tarefa
Os MBeans JMX representam a interface de gerenciamento de uma determinada parte da lógica. Todos os recursos gerenciados na infraestrutura padrão do produto são representados como MBeans JMX. Existem várias maneiras de criar seus próprios MBeans e registrá-los no JMX MBeanServer em execução em qualquer processo do WebSphere. Para obter informações adicionais, consulte a documentação da application programming interface (API) Java de MBean. Neste centro de informações, clique em .
Procedimento
Resultados
Independentemente da abordagem utilizada para criar e registrar seu MBean, é necessário configurar 2 permissões de segurança Java apropriadas para seu novo código de MBean. O AdminService e o MBeanServer do WebSphere são totalmente protegidos utilizando as permissões de segurança Java 2 e se você não conceder explicitamente suas permissões de código base, exceções de segurança serão emitidas ao tentar chamar métodos dessas classes. Se você estiver fornecendo o MBean como parte do aplicativo, é possível definir as permissões no arquivo was.policy fornecido como parte dos metadados do aplicativo. Se estiver utilizando uma interface CustomService ou outro código que não seja fornecido como um aplicativo, é possível editar o arquivo library.policy na configuração do nó ou até mesmo o arquivo server.policy no diretório properties de uma instalação específica.
![[z/OS]](../images/ngzos.gif)
Exemplo: O 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="Este MBean de estado de amostra está no estado parando.">
<notificationType>j2ee.state.stopping</notificationType>
</notification>
<notification name="j2ee.state.stopped" severity="6" log="false"
description="Este MBean de estado de amostra está no estado parado.">
<notificationType>j2ee.state.stopped</notificationType>
</notification>
</MBean>
Implementação 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);
// Constantes STATE protegidas por pacote.
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";
// O Estado Dynamicproxy está inicializado com o estado STOPPED.
private String state = STATE_STOPPED;
public SampleState() {
if (tc.isEntryEnabled()) Tr.entry(tc,"<init>");
// O estado é inicializado durante a inicialização de "estado",
// mas também pode ser inicializado aqui no construtor.
/*
state = "WebSphere Application Server para z/OS pronto para 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;
}
}
Implementação 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);
/**
* Retornar um resultado agregado de uma operação Mbean de várias chamadas que
* compila através de todos os resultados de MBeans do servant e retorna um
* único valor de retorno respectivo para um método chamado.
*
* @param methodName Nome do método MBean
* @param params Parâmetros do método MBean
* @param signatures Assinaturas do método MBean
* @param servantMBeanResults Resultado de cada instância de MBean do servant
* chamada pela chamada multicast
* dynamicproxy.
* Nota: esse valor pode ser "null" OU uma
* matriz de "nulls" no caso do valor de retorno do
* método ser "void." Implementação
* deste método DEVE tratar esse caso para
* evitar um <code>NullPointerException</code>.
* @param stateObject
* O provedor MBean forneceu <code>StateObject</code> utilizado pelo
* MBean dynamicproxy no CR para gerenciar seu estado. Nota: esse objeto
* PODERÁ SER nulo se "stateObjectClass" não foi especificado OU se ocorreu
* um erro interno durante a inicialização do MBean dynamicproxy.
* A implementação DEVE tratar adequadamente a entrada "null".
*
* Resultado agregado @return conforme definido pelo xml do MBean para a operação
* de MBean especificada.
*/
public Object aggregateResults(String methodName,
Object[] params,
String[] signatures,
Object[] servantMBeanResults,
StateObject stateObject) {
if (tc.isEntryEnabled()) Tr.entry(tc,"aggregateResults",methodName);
// Como você pode ver a partir do MBeanDescriptor do SampleStateMBean,
// ele declara os quatro métodos a seguir:
// 1. String getMBeanName() [proxyInvokeType == unicall]
// 2. String getState() [proxyInvokeType == multicall]
// 3. void setState(String) [proxyInvokeType == multicall]
// 4. void initializeState() [proxyInvokeType == multicall]
//
// A partir deste métodos, o único que requer agregação
// é o método #2 getState que é uma operação MBean de várias chamadas E
// que retorna um valor que pode ser agregado.
//
// Neste exemplo, nós simplesmente obtemos o resultado de pedidos do MBean getState
// de cada servant e os concatenamos em uma Cadeia longa que
// exibe o estado de cada servant.
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();
}
// Se também tivermos um método de exemplo que retorna um int,
// getNumberOfMBeans(), ele poderá obter a abordagem similar
// e adicionar o resultado getNumberOfMBeans() da cada servant aqui.
/* Exemplo adicionado para método não existente: 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() + "!";
}
}