Le client (et . . . SOAP, Simple . . . Les Web Services Le serveur Le répertoire . . . Olivier Ricou Conclusion Home Page Title Page JJ II J I Page 1 of 34 Go Back Full Screen Close Quit 31 mai 2010 Les Web Services, WS, reprennent ce que font les RMI, CORBA et autres mais : Le client (et . . . SOAP, Simple . . . – les WS sont indépendant des plateformes et des langages car écrits en XML, Le serveur Le répertoire . . . Conclusion Home Page Title Page JJ II J I Page 2 of 34 Go Back Full Screen Close Quit – la plupart des WS utilisent HTTP pour la transmission et évitent ainsi les pare-feux. Le contre-coût est – le poids des données à transmettre à cause du verbeux XML, – moins de services (ça progresse) On choisira donc : – les Web Services pour invoquer des services faiblement couplé à l’application développé, – les RMI pour l’utilisation de services fortement couplés. L’architecture globale reprend ce qu’on connait déjà : Le client (et . . . SOAP, Simple . . . Le serveur Le répertoire . . . Conclusion Home Page Title Page JJ II J I Page 3 of 34 Go Back Full Screen Close Quit – le client, – un serveur de nom de services (registry) – le serveur. ce qui donne en couche : Le client (et . . . SOAP, Simple . . . Le serveur Le répertoire . . . Conclusion Home Page Title Page JJ II J I Page 4 of 34 Go Back Full Screen Close Quit On note déjà 3 protocoles : – WSDL : la description du service en XML, – SOAP : le protocole d’invocation du service (il en existe d’autres), – HTTP : le protocole de transport. et si on entre dans les détails avec les applications (en jaune) et les documents tranmis (en bleu) : Le client (et . . . SOAP, Simple . . . Le serveur Le répertoire . . . Conclusion Home Page Title Page JJ II J I Page 5 of 34 Go Back Full Screen Close Quit 1. Le client (et . . . Le client (et WSDL) Un service se présente en WSDL, Web Service Definition Language. SOAP, Simple . . . Regardons la description du Web Service de Google : Le serveur Le répertoire . . . GoogleSearch.wsdl Conclusion Home Page 1 Title Page JJ II 2 3 4 J I Page 6 of 34 5 6 7 Go Back Full Screen Close Quit 8 9 <?xml version="1.0"?> <definitions name="GoogleSearch" targetNamespace="urn:GoogleSearch" xmlns:typens="urn:GoogleSearch" xmlns:xsd="http://www.w3.org/2001/XMLSc xmlns:soap="http://schemas.xmlsoap.org/ xmlns:soapenc="http://schemas.xmlsoap.o xmlns:wsdl="http://schemas.xmlsoap.org/ xmlns="http://schemas.xmlsoap.org/wsdl/ 11 12 Le client (et . . . 13 SOAP, Simple . . . 14 Le serveur 15 Le répertoire . . . 16 17 Conclusion 18 Home Page Title Page 19 20 21 JJ II 22 J I 23 24 Page 7 of 34 Go Back 25 26 27 Full Screen Close Quit 28 29 <!-- Types for search - result elements, directory <types> <xsd:schema xmlns="http://www.w3.org/2001/XMLSch targetNamespace="urn:GoogleSearch"> <xsd:complexType name="GoogleSearchResult"> <xsd:all> <xsd:element name="documentFiltering" <xsd:element name="searchComments" <xsd:element name="estimatedTotalResultsCo <xsd:element name="estimateIsExact" <xsd:element name="resultElements" <xsd:element name="searchQuery" <xsd:element name="startIndex" <xsd:element name="endIndex" <xsd:element name="searchTips" <xsd:element name="directoryCategories" <xsd:element name="searchTime" </xsd:all> </xsd:complexType> 31 32 Le client (et . . . 33 SOAP, Simple . . . 34 Le serveur 35 Le répertoire . . . 36 37 Conclusion 38 Home Page Title Page 39 40 41 JJ II 42 J I 43 Page 8 of 34 Go Back Full Screen Close Quit <xsd:complexType name="ResultElement"> <xsd:all> <xsd:element name="summary" type="xsd:stri <xsd:element name="URL" type="xsd:string"/ <xsd:element name="snippet" type="xsd:stri <xsd:element name="title" type="xsd:string <xsd:element name="cachedSize" type="xsd:s <xsd:element name="relatedInformationPrese <xsd:element name="hostName" type="xsd:str <xsd:element name="directoryCategory" type <xsd:element name="directoryTitle" type="x </xsd:all> </xsd:complexType> 45 46 Le client (et . . . 47 SOAP, Simple . . . 48 Le serveur 49 Le répertoire . . . 50 51 Conclusion 52 Home Page Title Page 53 54 55 JJ II 56 J I 57 58 Page 9 of 34 Go Back 59 60 61 Full Screen Close 62 63 64 Quit <!-- Services <!-- note, ie and oe are ignored by server; all tr ... <message name="doGoogleSearch"> <part name="key" type="xsd:string"/> <part name="q" type="xsd:string"/> <part name="start" type="xsd:int"/> <part name="maxResults" type="xsd:int"/> <part name="filter" type="xsd:boolean"/> <part name="restrict" type="xsd:string"/> <part name="safeSearch" type="xsd:boolean"/> <part name="lr" type="xsd:string"/> <part name="ie" type="xsd:string"/> <part name="oe" type="xsd:string"/> </message> <message name="doGoogleSearchResponse"> <part name="return" type="typens:GoogleS </message> ... </definitions> On y trouve les variables de classe des objets qui circuleront sur le réseau. Le client (et . . . A partir de là on peut écrire tout ses classes ou demander à un programme de le faire. Axis propose WSDL2Java : SOAP, Simple . . . Le serveur java org.apache.axis.wsdl.WSDL2Java GoogleSearch.wsdl Le répertoire . . . Conclusion ce qui construit Home Page Title Page JJ II J I > ls GoogleSearch/ DirectoryCategory.java GoogleSearchBindingStub.java GoogleSearchPort.java GoogleSearchResult.java Page 10 of 34 Go Back Full Screen Close Quit reste à écrire le programme Java : GoogleSearchService.java GoogleSearchServiceLocator ResultElement.java GoogleClient.java Le client (et . . . 1 SOAP, Simple . . . 2 Le serveur 3 Le répertoire . . . 4 5 Conclusion 6 Home Page Title Page 8 9 II 10 J I 11 12 Go Back 13 14 15 Full Screen Close Quit import import import import org.apache.axis.client.Call; org.apache.axis.client.Service; org.apache.axis.encoding.ser.*; javax.xml.namespace.QName; 7 JJ Page 11 of 34 package GoogleSearch; 16 public class GoogleClient { public static void main(String[] args) throws Exce java.net.URL url = new java.net.URL("http://api.google.com/searc String ns = "urn:GoogleSearch"; Service service = new Service(); Call call = (Call) service.createCall(); Class ser = BeanSerializerFactory.class; Class des = BeanDeserializerFactory.class; 18 19 Le client (et . . . 20 SOAP, Simple . . . 21 Le serveur 22 Le répertoire . . . 23 24 Conclusion 25 Home Page Title Page 26 27 28 JJ II J I Page 12 of 34 Go Back Full Screen Close Quit 29 call.registerTypeMapping(ResultElement.class, new QName(ns,"ResultElement"), ser, des); call.registerTypeMapping(DirectoryCategory.class new QName(ns, "DirectoryCategory ser, des); call.registerTypeMapping(GoogleSearchResult.clas new QName(ns, "GoogleSearchResul ser, des); call.setTargetEndpointAddress(url); call.setOperationName(new QName(ns, "doGoogleSearch")); GoogleSearchResult gsr = (GoogleSearchResult)cal new Object[] {"1QHAivJQFHLWdrREqYAON args[0], new Integer(1), new Integer(10), new new Boolean(false), "", "latin1", "l 31 32 Le client (et . . . 33 SOAP, Simple . . . 34 Le serveur 35 Le répertoire . . . 36 ResultElement[] re = gsr.getResultElements(); System.out.println("Google Search"); for (int i=0; i<re.length; i++) { String s = re[i].getSummary(); if ( s.equals("") ) s = re[i].getSnippet(); System.out.println(Title: " + re[i].getTitle() } 37 Conclusion 38 Home Page Title Page 39 40 41 JJ II 42 J I 43 } 44 Page 13 of 34 Go Back Full Screen Close Quit 45 } 1.1. Le client (et . . . SOAP, Simple . . . Le serveur Le répertoire . . . Conclusion Google Spell en python L’intérêt premier des Web Services est leur indépendance vis à vis des langages. Avec la description d’un service en WSDL on peut ainsi écrire son client avec le langage de son choix (en espérant qu’il propose une bibliothèque adaptée). En Python, comme en Java, on extrait du wsdl le paquet du service : Home Page Title Page JJ II J I Page 14 of 34 % wsdl2py GoogleSearch.wsdl % ls -rt GoogleSearch.wsdl GoogleSearch_services_types.py GoogleSearch_services.py Maintenant les fichiers générés ont changés : Go Back Full Screen Close Quit GoogleSearch_client.py GoogleSearch_types.py GoogleSearch_server.py puis on écrit notre programme en se basant sur les fichiers générés : Le client (et . . . googlespell.py SOAP, Simple . . . Le serveur 1 Le répertoire . . . 2 Conclusion 3 4 #! /usr/bin/env python from GoogleSearch_services import * import sys Home Page 5 Title Page JJ II 6 7 8 J I Page 15 of 34 9 10 11 Go Back Full Screen Close Quit 12 locator = GoogleSearchServiceLocator() google = locator.getGoogleSearchPort() req = doSpellingSuggestionWrapper() req._key = ’00000000000000000000’ req._phrase = ’’+sys.argv[1] resp = google.doSpellingSuggestion(req) print resp._return 1.2. Le client (et . . . 1 SOAP, Simple . . . 2 Le serveur 3 Le répertoire . . . 4 Conclusion 5 6 Home Page Title Page 7 8 9 JJ II J I 10 11 12 Page 16 of 34 13 Go Back 15 16 Full Screen 17 Close Quit 18 Et un Google Fight en perl #! /usr/bin/env perl use SOAP::Lite; my $key=’000000000000000000’; my $googleSearch = SOAP::Lite -> service("file:GoogleSearch.wsdl"); my $result; foreach $argnum (0 .. $#ARGV) { $result = $googleSearch->doGoogleSearch($key, $ARGV[$argnum], 0, 10, "false","", "false", "", "latin1", "latin1"); $˜="TWOCOL"; write; } format TWOCOL = @<<<<<<<<<<<<<<< @########## results $ARGV[$argnum],$result->{’estimatedTotalResultsCount . ce qui donne Le client (et . . . SOAP, Simple . . . Le serveur Le répertoire . . . Conclusion Home Page Title Page JJ II J I Page 17 of 34 Go Back Full Screen Close Quit [hermes]˜ % googlefight.pl java c++ java 227000000 results c++ 95400000 results 2. Le client (et . . . SOAP, Simple Object Access Protocol SOAP est un protocole d’invocation qui répond aux contraintes suivantes : SOAP, Simple . . . Le serveur Le répertoire . . . Conclusion Home Page Title Page JJ II J I Page 18 of 34 Go Back Full Screen Close Quit 1. L’application ou le service doit être ouvert : les clients doivent pouvoir tourner sur tout OS et pouvoir être écrit dans pratiquement tous les langages, 2. Elle doit être accessible depuis Internet et passer à travers les parefeu, 3. Elle doit être disponible en 7/24, 4. Elle doit pouvoir être sûre et chiffrer les transmissions de données, 5. Elle doit passer l’échelle et pouvoir répondre à des millions d’appels par jour. On retrouve à travers ces contraintes XML, HTTP, HTTPS et l’infrastructure des serveurs Web déjà bien éprouvés. L’empaquetage des données SOAP se presente sous la forme suivante : Le client (et . . . SOAP, Simple . . . Le serveur Le répertoire . . . POST /helloworld/rpcrouter HTTP/1.0 Host: localhost Content−Type: text/xml; charset=utf−8 Content−Length: 447 SOAPAction: "" En−tete HTTP Conclusion <?xml version=’1.0’ encoding=’UTF−8’?> Home Page <SOAP−ENV:Envelope xmlns:SOAP−ENV="http://schemas... Title Page <SOAP−ENV:Header> JJ II J I Page 19 of 34 Go Back En−tete SOAP (optional) <SOAP−ENV:Body> <ns1:getMessage xmlns:ns1="urn:helloworld"> <caller xsi:type="xsd:string" Corps SOAP (peut etre une "Erreur SOAP") Full Screen </SOAP−ENV:Envelope> Close Quit Enveloppe SOAP paquet SOAP On peut ajouter concernant le protocole, que Le client (et . . . SOAP, Simple . . . – SOAP est un protocole unidirectionnel. Même si le plus souvent on s’attend à recevoir une réponse, rien ne le demande dans les spécifications. On peut faire du SOAP sur SMTP, le protocole du mail. Le serveur Le répertoire . . . Conclusion – SOAP n’est pas un protocole de RPC. On peut l’utiliser pour transmettre des messages sans chercher à déclencher une action. Home Page Title Page JJ II J I Page 20 of 34 Les spécifications de SOAP décrivent un appel à une fonction comme une structure XML contenant : – – – – un nom de méthode, une signature (optionel), une liste d’arguments, un en-tête (optionel). Go Back Full Screen Close Quit Pour une présentation officielle de SOAP et ses spécifications, voir http ://www.w3c.org/2000/xp/Group/. Avec le client de GoogleSearch on voit passer sur le réseau en XML : Le client (et . . . GoogleSearch.soap SOAP, Simple . . . Le serveur 1 Le répertoire . . . 2 3 Conclusion 4 Home Page Title Page 5 6 7 JJ II J I 8 9 POST /search/beta2 HTTP/1.0 Content-Type: text/xml; charset=utf-8 Accept: application/soap+xml, multipart/related, tex User-Agent: Axis/1.1 Host: api.google.com Cache-Control: no-cache Pragma: no-cache SOAPAction: "" Content-Length: 946 10 Page 21 of 34 11 Go Back 12 13 Full Screen 14 Close 15 16 Quit <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/e xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-inst <soapenv:Body> 18 19 Le client (et . . . 20 SOAP, Simple . . . 21 Le serveur 22 Le répertoire . . . 23 24 Conclusion 25 Home Page Title Page 26 27 28 JJ II 29 J I 30 31 Page 22 of 34 Go Back 32 33 34 Full Screen Close Quit <ns1:doGoogleSearch soapenv:encodingStyle="http://schemas.xmlsoap.or xmlns:ns1="urn:GoogleSearch"> <ns1:arg0 xsi:type="xsd:string"> TXe6DPBQFHLjiwdyU4MQTV6sYG2IQcuv</ns1:arg0> <ns1:arg1 xsi:type="xsd:string">Osama Bin Laden</ <ns1:arg2 xsi:type="xsd:int">1</ns1:arg2> <ns1:arg3 xsi:type="xsd:int">10</ns1:arg3> <ns1:arg4 xsi:type="xsd:boolean">true</ns1:arg4> <ns1:arg5 xsi:type="xsd:string"></ns1:arg5> <ns1:arg6 xsi:type="xsd:boolean">false</ns1:arg6> <ns1:arg7 xsi:type="xsd:string"></ns1:arg7> <ns1:arg8 xsi:type="xsd:string">latin1</ns1:arg8> <ns1:arg9 xsi:type="xsd:string">latin1</ns1:arg9> </ns1:doGoogleSearch> </soapenv:Body> </soapenv:Envelope> 3. Le client (et . . . Le serveur La mise en place d’un service SOAP passe par les étapes suivantes : SOAP, Simple . . . 1. Installer l’infrastructure pour stocker le Web-Service, Le serveur Le répertoire . . . 2. Écrire le service, en Java dans notre cas, Conclusion 3. Enregistrer le service, Home Page 4. Écrire un client pour tester le service, Title Page JJ II J I Page 23 of 34 Go Back Full Screen Close Quit 5. Les compiler avec les chemins nécessaires, 6. En cas de problème, utiliser un outils qui intercepte les communications afin de les analyser. 3.1. Le client (et . . . SOAP, Simple . . . Le serveur Le répertoire . . . Conclusion Home Page Title Page JJ II J I Page 24 of 34 Go Back Full Screen Close Quit Installation de l’infrastructure Les Web services peuvent s’appuyer sur – – – – – un serveur d’application J2EE, .NET, le micro serveur de Java 1.6, Globus (grid computing) ... 3.2. Le client (et . . . SOAP, Simple . . . Le serveur Le répertoire . . . Conclusion Home Page Title Page JJ II J I Page 25 of 34 Go Back Full Screen Close Quit Les plateformes Les grandes marques et le libre offre des plateformes qui intègre l’ensemble des besoins : – – – – – IBM Emerging Technologies Toolkit Microsoft SOAP Toolkit 3.0 Sun Web Services Developer Pack 1.4 for Java JBoss ... Elles offrent : – le registry (UDDI), – les interfaces en WSDL – les services pour écrire le client pour appeler le service et gérer les réponses voire les erreurs, – la déclaration, l’enregistrement et la mise en production. Les principaux inconvénients de ces paquetages sont : Le client (et . . . SOAP, Simple . . . Le serveur – – – – le ”dark side” qui cache les mécanismes, incite les utilisateurs à la facilité (c’est mal !), rend difficile la personnalisation (custumization) du système, impose un système de pensé, Le répertoire . . . Mais il faut leur reconnaitre un gain de temps si on suit le mode de pensé du logiciel. Conclusion Home Page Title Page JJ II J I Page 26 of 34 Go Back Full Screen Close Quit Quoi qu’il en soit, un bon utilisateur doit comprendre les mécanismes sous-jacents. 3.3. Le client (et . . . Un exemple complet en Java 1.6 CircleFunctions.java SOAP, Simple . . . Le serveur 1 Le répertoire . . . 2 Conclusion 3 package ws; import javax.jws.WebService; import javax.xml.ws.Endpoint; // to start a server 4 Home Page Title Page 5 6 7 JJ II J I 8 @WebService public class CircleFunctions { public double getArea(double r) { return java.lang.Math.PI * r * r; } 9 public static void main(String[] args) { Endpoint.publish( "http://localhost:8088/circlefunctions", new CircleFunctions()); } 10 Page 27 of 34 11 Go Back 12 13 Full Screen 14 Close Quit 15 } Pour faire de cette classe un web service, le travail est devenu très simple : Le client (et . . . SOAP, Simple . . . Le serveur Conclusion Home Page Title Page JJ II J I Page 28 of 34 Go Back Full Screen Quit javac -d class src/CircleFunctions.java – générer toutes les classes nécessaire pour faire tourner le web-service Le répertoire . . . Close – compiler le code, % wsgen -cp class -d class ws.CircleFunctions % ls class/ws/jaxws GetArea.class GetCircumference.class GetArea.java GetCircumference.java GetAreaResponse.class GetCircumferenceResponse.class GetAreaResponse.java GetCircumferenceResponse.java – lancer le serveur java -cp class ws.CircleFunctions Le WSDL du service étant sur http://localhost:8088/circlefunctions?wsdl Le client est plus simple que dans le cas du GoogleSearch. Le client (et . . . SOAP, Simple . . . Le serveur Là encore il faut importer le WSDL et générer les classes Java associées : wsimport "http://localhost:8088/circlefunctions?WSDL" ce qui donne : Le répertoire . . . Conclusion Home Page Title Page JJ II J I Page 29 of 34 Go Back Full Screen Close Quit % ls ws CircleFunctions.class CircleFunctionsService.class GetArea.class GetAreaResponse.class ObjectFactory.class package-info.class Il ne reste plus qu’a écrire le client : Le client (et . . . TestCircle.java SOAP, Simple . . . Le serveur 1 Le répertoire . . . 2 3 Conclusion 4 Home Page Title Page 5 6 7 JJ II J I 8 9 10 Page 30 of 34 11 Go Back 12 13 Full Screen 14 Close 15 16 Quit import ws.CircleFunctions; import ws.CircleFunctionsService; public class TestCircle { public static void main(String[] args) { try { CircleFunctionsService service = new ws.CircleFunctionsService(); CircleFunctions port = service.getCircleFunctionsPort(); System.out.println(port.getArea(4.)); } catch (Exception e) {e.printStackTrace();} } } % java TestCircle 50.26548245743669 Le client (et . . . SOAP, Simple . . . Le serveur Le répertoire . . . Conclusion Home Page Title Page JJ II J I Page 31 of 34 Go Back Full Screen Close Quit 3.4. Le client (et . . . SOAP, Simple . . . Le serveur Un Web Service sur un serveur d’application Le principe consiste souvent à déposer dans le bon répertoire une archive comprise par le serveur de Web Services. On peut aussi uploader l’archive via l’interface d’administration du serveur. Le répertoire . . . Conclusion Il s’agit donc d’un serveur d’applications J2EE gérant les Web Services. Dans ce cas il suffit de déposer un fichier .war dans $GlassFish/domain/domain1/autodeploy/ ou à l’aide de l’interface Web. Exemple avec GlassFish Home Page Title Page JJ II J I Page 32 of 34 Go Back Full Screen Close Quit Pour écrire le client, on suit le même principe que pour TestCircle mais on le lance avec appclient fourni par Glassfish. 4. Le répertoire des services, UDDI UDDI.XML regroupe les informations sur les UDDI : http ://uddi.xml.org/. Le client (et . . . SOAP, Simple . . . Le serveur Le répertoire . . . Conclusion Home Page Title Page JJ II J I Page 33 of 34 Go Back Full Screen Close Quit Recherche de services sur l’UDDI public de XMethods 5. Le client (et . . . SOAP, Simple . . . Le serveur Conclusion La force de SOAP est son interopérabilité, mais l’interopérabilité n’est pas une fin en soit. La fin ce sont les services distribués et le commerce électronique. Le répertoire . . . Pour y arriver il faut atteindre une masse critique et surtout relier les services à travers des espaces comme ceux de Jini et Javaspace. Conclusion Home Page Title Page JJ II J I Page 34 of 34 Go Back Full Screen Close Quit Les Web Services visent un développement en masse via le WSDL, Web Services Description Language et les UDDI, Universal Description, Discovery and Integration. Le WSDL doit simplifier la mise en œuvre et l’usage des web services quand aux UDDIs ils doivent permettre de connaitre les services existants. Au niveau du mode de fonctionnement, WSDL s’appuit sur SOAP lequel s’appuit sur TCP/IP (on a vu HTTP, on a parlé de SMTP). WSDL n’est pas obligé de s’appuyer sur SOAP, mais cela lui offre une interopérabilité et un pré-travail bien agréable.