modele
Ce TP est à rendre pour le 23/10/2011, à raison d'un rendu par binôme.
Il est demandé de rendre le TP sous forme d'un dépôt Mercurial qui aura été initialisé en clonant le dépôt indiqué ci-dessous. Mercurial est un gestionnaire de version, au même titre que par exemple git. A la différence de svn ou CVS c'est système décentralisé, permettant de réaliser des commit sans connexion avec un quelconque serveur central. Une introduction rapide à Mercurial est à disposition ici.
hg push url-du-depot-distant
hg clone mon-repertoire-de-dev le-repertoire-a-zipper
puis zipper le répertoire ainsi obtenu;
mvn clean
dans le projet racine (projet
) avant la compression, en ayant quitter l'environnement de développement afin d'éviter toute recompilation intempestive.
Mettre à jour le projet de base:
hg pull https://forge.univ-lyon1.fr/hg/tiw5-2011-tp-base
Importer le projet services-impl
dans le workspace Eclipse.
etudiant
/etudiant
ayant accès au schéma public de la base postgres
.Ajouter, si ce n'est déjà fait, un serveur tomcat 7.0 à votre configuration Eclipse2).
Créer un fichier src/main/webapp/META-INF/context.xml
dans le projet web-interface
:
<Context> <Resource auth="Container" driverClassName="org.postgresql.Driver" maxActive="100" maxIdle="30" maxWait="10000" name="jdbc/EtudiantDS" password="etudiant" type="javax.sql.DataSource" url="jdbc:postgresql:postgres" username="etudiant" /> </Context>
Dans le projet web-interface
, ajouter le code suivant au fichier web.xml
:
<resource-ref> <res-ref-name>jdbc/EtudiantDS</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>
et créer un fichier src/main/webapp/WEB-INF/classes/META-INF/persistence.xml
:
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="etudiant"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <non-jta-data-source>java:/comp/env/jdbc/EtudiantDS</non-jta-data-source> <class>tiw5.modele.Album</class> <class>tiw5.modele.Piste</class> <class>tiw5.modele.Artiste</class> <properties> <property name="hibernate.hbm2ddl.auto" value="update"/> <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/> </properties> </persistence-unit> </persistence>
Dans ce TP, on utilisera Apache CXF comme implémentation de JAX-WS.
Dans le projet services-impl
, créer un répertoire src/main/java
et ajouter ce répertoire au sources dans Eclipse3). Y créer une classe tiw5.services.impl.AlbumDataService
sur le modèle suivant:
package tiw5.services.impl; import javax.jws.Oneway; import javax.jws.WebMethod; import javax.jws.WebService; import javax.persistence.EntityManager; import javax.persistence.Persistence; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import tiw5.modele.Album; import tiw5.modele.Artiste; @WebService(targetNamespace = "http://master-info.univ-lyon1.fr/M2TI/TIW5/services", serviceName = "AlbumDataService", name = "AlbumDataPortType", portName = "AlbumDataPort") public class AlbumDataService { private static final Logger log = LoggerFactory.getLogger(AlbumDataService.class); @WebMethod public Album getAlbumDescription(long albumId) { EntityManager em = Persistence.createEntityManagerFactory("etudiant") .createEntityManager(); Album album = em.find(Album.class, albumId); return album; } @Oneway @WebMethod public void addAlbumDescription(Album album) { EntityManager em = Persistence.createEntityManagerFactory("etudiant") .createEntityManager(); em.getTransaction().begin(); if (em.find(Album.class, album.getId()) != null) { log.info("found {}",album.getId()); em.merge(album); } else { log.info("did not found {}",album.getId()); em.persist(album); } for(Artiste a : album.getArtistes()) { if (em.find(Artiste.class, a.getUri()) != null) { em.merge(a); } else { em.persist(a); } } em.getTransaction().commit(); } }
Dans le projet web-interface
ajouter au fichier web.xml
le code suivant4):
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:/services.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <display-name>CXF Servlet</display-name> <servlet-name>CXFServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping>
créer le fichier src/main/webapp/WEB-INF/classes/services.xml
:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.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"/> <jaxws:endpoint id="album-data" implementor="tiw5.services.impl.AlbumDataService" address="/AlbumDataService"/> </beans>
Vérifier que le fichier pom.xml
contient les dépendances suivantes:
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>tiw5</groupId> <artifactId>modele</artifactId> <version>1.0-SNAPSHOT</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>tiw5</groupId> <artifactId>services-impl</artifactId> <version>1.0-SNAPSHOT</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>${cxf.version}</version> <type>jar</type> <scope>runtime</scope> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>${cxf.version}</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>3.6.7.Final</version> <type>jar</type> <scope>runtime</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.6.2</version> <type>jar</type> <scope>runtime</scope> </dependency> <dependency> <groupId>postgresql</groupId> <artifactId>postgresql</artifactId> <version>9.0-801.jdbc4</version> <type>jar</type> <scope>runtime</scope> </dependency> </dependencies> <properties> <cxf.version>2.4.2</cxf.version> </properties>
Exécuter l'application web dans le tomcat configuré dans Eclipse, vérifier le bon déploiement ici: http://localhost:8080/web-interface/services/ et comprendre le fichier WSDL associé au service déployer. Le comparer à la classe AlbumDataService
pour comprendre le rôle des différentes annotations qui y sont utilisées.
Créer un nouveau projet soapUI5) et indiquer l'adresse du WSDL généré par CXF. Remplir les données des requêtes prédéfinies et les exécuter pour tester le service.
src/main/resources/album-data.wsdl
du projet client
.pom.xml
de ce projet pour y ajouter le code permettant de générer un client pour ce service via apache CXF, en utilisant la documentation ici et là.@XmlRootElement
et servir de point de départ à une (dé)sérialisation6).disponible
: indique si le stock contient encore des disques correspondant au numéro passé en argument.assureCapacite
: prend une liste de couples (numéro d'album, quantité) et assure que la quantité requise est disponible pour chaque album.commande
: prend une liste de numéros d'albums et retire 1 à la quantité disponible de chaque album listé.assureCapacite
pourra se faire par simple mise à jour du nombre de disques disponibles.web-interface
.