Barre Formation IN2P3
École franco-maghrébine 2003 WebServices 13-17 octobre 2003

Travaux pratiques

Précédent

tp3b

Suivant

Enoncé :

Avant de permettre une réservation, il serait intéressant d'identifier le client (login/password).
Un WS doit pouvoir facilement être réalisé en ce sens. Une fois la personne identifiée, il est alors intéressant de conserver cette information (la personne s'est identifiée correctement) lors des appels aux autres WS (notamment réservation d'une salle) et sinon, interdire l'accès à ces autres WS.
Pour permettre de conserver cette information (authentifiée ou non) je propose d'utiliser un mécanisme de session non-http (plus dur à implémenter qu'une session http, mais portable et plus intéressant).
Les sessions non-http passent par l'utilisation de classes Axis particulières et par un identifiant de session stocké dans l'en-tête du message SOAP.

Aide :

Utiliser un mécanisme de session. Travailler le document WSDL (ce sera nécessaire pour décrire l'identifiant de session).

Correction :

La première est d'implémenter le mécanisme dans le service WEB.

Contenu du fichier tp3b/ReservationWS3b.java.

package tp3b;

import org.dom4j.io.*;
import org.dom4j.*;
import java.util.*;
import java.io.*;
import javax.naming.*;
import org.apache.axis.*;
import org.apache.axis.session.*;

public class ReservationWS3b {
    static HashMap mapSalle = new HashMap();
    static HashMap mapAmpm = new HashMap();
    static HashMap mapJour = new HashMap();
    static {
        Salle salle = new Salle();
        salle.setNomSalle("Bleuet");
        salle.setNumeroSalle(233);
        salle.setNomBatiment("R 2");
        mapSalle.put(new Integer(salle.getNumeroSalle()), salle);
        salle = new Salle();
        salle.setNomSalle("Marguerite");
        salle.setNumeroSalle(224);
        salle.setNomBatiment("R 2");
        mapSalle.put(new Integer(salle.getNumeroSalle()), salle);
        salle = new Salle();
        salle.setNomSalle("Tulipe");
        salle.setNumeroSalle(228);
        salle.setNomBatiment("R 2");
        mapSalle.put(new Integer(salle.getNumeroSalle()), salle);
        mapAmpm.put("am","am");
        mapAmpm.put("pm","pm");
        mapJour.put("lundi","lundi");
        mapJour.put("mardi","mardi");
        mapJour.put("mercredi","mercredi");
        mapJour.put("jeudi","jeudi");
        mapJour.put("vendredi","vendredi");
        mapJour.put("samedi","samedi");
    }
    Node node, node2;
    String xpathexp;
    XPath xpath;
    private MessageContext mc;
    private Session session;

    public ReservationWS3b() {
        mc = MessageContext.getCurrentContext();
        session = mc.getSession();
    }

    public String authentifier(String utilisateur, String motDePasse) {
        if ( ( utilisateur.equals("tomcat") && motDePasse.equals("tomcat") ) ||
             ( utilisateur.equals("admin")  && motDePasse.equals("admin") ) ) {
            session.set("utilisateur",utilisateur);
            return "Authentification correcte";
        } else {
            return "Authentification incorrecte";
        }
    }
    public String reservation(Cours cours, Salle salle, Horaire horaire) throws
HoraireFault,SalleFault,ReservationFault,Exception{

        String utilisateur;
        if (session.get("utilisateur") != null ) {
            utilisateur = (String)session.get("utilisateur");
            if ( utilisateur.equals("tomcat") ) {
                return "vous n'avez pas le privilege de creer des reservations de salle";
            } else if ( utilisateur.equals("admin") ) {
            } else {
                return "utilisateur inconnu";
            }
        } else {
            return "Pas d'authenfication";
        }
        Context initCtx = new InitialContext();
        Context envCtx = (Context) initCtx.lookup("java:comp/env");
        String ab = (String) envCtx.lookup("axis.base");
        String aw = (String) envCtx.lookup("axis.webapp");
        String xmlFile = ab + aw + "/planning.xml";
        System.err.println("xmlFile : " + xmlFile);
        System.err.println("salle.getNumeroSalle() : " + salle.getNumeroSalle());
        if (mapSalle.get(new Integer(salle.getNumeroSalle())) == null) throw new SalleFault("Cette salle
n'existe pas");
        if (horaire.getNumeroSemaine()<0 || horaire.getNumeroSemaine()>52) throw new HoraireFault("Cette
semaine n'exite pas");
        if (mapAmpm.get(horaire.getAmpm()) == null) throw new HoraireFault("Soit am soit pm.");
        if (mapJour.get(horaire.getNomJour()) == null) throw new HoraireFault("le jour de la semaine est
faux.");
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File(xmlFile));
        Map uris = new HashMap();
        uris.put( "planning", "http://in2p3.fr/WS/tp1" );
        xpathexp =	"//planning:semaine[@planning:numerosemaine='"
            + horaire.getNumeroSemaine()
            + "' and planning:salle/planning:nom='"
            + salle.getNomSalle()
            + "']";
        System.err.println(xpathexp);
        xpath = document.createXPath( xpathexp );
        xpath.setNamespaceURIs( uris );
        node = xpath.selectSingleNode( document );
        if (node == null) {
            // il faut créer la semaine pour la salle
            node = document.getRootElement();
            System.err.println("node.getName() : " + node.getName());
            Element semaineE=((Element)node).addElement( "planning:semaine" ,
"http://in2p3.fr/WS/tp1").addAttribute( QName.get("planning:numerosemaine", "http://in2p3.fr/WS/tp1"), new
Integer(horaire.getNumeroSemaine()).toString() );
            Element salleE=semaineE.addElement( "planning:salle" , "http://in2p3.fr/WS/tp1");
            salleE.addElement("planning:nom", "http://in2p3.fr/WS/tp1").addText(salle.getNomSalle());
            salleE.addElement("planning:numero", "http://in2p3.fr/WS/tp1").addText(new
Integer(salle.getNumeroSalle()).toString());
            salleE.addElement("planning:batiment", "http://in2p3.fr/WS/tp1").addText(salle.getNomBatiment());
            semaineE.addElement( "planning:jour", "http://in2p3.fr/WS/tp1").addAttribute(
QName.get("planning:nomjour", "http://in2p3.fr/WS/tp1"),"lundi");
            semaineE.addElement( "planning:jour", "http://in2p3.fr/WS/tp1").addAttribute(
QName.get("planning:nomjour", "http://in2p3.fr/WS/tp1"),"mardi");
            semaineE.addElement( "planning:jour", "http://in2p3.fr/WS/tp1").addAttribute(
QName.get("planning:nomjour", "http://in2p3.fr/WS/tp1"),"mercredi");
            semaineE.addElement( "planning:jour", "http://in2p3.fr/WS/tp1").addAttribute(
QName.get("planning:nomjour", "http://in2p3.fr/WS/tp1"),"jeudi");
            semaineE.addElement( "planning:jour", "http://in2p3.fr/WS/tp1").addAttribute(
QName.get("planning:nomjour", "http://in2p3.fr/WS/tp1"),"vendredi");
            semaineE.addElement( "planning:jour", "http://in2p3.fr/WS/tp1").addAttribute(
QName.get("planning:nomjour", "http://in2p3.fr/WS/tp1"),"samedi");
            node = semaineE;
        }
        System.err.println("node.getName() : " + node.getName());
        // l'horaire est-il deja pris
        xpathexp
=	"child::planning:jour[@planning:nomjour='"+horaire.getNomJour()+"']/planning:"+horaire.getAmpm()+"/planning:cours";
        System.err.println("xpathexp : " + xpathexp);
        xpath = node.createXPath( xpathexp );
        xpath.setNamespaceURIs( uris );
        node2 = xpath.selectSingleNode( node );
        if (node2 != null) throw new ReservationFault("Creneau horaire deja occupe");
        xpathexp =	"child::planning:jour[@planning:nomjour='"+horaire.getNomJour()+"']";
        System.err.println("xpathexp : " + xpathexp);
        xpath = node.createXPath( xpathexp );
        xpath.setNamespaceURIs( uris );
        node2 = xpath.selectSingleNode( node );
        Element ampmE=((Element)node2).addElement( "planning:"+horaire.getAmpm() , "http://in2p3.fr/WS/tp1");
        Element coursE = ampmE.addElement( "planning:cours" , "http://in2p3.fr/WS/tp1");
        coursE.addElement( "planning:intitule" , "http://in2p3.fr/WS/tp1").addText(cours.getIntituleCours());
        coursE.addElement( "planning:responsable" ,
"http://in2p3.fr/WS/tp1").addText(cours.getResponsableCours());
                                                          // on crée le cours et on sauvegarde le fichier xml
        OutputFormat format = OutputFormat.createPrettyPrint();
        XMLWriter writer = new XMLWriter( new FileWriter( xmlFile ), format );
        writer.write( document );
        writer.flush();
        writer.close();
        return "Reservation effectuee.";
    }
    
}

Il faut ensuite utiliser l'outil Java2WSDL afin de générer le fichier "ReservationWS3b" wsdl de ce service. Pour installer ce fichier wsdl dans axis il faut le placer dans le répertoire axis/WEB-INF/classes. Avant de l'installer il faut le modifier.

Contenu du fichier tp3b/ReservationWS3b.wsdl.

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://ReservationWS.tp3b" xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://ReservationWS.tp3b"
xmlns:intf="http://ReservationWS.tp3b" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns1="http://tp3b" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <wsdl:types>
  <schema targetNamespace="http://tp3b" xmlns="http://www.w3.org/2001/XMLSchema">
   <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
   <complexType name="SessionID">
    <xsd:sequence>
        <xsd:element name="ID" minOccurs="1" maxOccurs="1" type="xsd:long"/>
    </xsd:sequence>
   </complexType>
   <complexType name="Cours">
    <sequence>
     <element name="intituleCours" nillable="true" type="xsd:string"/>
     <element name="responsableCours" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <complexType name="Salle">
    <sequence>
     <element name="nomBatiment" nillable="true" type="xsd:string"/>
     <element name="nomSalle" nillable="true" type="xsd:string"/>
     <element name="numeroSalle" type="xsd:int"/>
    </sequence>
   </complexType>
   <complexType name="Horaire">
    <sequence>
     <element name="ampm" nillable="true" type="xsd:string"/>
     <element name="nomJour" nillable="true" type="xsd:string"/>
     <element name="numeroSemaine" type="xsd:int"/>
    </sequence>
   </complexType>
   <complexType name="HoraireFault">
    <sequence>
     <element name="info" nillable="true" type="xsd:string"/>
     <element name="message" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <complexType name="SalleFault">
    <sequence>
     <element name="info" nillable="true" type="xsd:string"/>
     <element name="message" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <complexType name="ReservationFault">
    <sequence>
     <element name="info" nillable="true" type="xsd:string"/>
     <element name="message" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
  </schema>
 </wsdl:types>

    <wsdl:message name="sessionID">
        <wsdl:part name="SessionID" type="tns1:SessionID"/>
    </wsdl:message>
    
   <wsdl:message name="HoraireFault">

      <wsdl:part name="fault" type="tns1:HoraireFault"/>

   </wsdl:message>

   <wsdl:message name="reservationRequest">

      <wsdl:part name="in0" type="tns1:Cours"/>

      <wsdl:part name="in1" type="tns1:Salle"/>

      <wsdl:part name="in2" type="tns1:Horaire"/>

   </wsdl:message>

   <wsdl:message name="SalleFault">

      <wsdl:part name="fault" type="tns1:SalleFault"/>

   </wsdl:message>

   <wsdl:message name="reservationResponse">

      <wsdl:part name="reservationReturn" type="xsd:string"/>

   </wsdl:message>

   <wsdl:message name="authentifierRequest">

      <wsdl:part name="in0" type="xsd:string"/>

      <wsdl:part name="in1" type="xsd:string"/>

   </wsdl:message>

   <wsdl:message name="ReservationFault">

      <wsdl:part name="fault" type="tns1:ReservationFault"/>

   </wsdl:message>

   <wsdl:message name="authentifierResponse">

      <wsdl:part name="authentifierReturn" type="xsd:string"/>

   </wsdl:message>

   <wsdl:portType name="ReservationWS3b">

      <wsdl:operation name="authentifier" parameterOrder="in0 in1">
      
         <wsdl:input message="impl:authentifierRequest" name="authentifierRequest"/>

         <wsdl:output message="impl:authentifierResponse" name="authentifierResponse"/>

      </wsdl:operation>

      <wsdl:operation name="reservation" parameterOrder="in0 in1 in2">

         <wsdl:input message="impl:reservationRequest" name="reservationRequest"/>

         <wsdl:output message="impl:reservationResponse" name="reservationResponse"/>

         <wsdl:fault message="impl:ReservationFault" name="ReservationFault"/>

         <wsdl:fault message="impl:SalleFault" name="SalleFault"/>

         <wsdl:fault message="impl:HoraireFault" name="HoraireFault"/>

      </wsdl:operation>

   </wsdl:portType>

   <wsdl:binding name="ReservationWS3bSoapBinding" type="impl:ReservationWS3b">

      <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>

      <wsdl:operation name="authentifier">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="authentifierRequest">

            <wsdlsoap:header use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://xml.apache.org/axis/session" message="intf:sessionID" part="SessionID"/>
            <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://ReservationWS.tp3b" use="encoded"/>

         </wsdl:input>

         <wsdl:output name="authentifierResponse">

            <wsdlsoap:header use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://xml.apache.org/axis/session" message="intf:sessionID" part="SessionID"/>
            <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://ReservationWS.tp3b" use="encoded"/>

         </wsdl:output>

      </wsdl:operation>

      <wsdl:operation name="reservation">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="reservationRequest">

            <wsdlsoap:header use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://xml.apache.org/axis/session" message="intf:sessionID" part="SessionID"/>
            <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://ReservationWS.tp3b" use="encoded"/>

         </wsdl:input>

         <wsdl:output name="reservationResponse">

            <wsdlsoap:header use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://xml.apache.org/axis/session" message="intf:sessionID" part="SessionID"/>
            <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://ReservationWS.tp3b" use="encoded"/>

         </wsdl:output>

         <wsdl:fault name="ReservationFault">

            <wsdlsoap:fault encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://ReservationWS.tp3b" use="encoded"/>

         </wsdl:fault>

         <wsdl:fault name="SalleFault">

            <wsdlsoap:fault encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://ReservationWS.tp3b" use="encoded"/>

         </wsdl:fault>

         <wsdl:fault name="HoraireFault">

            <wsdlsoap:fault encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://ReservationWS.tp3b" use="encoded"/>

         </wsdl:fault>

      </wsdl:operation>

   </wsdl:binding>

   <wsdl:service name="ReservationWS3bService">

      <wsdl:port binding="impl:ReservationWS3bSoapBinding" name="ReservationWS3b">

         <wsdlsoap:address location="http://localhost:8080/axis/services/ReservationWS3b"/>

      </wsdl:port>

   </wsdl:service>

</wsdl:definitions>

En utilisant l'outil WSDL2Java, vous pouvez générer le code servant au client puis il faut l'écrire, le client utilise une technique d'axis permettant d'utiliser des "handlers" côté client.

Contenu du fichier tp3bclient/ReservationClient.java.

package tp3bclient;
import org.apache.axis.*;
import org.apache.axis.session.*;
import org.apache.axis.handlers.*;
import org.apache.axis.client.*;
import org.apache.axis.transport.http.*;
import org.apache.axis.configuration.*;
public class ReservationClient {

    public static EngineConfiguration createClientConfig()
    {
        SimpleProvider clientConfig=new SimpleProvider();
        Handler sessionHandler=(Handler)new SimpleSessionHandler();
        SimpleChain reqHandler=new SimpleChain();
        SimpleChain respHandler=new SimpleChain();
        reqHandler.addHandler(sessionHandler);
        respHandler.addHandler(sessionHandler);
        Handler pivot=(Handler)new HTTPSender();
        Handler transport=new SimpleTargetedChain(reqHandler, pivot, respHandler);
        clientConfig.deployTransport(HTTPTransport.DEFAULT_TRANSPORT_NAME,transport);

        return clientConfig;
    }
    
    public static void main(String args[]) {
        try {
            EngineConfiguration clientConfig=ReservationClient.createClientConfig();
            ReservationWS3BService rws = new ReservationWS3BServiceLocator();
            ((org.apache.axis.client.Service )rws).setEngineConfiguration(clientConfig);
            ((org.apache.axis.client.Service )rws).setEngine(new AxisClient(clientConfig));
            ((org.apache.axis.client.Service )rws).setMaintainSession(true);
            ReservationWS3B rw = rws.getReservationWS3b();
            
            System.out.println(rw.authentifier("admin","admin"));
            
            
            Salle salle = new Salle();
            Horaire horaire = new Horaire();
            Cours cours = new Cours();

            salle.setNumeroSalle(233);
            salle.setNomSalle("Bleuet");
            salle.setNomBatiment("R 2");
            horaire.setAmpm("am");
            horaire.setNumeroSemaine(26);
            horaire.setNomJour("mardi");
            cours.setIntituleCours("WebServices");
            cours.setResponsableCours("Jean Pars");
            
            System.out.println(rw.reservation(cours, salle, horaire));
        } catch (ReservationFault af) {
            System.err.println(af.getInfo());
        } catch (HoraireFault af) {
            System.err.println(af.getInfo());
        } catch (SalleFault af) {
            System.err.println(af.getInfo());
        } catch (AxisFault af) {
            System.err.println(af.dumpToString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

École franco-maghrébine 2003 WebServices 13-17 octobre 2003