% $Id: index.tex,v 1.3 2006/03/20 21:22:44 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{<bortzmeyer@nic.fr>}}
\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}
<?php
  $server_url = '/meerkat/xml-rpc/server.php';
  $msg = new xmlrpcmsg('meerkat.getCategories', array());
  $client = new xmlrpc_client($server_url, "www.oreillynet.com", 80);

  # Send our XML-RPC message to the server and receive a response in return
  $response = $client->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'] . "<br />\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

<?xml version="1.0"?>
<methodCall>
   <methodName>examples.getStateName</methodName>
   <params>
      <param>
         <value><i4>41</i4></value>
         </param>
      </params>
   </methodCall>
\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{REST, le Web original}
\foreign{Representational State Transfer}. Pas un protocole ou un
format, c'est une architecture, c'est même l'architecture originale du
Web.

\begin{itemize}
  \item L'URI est important : connaitre l'URI doit suffire pour accéder à la ressource 
  \item  HTTP fournit toutes les opérations nécessaires (GET, PUT et DELETE, essentiellement).
  \item Chaque opération est auto-suffisante : il n'y a pas d'état.
  \item En outre, et c'est un point où le sens moderne de REST dévie
  de l'architecture originale du Web, les requêtes et surtout les
  réponses sont aujourd'hui typiquement encodées en XML
\end{itemize}

\end{slide}

\begin{slide}
\heading{Exemple REST en biologie}
XEMBL \url{http://www.xml.com/pub/a/ws/2002/05/14/biows.html}
interface REST à EMBL.

\begin{info}
import urllib
import sys
from xml.dom.ext.reader import Sax2
from xml import xpath

def extract(element, dom):
    match = xpath.Evaluate("/INSDSet/INSDSeq/%s/text()" % element, dom)
    return match[0].nodeValue

def format(element, dom):
    return "%s: %s" % (element, extract(element,dom))

id = sys.argv[1]
url = 'http://www.ebi.ac.uk/cgi-bin/dbfetch?db=embl&id=%s&format=insdxml'
result = urllib.urlopen(url % id)
reader = Sax2.Reader()
doc = reader.fromStream(result)
print format("INSDSeq_locus", doc)
print format("INSDSeq_moltype", doc)
print format("INSDSeq_definition", doc)
\end{info}
\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 (&registered($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}
<SOAP-ENV:Envelope
   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <SOAP-ENV:Body>
        <myapp:GetLastTradePrice xmlns:myapp="Some-URI">
            <symbol>AFNIC</symbol>
        </myapp:GetLastTradePrice>
    </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>
\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}




