Java Web Service ================ Un Web service permet de découpler la gestion des données du visuel. Un web service permettant la communication et l'échange de données entre applications et systèmes hétérogènes dans des environnements distribués Le principe de base est assez simple: un client "questionne" un web service hébergé sur un serveur via le protocole http, il obtient alors une réponse. Le réponse est de nature XML et peut représenter des objets. Le protocole de communication est défini dans le cadre de la norme SOAP dans la signature du service exposé (WSDL). Actuellement, le protocole de transport est essentiellement HTTP(S). .. note:: il est possible de faire des webs services avec d'autres technologies que java, ... python par exemple (aussi bien côté client que serveurs) Serveur ~~~~~~~ Pour pouvoir utiliser un web service il faut l'héberger. Pour cela nous allons devoir installer - un serveur applicatif Java EE: **Tomcat** - une application permettant le développement de services web: **Axis** Les deux projets sont hébergés par la fondation **Apache Software**. Nous partons sur un serveur Debian fraichement installé. L'objectif est d'installer la dernière version de chaque outil ... sinon un simple apt suffit .. code-block:: bash apt-get install tomcat8 Installation de Java -------------------- .. note:: on installe la version oracle de java mais il existe aussi une version open-source .. code-block:: bash apt-get install openjdk-7-jre openjdk-7-jdk java -version javac -version Le principe est de télecharger via le site d'oracle le jdk (ou le jre), de l'installer puis d'indiquer au système que nous souhaitons utiliser de façon préférentielle cette machine virtuelle .. code-block:: bash su - root wget --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u5-b13/jdk-8u5-linux-x64.tar.gz mkdir /opt/jdk tar -zxf jdk-8u5-linux-x64.tar.gz mv jdk1.8.0_05 /opt/ ln -s /opt/jdk1.8.0_05 /opt/jdk ls /opt/jdk update-alternatives --install /usr/bin/java java /opt/jdk/bin/java 2000 update-alternatives --install /usr/bin/javac javac /opt/jdk/bin/javac 2000 update-alternatives --display java update-alternatives --display javac java -version .. note:: dans update-alternatives on sélectionne une version d'outil par sa priorité içi 2000 (mais on aurait put mettre autre chose) Installation de Tomcat ---------------------- Le principe reste simple: - on récupère les sources - on installe les sources - on paramètre - on lance .. code-block:: bash su - root cd /opt wget http://mirrors.ircam.fr/pub/apache/tomcat/tomcat-8/v8.0.20/bin/apache-tomcat-8.0.20.tar.gz tar -xvf apache-tomcat-8.0.20.tar.gz ln -s apache-tomcat-8.0.20 tomcat rm apache-tomcat-8.0.20.tar.gz Pour paramétrer le port de l'interface d'administration web de tomcat, il faut éditer /opt/tomcat/conf/server.xml (par défaut 8080) Pour créer un utilisateur tomcat il faut éditer /opt/tomcat/conf/tomcat-user.xml et ajouter dans la balise racine .. code-block:: xml On peut maintenant démarrer et arrêter tomcat .. code-block:: bash /opt/tomcat/bin/startup.sh /opt/tomcat/bin/shutdown.sh une fois démarrer on peut avoir accès à la console d'administration via l'url http://127.0.0.1:8080 Si on a des soucis de lenteurs par faute de mémoire il faut modifier la variable **JAVA_OPTS** contenu dans le fichier /opt/tomcat/bin/startup.sh :: export JAVA_OPTS="-server -Xms2048 -Xmx4096" Il est possible d'intégrer Tomcat comme un service en éditant le fichier /etc/init.d/tomcat .. code-block:: bash #!/bin/sh CATALINA_HOME=/opt/tomcat; export CATALINA_HOME JAVA_HOME=/opt/java; export JAVA_HOME TOMCAT_OWNER=root; export TOMCAT_OWNER start() { echo -n « Starting Tomcat: » su $TOMCAT_OWNER -c $CATALINA_HOME/bin/startup.sh sleep 2 } stop() { echo -n « Stopping Tomcat: » su $TOMCAT_OWNER -c $CATALINA_HOME/bin/shutdown.sh } # See how we were called. case « $1″ in start) start ;; stop) stop ;; restart) stop start ;; *) echo $ »Usage: tomcat {start|stop|restart} » exit esac Apache et Tomcat ---------------- .. note:: cette installation n'est pas obligatoire Il est possible d'utiliser le moteur http d'Apache au lieu du moteur de Tomcat. Pourquoi? car pour de grosse infrastructure Apache est plus robuste. .. code-block:: bash apt-get install apache apache2-mpm-prefork libapache2-mod-jk On edite le module jk /etc/apache2/mods-available/jk.load afin d'ajouter quelques paramètres .. code-block:: bash LoadModule jk_module /usr/lib/apache2/modules/mod_jk.so JkWorkersFile /etc/apache2/workers.properties JkLogFile /var/log/apache2/mod_jk.log JkLogLevel debug JkLogStampFormat "[%a %b %d %H:%M:%S %Y] " Dans le fichier de configuration Apache de notre site on rajoute les directives JKMount avec context1 et contextB correspondant aux application web déployées sur notre tomcat .. code-block:: bash ServerAdmin webmaster@localhost DocumentRoot /var/www/ ... JkMount /contextA/* worker1 JkMount /contextB/jsps/*.jsp worker1 /* Au niveau de tomcat on active le connecteur ajp dans le fichier server.xml .. code-block:: xml On génère un fichier etc/apache2/workers.properties .. code-block:: bash workers.tomcat_home=/opt/tomcat workers.java_home=/opt/java ps=/ worker.list=worker1 worker.worker1.port=8009 worker.worker1.host=localhost worker.worker1.type=ajp13 worker.worker1.lbfactor=1 On peut redémarrer apache .. code-block:: bash /etc/init.d/apache2 restart On a maintenant accès à nos serveur tomcat via le port apache 80 Installation de Axis -------------------- .. note:: Axis peut être lancer de façon indépendante comme un serveur. Mais les performances sont meilleurs en tant que webapp d'un serveur d'application. Donc nous utiliserons la version war et non Binary Distribution Le principe général est - on récupère axis - on l'installe - on l'intègre comme webapp dans tomcat - on valide l'intégration .. code-block:: bash cd /tmp wget http://archive.apache.org/dist/axis/axis2/java/core/1.6.1/axis2-1.6.2-war.zip unzip axis2.1.6.1-war.zip cp axis2.war /opt/tomcat/webapps /opt/tomcat/bin/shutdown.sh /opt/tomcat/bin/startup.sh On a maintenant accès à l'interface http://127.0.0.1:8080/axis2. On peut via cette interface valider notre système. .. note:: le premier accès à l'interface génère un dossier /opt/tomcat/webapps/axis2. Dans une utilisation plus approfondie des web services il faudra peut être rajouter des librairies dans /opt/tomcat/webapps/axis2/WEB-INF/lib. Certaine de ces librairies sont accessibles via la Binary Distribution de Axis. L'interface d'Axis2 donne accès à la liste des services disponibles (et à leurs définitions WSDL) mais aussi à une interface d'administration. Cette dernière réclame une authentification qu'on gère au niveau du fichier /opt/tomcat/webapps/axis2/axis2.xml (par défaut le user est admin, password axis2). Programmation et déploiement du Web Service ------------------------------------------- Nous allons développer un web service. Nous allons d'abord créer un workspace qui le permet :: root +--- workspace +--- tmp +--- service +--- myws +--- test +--- MyTest.java Ce qui s'obtient ainsi .. code-block:: bash mkdir -p /root/workspace/tmp mkdir -p /root/workspace/service/myws/test On édite notre service mytest.java .. code-block:: java package service.myws.test; public class MyTest { public String echo(String value) { return value; } } On compile notre service .. code-block:: bash cd /root/workspace javac -d tmp/ service/myws/test/MyTest.java On a donc maintenant dans tmp notre classe compilée. On ajoute un fichier xml permet de décrire notre service .. code-block:: bash cd /root/workspace mkdir -p tmp/META-INF vi tmp/META-INF/services.xml .. code-block:: xml service.myws.test.MyTest On génère une archive pour la déployer en tant que service .. code-block:: bash cd /root/workspace jar -cvf MyTest.aar -C tmp/ . .. note:: il faut noter que l'archive se nomme aar et non jar comme d'habitude On peut maintenant déployer notre archive. Ce déployement peut être réalisé via l'interface web dans la partie administration upload de service. Cette interface est complète et permet notament d'activer ou de désactiver un service. En ligne de commande le déployement consiste à copier notre archive dans le dossier services de l'application axis2 de tomcat .. code-block:: bash cp /root/workspace/MyTest.aar /opt/tomcat/webapps/axis2/WEB-INF/services Client ~~~~~~ Pour créer un client il faut un serveur ... sur lequel on a accès à la définition du service qu'on souhaite appeler. Dans notre cas on a accès à cetté définition via l'url http://127.0.0.1:8080/axis2/services/MyTest?wsdl. Axis possède un script qui permet à partir d'une définition wsdl de générer des classes pour avoir accès à ce service .. code-block:: bash cd /root/workspace java -Djava.ext.dirs=/opt/tomcat/webapps/axis2/WEB-INF/lib org.apache.axis2.wsdl.WSDL2Java -uri http://127.0.0.1:8080/axis2/services/MyTest?wsdl On retrouve ainsi dans /root/workspace/src/service/myws/test deux classes: * MyTestCallbackHandler.java * MyTestStub.java qui permettent l'accès au service. On va créer un fichier Client.java dans /root/workspace/src/service/myws/test .. code-block:: java ackage service.myws.test; import service.myws.test.MyTestStub.EchoResponse; public class Client { public static void main(String[] args) throws Exception { MyTestStub stub = new MyTestStub(); //Create the request MyTestStub.Echo request = new MyTestStub.Echo(); request.setArgs0("Hello world"); //Invoke the service EchoResponse response = stub.echo(request); System.out.println("Response : " + response.get_return()); } } On peut maintenant compiler cette classe .. code-block:: bash mkdir -p /root/workspace/tmp cd /root/workspace/src javac -Djava.ext.dirs=/opt/tomcat/webapps/axis2/WEB-INF/lib service/myws/test/*.java -d ../tmp/ /* Et maintenant on utilise notre classe .. code-block:: bash cd /root/workspace/tmp java -Djava.ext.dirs=/opt/tomcat/webapps/axis2/WEB-INF/lib service/myws/test/Client .. note:: il faut noter qu'on utilise la librairie axis2 même pour le client On peut aussi écrire un client python .. code-block:: python import SOAPpy client = SOAPpy.SOAPProxy("http://localhost:8080/axis2/services/MyTest", namespace="http://test.myws.service") print client.echo("coucou") .. note:: la notion de namespace est obtenu via le wsdl, et le nom de la méthode via l'operation des binding SOAP .. note:: pour voir les messages SOAP échangés il faut activer les logs dans notre client python .. code-block:: python client.config.debug = 1 Par défaut sur un serveur tomcat avec une webapps Axis il existe un service Version qui permet d'avoir la version d'Axis. Et bien on peut obtenir cette information via: * un client java (cf méthode précédente) * une demande par url http://127.0.0.1:8080/axis2/services/Version * via un client python .. code-block:: python import SOAPpy client = SOAPpy.SOAPProxy("http://localhost:8080/axis2/services/Version", namespace="http://axisversion.sample") print client.getVersion() Vive l'interportabilité