User Tools

Site Tools


wiki:epims4_0m2:developer:cxf_web-services

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
wiki:epims4_0m2:developer:cxf_web-services [2008/03/19 11:50]
barthe created
wiki:epims4_0m2:developer:cxf_web-services [2008/10/02 10:21] (current)
Line 1: Line 1:
 ====== CXF ====== ====== CXF ======
 ==== Intro ==== ==== Intro ====
-Pour implémenter les web-services dans ePims nous utilisons la technologie apache [[http://​incubator.apache.org/​cxf/​|CXF]] (Celtix-XFire). Cette librairie permet, entre autres, de créer des web-services ​très facilement ​à partir d'​interface déjà écrite.+Pour implémenter les web-services dans ePims nous utilisons la technologie apache [[http://​incubator.apache.org/​cxf/​|CXF]] (Celtix-XFire). Cette librairie permet, entre autres, de créer ​très facilement, en collaboration avec Spring, ​des web-services à partir d'​interface déjà écrite. 
 + 
  
 ==== Utilisation ==== ==== Utilisation ====
-Il faut tout d'​abord importer les librairies nécessaires au fonctionnement de CXF. Pour l'​utilisation faîtes dans ePims il est nécessaire de prendre les dépendances suivantes (facilement retrouvable grâce à la target ​//resolve// des build.xml).+Il faut tout d'​abord importer les librairies nécessaires au fonctionnement de CXF. Pour l'​utilisation faîtes dans ePims il est nécessaire de prendre les dépendances suivantes (facilement retrouvable grâce à la target ​''​resolve'' ​des build.xml).
 <​code>​ <​code>​
 commons-logging-1.1.jar commons-logging-1.1.jar
Line 24: Line 26:
 xml-resolver-1.2.jar xml-resolver-1.2.jar
 </​code>​ </​code>​
 +
 +Librairie nécessaire si le //​databinding//​ utilisé est celui d'​Aegis :
 +<​code>​
 +jdom-1.0.jar
 +</​code>​
 +
  
 ==== Serveur Web-services ==== ==== Serveur Web-services ====
-Côté serveur il faut configurer plusieurs choses 
  
-  ​* **web.xml** : pour déclarer+== Configuration == 
 +Côté serveur il faut tout d'​abord écrire l'​interface comportant les méthodes des services voulus ainsi que la classe d'​implémentation de cette interface (nous prendrons respectivement pour exemple l'​interface ''​IPlateServices''​ et son implémentation ''​PlateServices''​). L'​interface va servir à exposer en web-services uniquement les méthodes voulues et non pas toutes les méthodes présentes dans l'​implémentation. 
 + 
 +Afin d'​exposer ces méthodes en web-services il faut configurer CXF et créer ou modifier 3 fichiers. 
 + 
 +  ​* **springWSAppContext.xml** (si il n'​existe pas ce fichier peut porter un autre nom) : ce fichier permet de déclarer dans Spring le bean de l'​implémentation du web-services (''​PlateServices''​) et de définir ses propriétés (''​delegate''​ est un attribut de la classe). **A noter** : l'​identifiant de ce bean, qui sera utilisé ensuite. 
 +<code xml> 
 + <bean id="​plateServices"​ class="​cea.edyp.platews.services.PlateServices">​ 
 + <​property name="​delegate">​ 
 + <ref bean="​robotPlanningService"></​ref>​ 
 + </​property>​ 
 + </​bean>​ 
 +</​code>​ 
 + 
 +  * **services.xml** : déclaration des services. Pour chaque service à déclarer ​il faut faire une balise ''​simple:​server''​. Les "​champs"​ à compléter sont : 
 +    * id : le nom du serveur du service 
 +    * serviceClass : l'​interface du service (ici //​IPlateServices//​) 
 +    * address : l'​adresse où sera accessible le service sur le serveur. (par exemple, si le serveur d'​application est //​edyp-epims:​8008//​ ce services sera accessible à <​nowiki>​http://​edyp-epims:​8008/​eP-WS/​PlateServices</​nowiki>​) 
 +    * //​simple:​serviceBean//​ -> ref bean : l'​identifiant du bean de l'​implémentation du services (cf configuration du fichier précédant). 
 +<code xml> 
 +<beans xmlns="​http://​www.springframework.org/​schema/​beans"​ 
 + xmlns:​xsi="​http://​www.w3.org/​2001/​XMLSchema-instance"​ 
 + xmlns:​simple="​http://​cxf.apache.org/​simple"​ 
 + xmlns:​soap="​http://​cxf.apache.org/​bindings/​soap"​ 
 + xsi:​schemaLocation="​ 
 + http://​www.springframework.org/​schema/​beans http://​www.springframework.org/​schema/​beans/​spring-beans-2.0.xsd 
 + http://​cxf.apache.org/​bindings/​soap http://​cxf.apache.org/​schemas/​configuration/​soap.xsd 
 + http://​cxf.apache.org/​simple http://​cxf.apache.org/​schemas/​simple.xsd">​ 
 + 
 + 
 + <import resource="​classpath:​META-INF/​cxf/​cxf.xml"​ /> 
 + <import resource="​classpath:​META-INF/​cxf/​cxf-extension-soap.xml"​ /> 
 + <import resource="​classpath:​META-INF/​cxf/​cxf-servlet.xml"​ /> 
 + 
 + <​simple:​server id="​plateServicesEndPoint"​ 
 + serviceClass="​cea.edyp.platews.services.IPlateServices"​ 
 + address="/​PlateServices">​ 
 + <​simple:​serviceBean>​ 
 + <ref bean="​plateServices"​ /> 
 + </​simple:​serviceBean>​ 
 + <​simple:​dataBinding>​ 
 + <bean class="​org.apache.cxf.aegis.databinding.AegisDatabinding"​ /> 
 + </​simple:​dataBinding>​ 
 + </​simple:​server>​ 
 +</​code>​ 
 +Nota: le ''​simple:​dataBinding''​ permet de forcer CXF à utiliser Aegis comme transformateur Java -> XML. Par défaut il utilise JAXB, mais celui-ci s'est révélé, au moment de l'​intégration de CXF au projet, source de bug. 
 + 
 + 
 +  * **web.xml** : il va servir à déclarer les 2 fichiers écrits précédemment ainsi que la servlet de CXF qui interceptera les requêtes.
 <code xml> <code xml>
  <​context-param>​  <​context-param>​
Line 63: Line 118:
  </​servlet-mapping>​  </​servlet-mapping>​
 </​code>​ </​code>​
 +
 +== Test ==
 +En dehors des tests unitaires on peut tester le fonctionnement des web-services en les interrogeant avec des logiciels dédiés. Exemple : [[http://​www.soapui.org/​|SoapUI]]. Afin que le logiciel puisse construire des requêtes pour les services il faut lui donner le WSDL (le fichier de description du service). Celui-ci peut être atteint en ajoutant ''?​WSDL''​ à l'​adresse du web-services. Pour notre exemple précédant l'url du WSDL sera donc <​nowiki>​http://​edyp-epims:​8008/​eP-WS/​PlateServices?​WSDL</​nowiki>​.
 +----
  
 ==== Client Web-services ==== ==== Client Web-services ====
 +=== Création et utilisation ===
 +La méthode de création de client utilisée dans ePims se base sur l'​utilisation des interfaces des web-services. L'​exemple pour cette partie sera pris sur la classe ''​WSDataProvider''​ qui permet d'​interroger les services fournis par ''​PlateServices''​.
 +
 +  * Déclaration du client : il faut que CXF ait connaissance des signatures des méthodes des services qu'il interrogera. Il faut donc, à notre classe ​ d'​accès aux web-services (''​WSDataProvider''​),​ un attribut client du type de l'​interface du services (accessible dans eP-Plate grâce à la librairie de communication eP-CoL).
 +<code java>
 +private IPlateServices client;
 +</​code>​
 +
 +  * Initialisation du client (dans le constructeur de la classe par exemple). Le client va être créé par une fabrique de CXF (''​ClientProxyFactoryBean''​). Il faut lui donner la classe du service (''​IPlateServices''​),​ l'url à interroger (exemple <​nowiki>​http://​edyp-epims:​8008/​eP-WS/​PlateServices</​nowiki>​) et, accessoirement,​ le //​databinding//​ à utiliser (pour des raisons de compatibilité avec le serveur nous utilisons aussi Aegis pour le client). Puis il suffit de demander à la fabrique de créer le client et de l'​affecter à notre attribut précédemment déclaré.
 +<code java>
 +ClientProxyFactoryBean factory = new ClientProxyFactoryBean();​
 +factory.setServiceClass(IPlateServices.class);​
 +factory.setAddress(url.toString());​
 +factory.getServiceFactory().setDataBinding(new AegisDatabinding());​
 +client = (IPlateServices) factory.create(); ​  
 +</​code>​
 +
 +  * Utilisation du client : il suffit d'​appeler la méthode voulu du client. Par exemple si l'on veut récupérer une plaque virtuelle sachant son nom :
 +<code java>
 +IComVirtualPlate results = client.getVirtualPlate(name);​
 +</​code>​
 +CXF lancera automatiquement une requête SOAP correctement formé à l'url donnée à la fabrique, attendra la réponse, la traitera et la fournira comme renvoie de la méthode appelée. :!: **Attention** : les objets renvoyés par CXF sont du bon type mais sont des proxy : ils n'ont que les méthodes d'​accès get/set aux attributs, il faut donc faire une transposition de ces objets en //vrai// objets voulu.
 +
 +
 +----
 +==== Nota Bene - Bugs - Problèmes rencontrés ====
 +  * Nous avons essayez d'​utiliser des ''​endpoint''​ au tout début des l'​implémentation,​ en lieu et place des ''​server''​ (cf le web.xml plus haut) mais ceux-ci générais une erreur au déploiement de l'​application : 
 +    * <​code>​
 +Error creating bean with name '​plateServicesEndPoint':​ Invocation of init method failed; ​
 +nested exception is java.security.AccessControlException:​ access denied (javax.xml.ws.WebServicePermission publishEndpoint )
 +</​code>​
 +    * Apparemment il s'​agirait d'un problème du ''​SecurityManager''​ de Tomcat auquel doit faire appel CXF (spec JEE5) pour autoriser la publication (''​PUBLISH_PERMISSION''​) des ''​endpoint''​.
 +    * La solution appliquée à été d'​utiliser à la place des balises ''​endpoint''​ des ''​server''​ qui eux n'ont pas besoin de PUBLISH_PERMISSION. ​
 +    * Un autre solution aurait été de pouvoir configurer le serveur d'​application pour qu'il accepte la publication des ''​endpoint'',​ mais nous n'​avons pas réussi à le faire. ​
 +
  
wiki/epims4_0m2/developer/cxf_web-services.1205923848.txt.gz · Last modified: 2008/09/24 15:35 (external edit)