Les MBeans WebLogic faciles avec Groovy

GroovyMBean

Groovy, langage dynamique à succès s’exécutant sur la JVM, comporte un petit composant très simple mais très puissant pour accéder aux MBeans : GroovyMBean
http://groovy.codehaus.org/Groovy+and+JMX

En résumé, une fois une référence au serveur JMX (directe ou via une remote connection) obtenue, il suffit de créer un GroovyMBean à l’aide de l’ObjectName du MBean à manipuler …

def groovyMBean = new GroovyMBean(server, mBeanObjectName) 

… pour pouvoir accéder aux attributs JMX comme de banals attributs d’objet :

groovyMBean.myAttribute

… ou mieux, appeler une opération JMX aussi simplement qu’une méthode :

groovyMBean.myOperation(param1,param2)

C’est ici les capacités dynamiques du langage Groovy qui permettent à GroovyMBean de se comporter comme une sorte de proxy universel et cacher la lourdeur des apis JMX, apis qui ressemblent fortement à de la réflection.

Les MBeans de WebLogic

Oui mais voilà, mon expérience personnelle étant assez centrée sur WebLogic, je trouvais que GroovyMBean n’était pas encore assez simple d’utilisation 😉

En effet, les MBeans de WebLogic sont organisés de manière hiérarchique : pour naviguer dans cette hiérarchie, les MBeans de WebLogic disposent d’attributs de type ObjectName ou ObjectName[] référençant des MBeans enfants.

Ainsi, à partir de l’ObjectName d’un MBean racine, il est possible d’accéder à tous les MBeans de la hiérarchie sans avoir à construire un ObjectName compliqué ou le rechercher avec les apis JMX.

C’est grâce à cela que WLST (WebLogic Scripting Tools), l’outils de scripting basé sur JPython de WebLogic, peut exposer la configuration ou l’état des ressources d’un domaine WebLogic sous la forme d’une arborescence de fichier :

#wlst
wls:/offline> connect('weblogic','weblogic','t3://localhost:7001')
Connecting to t3://localhost:7001 with userid weblogic (...)
wls:/base_domain/serverConfig> cd('JDBCSystemResources')
wls:/base_domain/serverConfig/JDBCSystemResources> ls()
dr--   cgDataSource
dr--   cgDataSource-nonXA
dr--   samplesDataSource

wls:/base_domain/serverConfig/JDBCSystemResources> cd('cgDataSource/JDBCResource/cgDataSource/JDBCDriverParams/cgDataSource')
wls:/base_domain/serverConfig/JDBCSystemResources/cgDataSource/JDBCResource/cgDataSource/JDBCDriverParams/cgDataSource> ls()
dr--   Properties

-r--   DriverName                                   com.pointbase.jdbc.jdbcUniversalDriver
-r--   Password                                     ******
-r--   PasswordEncrypted                            ******
-r--   Url                                          jdbc:pointbase:server://localhost:9093/weblogic_eval;new
-r--   UseXaDataSourceInterface                     true

-r-x   isSet                                        Boolean : String(propertyName)
-r-x   unSet                                        Void : String(propertyName)

Si on revient au Groovy et à GroovyMBean, cela signifie qu’il faut ré-instancier à chaque niveau de la hiérarchie une nouvelle instance à partir des ObjectName récupérés :

def server = ...
def domain = new GroovyMBean(server,
  'com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean')
def domainConfig = new GroovyMBean(server,domain.DomainConfiguration)
domainConfig.JDBCSystemResources.each { moduleObjectName ->
    def module = new GroovyMBean(server, moduleObjectName)
    // ...
}

A Groovier Mbean

Ce qu’il me manquait donc dans GroovyMBean c’est juste la capacité de transformer automatiquement les valeurs de type ObjectName en GroovyMBean.
J’ai donc surchargé légèrement GroovyMBean pour créer un nouveau composant que j’ai appelé GroovierMBean : celui-ci convertit à la volée les ObjectName pour que le script appelant récupère à la place un nouveau GroovierMBean directement exploitable pour continuer la navigation.

Associé à une autre petite classe utilitaire (WebLoMBean) pour faciliter l’accès remote au serveur JMX weblogic, il suffit maintenant que de quelques lignes pour, par exemple, vérifier que toutes les queues JMS d’un domaine ont une queue d’erreur configurée :

def domain = fr.ippon.groovy.util.WebLoMBean.getDomainMBean('t3://localhost:7001','weblogic','weblogic');

domain.DomainConfiguration.JMSSystemResources.each { module ->
  module.JMSResource.Queues.each { queue ->
    if(!queue.Name.endsWith("_error")) {
      if(queue.DeliveryFailureParams.ErrorDestination == null) {
        println "La queue ${queue.Name} n'a pas de queue d'erreur"
      }
    }
  }
}

Vous aurez remarqué qu’aucune référence à GroovierMBean n’apparaît dans cet exemple : en effet, une fois récupéré l’instance
pointant sur le MBean racine du MBeanServer DomainRuntime du domaine WebLogic ( via l’appel à WebLoMBean ) il n’est ici plus nécessaire d’en réinstancier explicitement, pourtant la plupart des objets manipulés par le script sont des GroovierMBean.
Pour des besoins plus compliqués il sera parfois plus simple de rechercher les mbeans de manière classique en interrogeant le serveur JMX puis d’utiliser explicitement GroovierMBean pour accéder aux MBeans dépendants

J’espère que cette petite présentation permettra à ceux que la complexité de JMX rebutait de se lancer dans la manipulation des mbeans et peut-être par la même occasion de découvrir les possibilités du langage Groovy.

Ressources :

Vous trouverez attachées à cette page un zip contenant l’environnement nécessaire pour exécuter le script ci-dessus (nécessite une install de Ant, de Groovy et de WebLogic)

Tweet about this on TwitterShare on FacebookGoogle+Share on LinkedIn

3 réflexions au sujet de « Les MBeans WebLogic faciles avec Groovy »

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *


*