L'objectif de ce TP est de mettre en place:
Les développements se feront dans le projet services
du TP3. Si les services du TP3 ne sont pas pleinement fonctionnels, on pourra se contenter d'en faire une version simplifiée (e.g. sans persistance) pour les besoins de ce TP.
Dans les dépendances du projet on utilisera une version >= 3 pour CXF.
Ce TP est à rendre pour le mercredi 17/11/2014 05/11/2014. Le rendu se fera par l'intermédiaire d'un projet forge (on fera attention a bien donner au moins le rôle “reporter” à Emmanuel Coquery et à Lionel Medini) contenant:
target
)
L'identifiant du projet forge (de la forme pxxxxxx-nomprojet) est à saisir dans Tomuss, dans l'UE Tiw5 WebServices, dans la case TP4_F
. On fera attention à tagger la révision correspondant au rendu avec le tag TP4
.
Créer une classe sw.film.vod.services.ClientResource qui implémente les opérations CRUD1) pour la classe client (en utilisant un ClientDAO).
Annoter cette classe via l'|API JAX-RS pour en faire une ressource REST.
Déployer la ressource aux côtés des services du TP3 en utilisant CXF.
Créer une classe sw.film.vod.services.handlers.SimpleLogHandler
contenant le code suivant:
package sw.film.vod.services.handlers; import javax.xml.ws.handler.LogicalHandler; import javax.xml.ws.handler.LogicalMessageContext; import javax.xml.ws.handler.MessageContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SimpleLogHandler implements LogicalHandler<LogicalMessageContext> { private final static Logger LOG = LoggerFactory.getLogger(SimpleLogHandler.class); @Override public void close(MessageContext ctx) { } @Override public boolean handleFault(LogicalMessageContext ctx) { LOG.warn("faute"); return true; } @Override public boolean handleMessage(LogicalMessageContext ctx) { boolean outbound = (Boolean) ctx.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); LOG.info("message "+(outbound?"sortant":"entrant")); return true; } }
Créer un fichier src/main/resources/sw/film/vod/services/handler-chains.xml
contenant:
<?xml version="1.0" encoding="UTF-8"?> <handler-chains xmlns="http://java.sun.com/xml/ns/javaee"> <handler-chain> <handler> <handler-name>sw.film.vod.services.handlers.SimpleLogHandler</handler-name> <handler-class>sw.film.vod.services.handlers.SimpleLogHandler</handler-class> </handler> <!-- handler> <handler-name>un.autre.Handler</handler-name> <handler-class>un.autre.Handler</handler-class> </handler --> </handler-chain> </handler-chains>
Ajouter l'annotation @HandlerChain(file="handler-chains.xml")
dans la classe sw.film.vod.services.VODService
2), déployer le service et tester l'affichage dans les log en appelant le service avec SOAPUI.
Créer un nouveau handler qui récupère dans le header SOAP la valeur de l'élément client-id
et l'injecte dans le contexte (propriété “client-id”). Modifier le handler de log pour afficher cette propriété si elle est présente. Ajouter ce handler dans la chaîne d'interception et modifier le test soapUI de votre service de livraison pour y intégrer le nouveau header et tester.
Créer un handler logique d'authentification qui ajoute une propriété client
contenant un objet Client
correspondant à la propriété client-id
. Si le client n'existe pas, le handler interdit l'accès au service.
Ajouter l'intercepteur dans la chaîne des services et tester. On pourra créer un ensemble de clients pour le test via un test JUnit dans le projet services
en utilisant JPA, ou via toute autre méthode, e.g. utilisation de script d'init SQL, etc.
Ajouter un champ double valeurCompte
dans la classe Client.
Modifier l'API du service (interface IVODService
) de façon à supprimer le paramètre clientId de la méthode access
.
Ajouter un champ de type javax.xml.ws.WebServiceContext
dans la classe d'implémentation du service de vod.
Annoter ce champ avec @Resource
afin que le contexte soit injecté via IoC.
La méthode getMessageContext()
permet alors de récupérer le contexte du message et les propriétés qui ont été ajoutées par les handlers.
Modifier le code métier du service pour:
<note tip>Seules les propriétés dont le scope est MessageContext.Scope.APPLICATION peuvent être accédées dans le bean qui code le service. Il faut donc penser à changer le scope de la propriété client
dans le handler d'authentification via
ctx.setScope("client", Scope.APPLICATION);
</note>
On souhaite sécuriser la ressource REST Client. Utiliser l'API Filters de JAX-RS pour vérifier la présence d'un mot de passe correspondant à celui de l'utilisateur pour toute modification de ce dernier.