Libérez la puissance de Gogo Shell

// The english version of this article can be found here: Unleash the power of Gogo Shell.

Gogo Shell ouvre d’énorme possibilités mais certains obstacles limite la plein expression de son potentiel. Voyons au fil de ce billet comment lever ces barrières.

Quelques rappels : utilisation usuelle de Gogo Shell

Apache Felix Gogo Shell est un interpréteur de commandes en mode interactif qui permet d’interagir avec un conteneur OSGi.

Gogo Shell est accessible simplement via telnet :

$ telnet localhost 11311
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
____________________________
Welcome to Apache Felix Gogo

g!

Attention ! À partir de la version 7.1 de Liferay, l’accès à Gogo Shell via telnet n’est plus activé par défaut. Pour l’activer, il faut ajouter la ligne suivante dans le fichier portal-ext.properties :

 
module.framework.properties.osgi.console=localhost:11311

Une fois que la connexion telnet est ouverte, les commandes Gogo Shell peuvent être enchaînées à loisir :

g! lb | grep search 
  438|Active     |   10|Liferay Portal Search Elasticsearch (2.1.8)
true
g! 

Au delà des commandes propres à la gestion du conteneur OSGi, Gogo Shell propose un langage assez complet, doté notamment des structures de contrôle standards comme la boucle ou la conditionnelle :

g! each [1 2 3] { echo -- $it --  }
-- 1 --
-- 2 --
-- 3 --
null
null
null

De plus Gogo Shell permet d’appeler n’importe quelle méthode de n’importe quel service déployé au sein du conteneur OSGi :

g! ((($.context getService ($.context getServiceReference com.liferay.portal.kernel.service.UserLocalService)) getUserByScreenName 20116 'test') getFullName)
Test Test

S’affranchir du mode interactif

Dès lors que l’on souhaite utiliser Gogo Shell à des fins d’automatisation des tâches, par exemple au sein d’un script bash, la connexion telnet pose des difficultés.

Bonne nouvelle, comme indiqué dans la documentation officielle Liferay, l’outil de développement Blade peut être utilisé pour surmonter cet obstacle :

$ blade sh 'lb | grep search'
lb | grep search
  438|Active     |   10|Liferay Portal Search Elasticsearch (2.1.8)
true

Seulement voilà, sur un environnement de production, l’utilisation de Blade est souvent impossible. En effet, au moment où ces lignes sont écrites, la procédure d’installation de Blade n’est pas adaptée à un contexte de production. De plus les équipes d’exploitation apprécient généralement peu l’installation d’un outil dédié au développement sur un serveur de production.

Heureusement, il existe d’autre moyen d’automatiser un session telnet. Un script Expect par exemple, remplit très bien ce rôle :

#!/usr/bin/expect -f
log_user 0
spawn telnet localhost 11311
expect "g!"
send -- "lb | grep search\n"
expect "g!"
send_user $expect_out(buffer)

myscript.sh

Il suffit ensuite d'exécuter le script :

$ ./myscript.sh
lb | grep search
  438|Active     |   10|Liferay Portal Search Elasticsearch (2.1.8)
true

L’interpréteur Expect est une commande éprouvée (elle existe depuis presque 30 ans) qui peut être installée via les outils d’installation standard des distributions Linux.

Pour une distribution supportant APT :

sudo apt-get install expect

Pour une distribution supportant YUM :

sudo yum install expect

Au delà d’OSGi : Groovy à la rescousse !

En terme d’exécution de composants du portail, Gogo Shell se cantonne aux services exposés au niveau du conteneur OSGi. Hors, le portail Liferay propose de nombreuses classes Java très intéressantes qui ne sont pas exposées en OSGi.

Mais heureusement rien n’est jamais complètement impossible avec Liferay !

En effet, comme expliqué par Piotr Swiniarski dans un billet publié sur le blog de Mimacom, il est possible d’invoquer le service d'exécution de script Groovy de Liferay depuis Gogo Shell.

Ainsi, il est possible d’invoquer n’importe quelle classe du portail. Par exemple, en utilisant ce principe, on peut changer le niveau de log d’un logger particulier via un script Expect comme celui-ci :

#!/usr/bin/expect -f
log_user 0
spawn telnet localhost 11311
expect "g!"

set groovy_script " \
	import static com.liferay.util.log4j.Log4JUtil.setLevel; \
	setLevel('com.company.mylogger','DEBUG',true); \
";

send -- " \
($.context getService (( \
  $.context getServiceReferences \
    com.liferay.portal.kernel.scripting.ScriptingExecutor \
    \"(scripting.language=groovy)\" \
) 0)) eval null null null \"$groovy_script\" \
\n"

expect "g!"
send_user $expect_out(buffer)

setloglevel.sh

Grâce à cette brillante idée de Piotr, les possibilités deviennent infinies.

D’autre part cela permet d’utiliser un langage familier des développeurs Java, bien plus pratique à l’usage que le langage de Gogo Shell.

Passer au niveau supérieur

À ce stade les possibilités sont immenses, mais avant que votre script soit prêt à partir en production en toute sérénité, il y a encore pas mal de points à traiter :

  • gérer tous les cas d’erreur (échec de connexion telnet, exception dans le code Groovy, etc),

  • gérer le statut de retour du script,

  • gérer les éventuels dépassements de buffer de l'interpréteur Expect,

  • etc.

Mais n’ayez pas peur, vous n’aurez pas à gérer cela vous-même, car le dépôt slemarchand/liferay-gogo-scripts sur GitHub contient plus d’une quinzaine de scripts complets que vous pourrez utiliser directement, ou sur lesquels vous pourrez vous baser pour réaliser vos propres scripts.

Vous trouverez dans ce dépôt de sources, entre autres, les scripts suivants :

  • gogo-groovy-script qui vous permettra d'exécuter directement un script groovy à partir d’un fichier,

  • gogo-bundle-get-state qui vous retourne l'état d’un bundle OSGi particulier,

  • gogo-bundle-start et gogo-bundle-stop qui respectivement démarre et arrête un bundle OSGi,

  • gogo-set-log-level qui modifie le niveau de log d’un logger particulier,

  • gogo-reindex-all-search-indexes qui re-construit tous les index de recherche,

  • et gogo-clear-all-caches qui vide tous les caches du serveur.

Quelque chose à partager ?

Avez-vous déjà eu rencontré ces problématiques autour de Gogo Shell ? Comment de votre côté les avez-vous résolus ? Avez-vous rencontré d’autres problématiques connexes ?

N’hésitez pas à partagez vos expériences dans les commentaires de ce billet pour apporter votre pierre à l’édifice de la communauté Liferay !

 

Sébastien Le Marchand
Consultant Technique indépendant à Paris