% $Id: index.tex,v 1.2 2003/11/03 13:56:09 bortzmeyer Exp $ % Mise au point %\documentclass[a4,landscape,article]{seminar} %\documentclass[a4,landscape,article,slidesonly]{seminar} % Impression réelle \documentclass[a4,landscape,slidesonly]{seminar} %%%%%%%%%% \usepackage[latin1]{inputenc} \usepackage{fancybox} \usepackage[slides]{afnic} \usepackage[french, english]{babel} \newcommand{\ws}{\foreign{Web Services} } \newcommand{\uws}{\foreign{Web Service} } \newpagestyle{MH}% {Les \ws (JRES 2003)\hfil\thepage} {AFNIC\hfil{}Stéphane Bortzmeyer} \slidepagestyle{MH} \epsfslidesize \pagestyle{empty} \title{Les \ws} \author{Stéphane Bortzmeyer \\ \url{}} \date{Novembre 2003} \begin{document} \begin{slide} %\includegraphics[scale=0.38]{logo_NB.eps} \maketitle \addtocounter{slide}{-1} \slidepagestyle{empty} \end{slide} \begin{slide} \addtocounter{slide}{-1} Ce document est distribué sous les termes de la GNU Free Documentation License \url{http://www.gnu.org/licenses/licenses.html#FDL}. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. \end{slide} \begin{slide} \heading{Pourquoi utiliser le réseau} \begin{itemize} \item C'est l'autre machine qui a les données \item C'est l'autre machine qui va vite \item C'est l'autre machine qui a les bons logiciels \end{itemize} \end{slide} \begin{slide} \heading{Avant les \ws, les bricolages} \begin{itemize} \item On copiait les données et les logiciels (cohérence), \item On analysait les pages Web (\foreign{Welcome to Hell}), \item On formatait en texte puis on re-analysait (whois...). \end{itemize} \end{slide} \begin{slide} \heading{Programmation réseau sérieuse} \begin{itemize} \item On faisait tout à la main (définir un protocole, peut-être avec BEEP, écrire les clients et les serveurs) \item On avait des solutions spécifiques à un langage (RMI) \item Corba \url{http://www.corba.org/} \item ONC-RPC \end{itemize} \end{slide} \begin{slide} \heading{Les \ws arrivent} \url{http://www.w3.org/2002/ws/} Ils s'appuient sur le succès du Web : \begin{itemize} \item Disponibilité de HTTP, \item Web, donc bon, \item Et on passe les coupe-feux ! \end{itemize} Voir quand même \rfc{3205}. \end{slide} \begin{slide} \heading{Les \ws spécifient~:} \begin{itemize} \item Un encodage (toujours XML), \item Un transport (souvent HTTP), \item Une organisation des requêtes et réponses (RPC, par exemple). \end{itemize} \end{slide} \begin{slide} \heading{XML-RPC, le plus simple} \url{http://www.xml-rpc.com} Principe : la bibliothèque client encode les paramètres en XML et la bibliothèque serveur les décode. Le programmeur ne voit \textbf{jamais} de XML. On ne fait que des appels de procédure. Transport en HTTP seulement. Bibliothèques pour tous : Perl, C, Python, Ruby, Java, VisualBasic/.NET, PHP et même Emacs-Lisp. \end{slide} \begin{slide} \heading{XML-RPC, exemple Java} \begin{info} // server has been created above Vector params = new Vector(); params.addElement(new Integer(5)); params.addElement(new Integer(3)); // Call the server, and get our result. Hashtable result = (Hashtable) server.execute("sample.sumAndDifference", params); // We cannot use the procedure name directly (a limit of Java) int sum = ((Integer) result.get("sum")).intValue(); int difference = ((Integer) result.get("difference")).intValue(); \end{info} \end{slide} \begin{slide} \heading{XML-RPC, exemple Python} \begin{info} server = xmlrpclib.Server ('http://whois.eureg.org:8080/RPC2') # Call the server, and get our result. result = server.sample.sumAndDifference(3, 5); sum = result["sum"] difference = result["difference"] \end{info} \end{slide} \begin{slide} \heading{Exemples : Meerkat} Un service d'informations en ligne \url{http://www.oreillynet.com/pub/a/rss/2000/11/14/meerkat_xmlrpc.html}, accessible en XML-RPC. \begin{info} send($msg); $value = $response->value(); # And convert it to a PHP data structure $categories = xmlrpc_decode($value); # Iterate over the results, printing each category's title while( list($k, $v) = each( $categories ) ) { print $v['title'] . "
\n"; } ?> \end{info} \end{slide} \begin{slide} \heading{Exemples : Adam's Names} Une interface d'accès au registre : \url{http://www.adamsnames.tc/api/xmlrpc.html} Permet par exemple un whois moderne : \begin{info} my $rpc = Frontier::Client->new( url => 'http://www.adamsnames.tc/api/xmlrpc' ); my $status = $rpc->call('domquery', 'xmlrpcdemo.tc'); my $dumper = Data::Dumper->new([ $status ])->Terse(1)->Indent(1); my $txt = $dumper->Dump; \end{info} \end{slide} \begin{slide} \heading{XML-RPC, détails} Types de paramètres : \begin{itemize} \item entiers, dates, booléens, chaines \item \foreign{structs} (tableaux associatifs) \item tableaux \end{itemize} Les erreurs sont signalées par des exceptions. \end{slide} \begin{slide} \heading{XML-RPC, le serveur} Avec le ``registry'' de XML-RPC (pour l'introspection). \begin{info} self.registry.add_method('registry.queryDomain', self.domquery, [[STRUCT, STRING, STRUCT]]) ... def domquery (self, domain, credentials): """Queries the registry for a domain's attributes""" if credentials.has_key('name'): raise Unauthorized self.cursor.execute(""" SELECT name, ... def call (self, methodName, params): """Use our registry to find and call the appropriate method.""" try: return self.registry.dispatch_call(methodName, params) except Unauthorized: raise xmlrpclib.Fault(403, 'Unauthorized') \end{info} \end{slide} domquery est une procédure normale, sans aucune connaissance de XML-RPC (par exemple, elle lève des exceptions normales). call connait le protocole et lève donc des exceptions spécifiques. \begin{slide} \heading{XML-RPC, sur le câble} Uniquement si vous voulez écrire une bibliothèque \begin{info} POST /RPC2 HTTP/1.0 User-Agent: Frontier/5.1.2 (NetBSD) Host: betty.userland.com Content-Type: text/xml Content-length: 181 examples.getStateName 41 \end{info} \end{slide} \begin{slide} \heading{XML-RPC, lectures} Un O'Reilly très bien Le HOWTO \url{http://xmlrpc-c.sourceforge.net/xmlrpc-howto/xmlrpc-howto.html} \end{slide} \begin{slide} \heading{XML-RPC, limites} \begin{itemize} \item Unicode ? (uniquement ASCII, en standard) \item Introspection ? \url{http://xmlrpc-c.sourceforge.net/xmlrpc-howto/xmlrpc-howto-api-introspection.html} \end{itemize} \end{slide} \begin{slide} \heading{SOAP, le plus vendu} \url{http://www.soapware.org/} \url{http://www.w3.org/TR/SOAP/} Simple Object Access Protocol Le meilleur marketing (W3C et Microsoft) \end{slide} \begin{slide} \heading{SOAP, les principes} Très proche de XML-RPC. La bibliothèque client encode les paramètres en XML et la bibliothèque serveur les décode. Le programmeur ne voit \textbf{jamais} de XML. On fait des appels de procédure ou de l'asynchrone. Transport en HTTP, BEEP, etc. Bibliothèques pour tous : Perl, C, C\#, Python, Ruby, Java, VisualBasic/.NET, PHP, Ada. \end{slide} \begin{slide} \heading{SOAP, un exemple Perl} SOAP::Lite \url{http://www.soaplite.com/} \begin{info} # Utilise l'AUTOLOAD de Perl use SOAP::Lite +autodispatch => uri => 'http://www.soaplite.com/Temperatures', proxy => 'http://services.soaplite.com/temper.cgi'; print f2c(100), "\n"; # Appelle une procédure distante \end{info} \end{slide} \begin{slide} \heading{SOAP, un exemple Python} SOAPpy \url{http://pywebsvcs.sourceforge.net/} \begin{info} server = SOAP.SOAPProxy('http://api.google.com/search/beta2', namespace='urn:GoogleSearch') result = server.doGoogleSearch('Zls0Q7uAt2Lrcd7BHjai...zWJj7', 'python wsdl', ...); print result['estimatedTotalResultsCount'] \end{info} \end{slide} La chaine incompréhensible est la clé de la licence Google. \begin{slide} \heading{SOAP, détails} Types de paramètres : \begin{itemize} \item entiers, dates, booléens, chaines, etc (tout ce qu'on peut écrire avec les schémas) \item \foreign{structs} (tableaux associatifs) \item tableaux \end{itemize} Les erreurs sont signalées par des exceptions (\foreign{faults}). \end{slide} \begin{slide} \heading{SOAP, le serveur} \begin{info} use SOAP::Transport::HTTP; my $daemon = SOAP::Transport::HTTP::Daemon -> new (LocalAddr => 'localhost', LocalPort => 8080) -> dispatch_to('Handler'); $daemon->handle; package Handler; sub hi { return "hello, world"; } sub bye { return "goodbye, cruel world"; } \end{info} \end{slide} \begin{slide} \heading{Serveur SOAP plus détaillé} On veut créer un service indiquant la disponibilité d'un nom de domaine. \begin{info} % whois -h whois.sidn.nl 'is bortzmeyer.nl' bortzmeyer.nl is free % whois -h whois.sidn.nl 'is ripe.nl' ripe.nl is active \end{info} \end{slide} \begin{slide} \heading{Méticiel} On développe une bibliothèque ``métier'', assez indépendante de SOAP. \begin{info} package Meticiel; sub is_available () { if ($domain !~ /\.fr$/) { return "We only register domains in \".fr\""; } if (®istered($domain)) { return "Domain $domain already registered"; } return "Domain $domain is available. Buy it soon!"; } \end{info} \end{slide} \begin{slide} \heading{Logiciel réseau} Puis on écrit la colle SOAP autour. \begin{info} use SOAP::Transport::HTTP; $hostname = ` hostname`; chomp $hostname; my $daemon = SOAP::Transport::HTTP::Daemon -> new (LocalAddr => $hostname, LocalPort => 8080) -> dispatch_to(undef, Meticiel, undef, undef); print "Contact to SOAP server at ", $daemon->url, "\n"; $daemon->handle; \end{info} On peut alors développer les clients. \begin{info} $result = SOAP::Lite -> uri('http://does-not-exist-really-just-a-URI.nic.fr/Meticiel') -> proxy("http://$hostname:8080/") -> is_available($domain); unless ($result->fault) { print $result->result(); print "\n"; } else { print join ', ', $result->faultcode, $result->faultstring, $result->faultdetail; } \end{info} \end{slide} \begin{slide} \heading{SOAP, sur le câble} Uniquement si vous voulez écrire une bibliothèque SOAP s'appuie sur les schémas XML. SOAP permet de transmettre du XML brut (à analyser soi-même). \begin{info} POST /StockQuote HTTP/1.1 Content-Type: text/xml; charset="utf-8" Content-Length: 2456 SOAPAction: "http://electrocommerce.org/abc#MyMessage" \end{info} \end{slide} \begin{slide} \heading{SOAP, sur le câble, suite} \begin{info} AFNIC \end{info} \end{slide} Les \foreign{namespaces} (ici, ``myapp'') permettent de définir ses propres élements, sans risque de collision. \begin{slide} \heading{SOAP, lectures} Un O'Reilly assez médiocre Plein de ``SOAP pour les nuls''. \end{slide} \begin{slide} \heading{SOAP, les problèmes} \begin{itemize} \item Usine à gaz \item Peu interopérable \end{itemize} \foreign{What's wrong with SOAP?} \begin{info} wc soap-spec.txt 1519 10671 79445 soap-spec.txt wc xmlrpc-spec.txt 315 1657 15838 xmlrpc-spec.txt \end{info} \end{slide} \begin{slide} \heading{Exemples : Google} Google a un accès SOAP \url{http://www.google.com/apis/index.html}, décrit en WSDL (inscription gratuite et obligatoire) \end{slide} \begin{slide} \heading{Exemple, Amazon} \url{http://www.amazon.com/webservices} IL existe des paquetages tout faits, au dessus de SOAP. \begin{info} % perl amazon-by-keyword.pl ipv6 IPv6 Essentials - $27.97 Understanding Ipv6 - $20.99 IP Addressing and Subnetting, Including IPv6 - $41.97 ... \end{info} \end{slide} \begin{slide} \heading{UDDI, l'annuaire universel} \url{http://www.uddi.org/} Oasis et d'autres. Permet d'enregistrer les Web Services, afin de les retrouver. (``The CPAN of Web Services'') Un protocole + plusieurs registres (encore du travail pour les gérants de registre). Un registre UDDI peut être accédé en SOAP mais aussi en XML-RPC ou Corba. Documentation difficile à aborder (Oasis...). L'information estr très structurée, avec beaucoup de niveaux. \end{slide} Et la documentation n'est pas en hyper-texte :-( \begin{slide} \heading{UDDI, exemple} \begin{info} use UDDI::Lite +autodispatch => proxy => 'http://uddi.microsoft.com/inquire'; $info = find_business(name => 'amazon') -> businessInfos->businessInfo->serviceInfos->serviceInfo; print $info->name, "\n"; \end{info} \end{slide} \begin{slide} \heading{UDDI, plein pot} \begin{info} # find_* : "fuzzy" searches # get_* : exact searches, with the key $mybusinessList = find_business(name => 'ama'); $mybusinessInfos = $mybusinessList->businessInfos; @mybusinessInfo = $mybusinessInfos->businessInfo; for $mybusinessInfo (@mybusinessInfo) { print $mybusinessInfo->name, "\n"; print $mybusinessInfo->businessKey, "\n\n"; $myserviceInfos = $mybusinessInfo->serviceInfos; @myserviceInfo = $myserviceInfos->serviceInfo; for $myserviceInfo (@myserviceInfo) { print " ", $myserviceInfo->name, "\n"; print " ", $myserviceInfo->serviceKey, "\n"; @myserviceDetails = get_serviceDetail (serviceKey => $myserviceInfo->serviceKey); for $myserviceDetail (@myserviceDetails) { print " ", $myserviceDetail->name, "\n"; print " ", $myserviceDetail->description, "\n"; $mybindingTemplate = $myserviceDetail->bindingTemplates->bindingTemplate; # Actually, several print " ", $mybindingTemplate->description, "\n"; print " ", $mybindingTemplate->accessPoint, "\n"; } print "\n"; } print "\n\n"; } \end{info} \end{slide} \begin{slide} \heading{WSDL, méta-informations} WSDL est un langage (du W3C \url{http://www.w3c.org/TR/wsdl}) pour décrire les API (surtout pour SOAP) \end{slide} \begin{slide} \heading{WSDL, exemple} \begin{info} my $google = SOAP::Lite->service('http://api.google.com/GoogleSearch.wsdl'); my $result = $google->doGoogleSearch( $key, $query, 0, 10, 'false', '', 'false', '', 'latin1', 'latin1'); \end{info} \end{slide} \begin{slide} \heading{Utilisateurs : quelques conseils} \begin{enumerate} \item Suivre un tutoriel, \item Lire la spécification (formelle avec WSDL ou informelle), \item Écrire le client (choix du langage, de la bibliothèque). \end{enumerate} \end{slide} \begin{slide} \heading{Créateurs : quelques conseils} \begin{enumerate} \item Choix importants (paiement, qualité de service, conditions d'accès, conditions d'usage, \textbf{sécurité}), \item Écrire la spécification (formelle avec WSDL ou informelle), \item Écrire la partie métier (si pas encore fait), \item Écrire le serveur. \end{enumerate} \end{slide} \begin{slide} \heading{L'avenir est aux \ws ?} \begin{itemize} \item Vers une migration technique vers les \ws ? \item Vers une vraie ouverture des systèmes d'information ? La fin des \foreign{semantic firewall} ? \end{itemize} \end{slide} \end{document}