Génération dynamique de fichiers WSDL avec Perl
Dans le cadre de mon travail, je devais rendre accesible via des Web Services un ensemble de modules écrits en Perl.
Pour que les interfaces d’un module soient accessible via SOAP, il faut les décrire à l’aide du langage WSDL.
Le format WSDL est basé sur XML, il est relativement difficile de le comprendre et encore plus de l’écrire à la main.
C’est pour cette raison que la plupart des langages de programmation proposent des outils de géneration automatique.
Le principale problème que l’ont peut rencontrer avec ce genre d’outils est le manque de contrôle.
Pour palier à ce problème, Perl propose une solution remarquable : décrire l’interface à l’aide de commentaires directement dans le code.
Effectivement à l’aide du module Pod::WSDL, il est possible d’extraire les informations nécessaires pour créer le fichier de déscription d’interface.
Par exemple :
=begin WSDL
_IN $bar $string description du paramètre
_RETURN $string
_FAULT Error::Simple Le type d'éxception déclancher en cas d'erreur
_DOC description rapide du fonctionnement de ma fonction
=cut
sub foo ($) {
my $bar = shift;
return $bar;
}
Ensuite, il ne reste plus qu’à charger le module précédant et extraire les informations pour produire le fichier WSDL, à l’aide du bout de code suivant:
use Pod::WSDL;
my $pod = new Pod::WSDL(
source => 'My::Server',
location => 'http://localhost/My/Server',
pretty => 1,
withDocumentation => 1);
print $pod->WSDL;
Celui-ci vous affiche le fichier WSDL, directement sur la sortie standard.
Les fichiers produits par Pod::WSDL sont conformes aux spécifications et fonctionnent parfaitement.
Je les ai testé avec SOAP::Lite et le framework Apache Axis.
Nous avons une jolie solution pour créer des fichiers WSDL directement lors de l’installation de nos modules.
Néanmoins j’ai voulu pousser le concept de génération dynamique un peu plus loin.
Tout simplement parce que mon interface SOAP est séparée des modules qu’elle met à disposition (dans deux paquets différents).
Dans Web Services, il y a la notion de Web. J’ai donc mis à contribution le framework Mason, qui est un outil de template permetant de faire des sites web dynamiques en Perl.
Celui-ci dispose deux fonctionnalités intéressantes :
- un système de cache ;
- un système de gestion de page non disponible.
Le système de gestion de page non disponbile, permet de créer des pages web dynamiquement en fonction de l’url demander.
Le fichier dhandler suivant permet de créer dynamiquement un fichier WSDL en fonction du nom du module Perl:
< %once>
use Pod::WSDL;
use strict;
< %once>
< %init>
my $arg = $m->dhandler_arg;
$arg =~ s/\.wsdl//;
my $pod;
eval {
$pod = new Pod::WSDL(
source => $arg,
location => 'http://localhost/soapEndPoint',
pretty => 1,
withDocumentation => 0
);
};
if ($@) {
return 404;
}
$m->out($pod->WSDL);
< /%init>
Par exemple pour récupèrer le fichier WSDL pour le module Test, il suffit d’aller sur l’url : http://localhost/Test.wsdl.
L’opèration de géneration est rélativement rapide, mais dans le cas d’un service fortement solicité, il faut mettre en place un système de cache, comme celui décrit dans la documentation de Mason : DATA CACHING
Voilà