XML et Services WEB



XML


Soit une liste des cours AF400 , en HTML :

<h3>Liste des cours AF400 (&copy; Volubis)</h3>
<ul>
<li>&pound;C01.120 <em>(module &pound;cursuspgm)</em> ESPACE ADRESSABLE UNIQUE</li>
<li>&pound;C01.130 <em>(module &pound;cursuspgm)</em> INIT OS/400 (notion d'objet, biblioth&egrave;que)</li>
<li>etc...</li>
</ul>

ce qui s'affiche :

Liste des cours AF400 (© Volubis)

imaginons maintenant la même liste XML

(voir le fichier complet, le source du pgm ayant réalisé cela)

Voici la manière dont RDP, montre ce fichier :

Pour les règles du jeu XML, voir ce cours

 


L'état de l'art est aujourd'hui de travailler dans une architecture dite 3 tiers, c'est à dire en découplant le serveur de traitement (les programmes souvent placés avec le serveur WEB) des données (pouvant être situées sur un serveur éloigné).

Cette technique est implémentée avec les serveurs d'application ou serveurs de servlet.
    Websphere Application Server(WAS) ou TOMCAT par exemple, mais aussi ".NET" de Microsoft.

 

Il s'agit d'écrire des programmes JAVA (ou C#) s'exécutant sur le serveur et non sur le poste client , le serveur d'application assurant le lien entre le serveur WEB et la JVM (machine virtuelle java).Ces programmes java pouvant être des classes autonomes (servlet) générant du HTML :


ou contenus dans des pages JSP : pages HTML faisant références à des objets externes [des beans].

Les pages JSP permettant d'intégrer du HTML (conçu par un graphiste) et du code JAVA (écrit par un développeur) dans un même fichier.


Aujourd'hui, pour une application WEB, l'architecture logique doit être :


 Tout cela étant normalisé aujourd'hui sous le vocable générique de "Web services"

Définitions

liens :

Présentation de l'architecture web-services

(ou services web)


   

Il existe deux types de services WEB

Un web-service : c'est un logiciel qui interagis avec d'autres au moyen de protocoles universels (http, xml...)

Précisions sur SOAP

Précisions sur WSDL

 

Java et les web-services


Et sur nos systèmes I5 et AS400 ?


IBM proposait déja des mécanismes d'appel de programmes (RPG ou COBOL) depuis une application Java : PCML : langage de description du programme
<pcml version="1.0">
 <!-- Create a Data Structure -->
 <struct name ="custinfo" >
   < data name ="Number" type="char" length= " 7"
            usage="inputoutput" init="0014400"> </data>
   < data name ="Name"   type="char" length= " 40"
            usage="inputoutput" init=" "> </data>
 </struct>
 <!-- Program getcust -->
 <program name="getcust"
              path="/ QSYS.lib/MABIB.lib /GETCUST.pgm" >
   < data name ="gotback" type=" struct"
            usage="inputoutput" struct="custinfo"> </data>
 </program >
</pcml>


public static void main(String[] argv)
{
       AS400 as400System = new AS400();
       ProgramCallDocument pcml = null;
       String msgId, msgText;
       Object value = null;
       try {
           System.out. println ("Creating ProgramCallDocument for GetCust pgm.");
           pcml = new ProgramCallDocument(as400System, "GETCUST");
           boolean ok = pcml.callProgram("getcust");
           System.out.println(" rc is---> " + rc);
           if (!ok)
               { /* Retrieve list of AS/400 messages & display them */ }
           el se
               {
                  value = pcml.getValue("getcust.gotback.Name");
                  System.out.println("Customer name: " + value);
               }
       } catch (PcmlException exc) {
           System.out.println("*** Call to getcust failed. ***");
           Sy ste m. exit (0);
       }
       System.exit(0 );
} // end main method


WDS Client V6.01 puis RDI/RDP for SOA proposent maintenant des outils de gestion de services WEB.

1/ Déclaration de vos programmes historiques en services WEB


Avec un assistant


Générant automatiquement le fichier WSDL

2/ et des outils pour tester

Voyez les cours sur les nouveautés WDSC V6 ou WDSC V7 pour plus de précisions.

Enfin, l'intégration de code-opération pour manipuler le XML et l'arrivée d'outils pour travailler sur les sockets (outils IBM ou projets indépendants comme iSockets  ou HTTPApi de Scott Klement ) permettent aujourd'hui de consommer des services WEB depuis un RPG.


voir les liens ci dessous :


V6R1 : IBMi, Integreted Web Application Serveur V7.1

 

 

Il s'agit du nouveau serveur d'application intégré à l'OS pour distribuer les applications Java., remplaçant Tomcat, qui n'est plus fourni avec la V6 et en V5R40, via PTF

 

Ce serveur support JSF, JSP, servlets et services web, et implique peu de ressources et d'administration, c'est le même que celui utilisé par DB2 WebQUERY, il est basé sur OSGI . (vous trouverez plus d'infos à http://www-03.ibm.com/systems/i/software/iws/ et un comparatif entre WAS Express et ce dernier, ici )

 

Lancez le serveur d'administration HTTP, si ce n'est déjà fait par STRTCPSVR *HTTP HTTPSVR(*ADMIN)

Puis loggez vous sur http://<votreas400>:2001/HTTPAdmin/

 

en même temps que la création du serveur d'application, vous allez déployer votre premier service web

Ici un programme W_RECAP de BDVIN0, attendant une zone PR_CODE, et retournant une DS nommée INFOCENTRE,
    ce pgm a été compilé avec PGMINFO(*PCML:*MODULE) , en V5R40 il faut SI27065 pour activer cette option.



Si vos programmes sont dans un ASP indépendant, Utilisez plutôt l'option Browse...

Et indiquez /iASP/QSYS.LIB/mabib.LIB/monpgm.PGM ou monsrvpgm.SRVPGM

ou /iASP est le point de montage de votre ASP indépendant

Indiquez ensuite, le nom publique du service et un texte explicatif

puis, précisez le sens d'utilisation des paramètres (automatiquement découverts par l'assistant grace à PGMINFO)

Si vous avez oublié l'option PGMINFO ou si vous appelez un CL (CLLE et non CLP), il faudra faire référence à un fichier PCML, pour faire apparaitre les paramètres

SI vous voulez lancer un COBOL (non ILE) ou un RPG 3, faite un CLLE qui appelle pour vous.

un fichier PCML devant être structuré comme suit :

<pcml version="4.0"> 
   <program name="MONPGM" path="/QSYS.LIB/MABIB.LIB/MONPGM.PGM"> 
      <data name="P1" type="char"   length="3" usage="inputoutput" /> 
      <data name="P2" type="packed" length="2" precision="0" usage="inputoutput" /> 
   </program> 
 </pcml> 


Dans un ASP indépendant

<pcml version="4.0"> 
   <program name="MONPGM" path="/IASP/QSYS.LIB/MABIB.LIB/MONPGM.PGM"> 
      <data name="P1" type="char"   length="3" usage="inputoutput" /> 
      <data name="P2" type="packed" length="2" precision="0" usage="inputoutput" /> 
   </program> 
 </pcml> 

avec une structure :

<pcml version="4.0"> 
 <!-- exemple avec une structure complexe -->
 <struct name="INFOCENTRE">
   <data name="PR_CODE" type="int" length="4" precision="31" usage="inherit" /> 
   <data name="PR_NOM" type="char" length="50" usage="inherit" /> 
   <data name="PR_TEL" type="char" length="20" usage="inherit" /> 
   <data name="APPEL00001" type="char" length="80" usage="inherit" /> 
   <data name="NBVIN" type="packed" length="3" precision="0" usage="inherit" /> 
   <data name="ENCAVE" type="char" length="3" usage="inherit" /> 
   <data name="CEPAGE" type="char" length="25" usage="inherit" /> 
   <data name="NBCEPAGE" type="packed" length="3" precision="0" usage="inherit" />
 </struct> 
 <!-- le pgm avec ses paramètres -->
 <program name="AVECDS" path="/QSYS.LIB/MABIB.LIB/AVECDS.PGM">
     <data name="PR_CODE" type="packed" length="9" precision="0" usage="inputoutput" />
     <data name="NBPROD" type="int" length="4" precision="31" usage="inputoutput />
     <data name="INFOCENTRE" type="struct" struct="INFOCENTRE" count="500" usage="inputoutput" />
 </program> 
</pcml>

voici les types reconnus par PCML :  char | int | packed | zoned | float | byte | struct


Pour infos, voici un extrait du programme déployé ici, en ce qui concerne les paramètres :

 H PGMINFO(*PCML : *MODULE)
 DPR_code                          S              6  0    
 DINFOCENTRE                     E DS                  qualified   

                                                              
C *entry plist
C parm pr_code
C parm infocentre

 

Les derniers groupes PTF (2009) apportent la possibilité de gérer en variable (integer uniquement) le nombre d'occurrences d'une structure

Indiquez le profil utilisateur qui lancera le programme

indiquez aussi, la liste des bibliothèques à utiliser



Si vous travaillez avec un ASP indépendant, vous saisirez /IASP/QSYS.LIB/AUTREBIB.LIB

et voilà, vérifiez les informations récapitulatives (regardez les ports IP attribués automatiquement)

liste des services (l'assistant créé un exemple nommé ConvertTemp)

Les opérations admises

soit les informations que l'on peut demander :

w_recap, les paramètres retour transmis dans l'enveloppe SOAP
w_recap_XML, les données transmises dans un flux XML

 

Le serveur se créé

Puis, vous basculez automatiquement sur la gestion du serveur d'application de type web services V1.3, cette fois.

Remarquez l'ajout automatique du service exemple convertTemp

Vous pouvez, ici, revenir gérer les services déployés, ou bien, en déployer de nouveaux.


(properties, permet de changer le profil ou d'éditer le fichier WSDL)

le WSDL pouvant être produit dynamiquement ou de manière statique (nouveauté) et donc être édité par vos soins

passez la paramètre "Web service endpoint generation" à Static, appliquez, puis éditer le wsdl.



Important si vous masquez votre Serveur IBM i derrière un nom de domaine public.

Il faudra alors remplacer (par exemple)

   <soap:address location="http://as400.volubis.intra:10030/web/services/W_RECAP"/>

par

   <soap:address location="http://www.volubis.fr:10030/web/services/W_RECAP"/>


Mais surtout, vous pourrez tester votre service web, par le bouton "Test Service"

Choisissez l'opération (w_recap ou w_recap_XML), ici w_recap

Ajoutez un paramètre en entrée, PR _CODE est automatiquement proposé et vous ne pourrez l'ajouter qu'une seule fois

puis ajoutez une valeur (là aussi, une seule occurrence, dans ce cas) et cliquez sur GO

la réponse vous est affichée dans la fenêtre Status

Ci dessous, le résultat de w_recap_XML

 

 

Vous pouvez tester aussi avec des produits standard comme soapUI

Installez et lancez le produit.

Créez un nouveau projet en indiquant les coordonnées pour acquérir le fichier WSDL sur le system i.

renseignez les valeurs envoyées en remplacant les ? par vos données (ici le producteur 45)

lancez (flèche verte en haut à gauche de la fenêtre Request1)


Si vous rencontrez des problèmes, voyez

Octobre 2008, une PTF PTF SI32432 apporte les scripts suivants qui à ce jour ne sont donc pas documentés, dans /Qibm/ProdData/os/webservices/V1/server/bin

createWebServicesServer.sh
deleteWebServicesServer.sh
getWebServiceProperties.sh
getWebServicesServerProperties.sh
installWebService.sh
listWebServices.sh
listWebServicesServers.sh
setWebServiceProperties.sh
setWebServicesServerProperties.sh
startWebService.sh
startWebServicesServer.sh
stopWebService.sh
stopWebServicesServer.sh
uninstallWebService.sh

 

pour le passage en production d'un service WEB, il faut passer en production l'objet *PGM (l'exécutable) et l'enregistrer ensuite par le script installWebService.sh


pour vous familiariser avec les scripts, passez la commande QSH (qui un émulateur de shell UNix sur AS/400) sur une ligne de commande OS/400

puis cd /qibm/proddata/os/webservices/v1/server/bin


ls vous affiche le contenu du répertoire, pwd vous affiche le répertoire en cours, etc...

listWebServices.sh -server WSERVICE, vous affiche les services disponibles d'un serveur donné.

si vous tapez le nom d'un script -help , il vous affiche une aide "limitée" (ainsi que si des paramètres sont manquants) , par exemple :

installWebservice.sh 
     
Command usage: 
   installWebService.sh 
   -server 'server-name' -programObject 'program-object' 
   [-service 'service-name'] [-pcml 'pcml-file'] [-userid 'userid'] 
   [-libraryList 'library-list'] [ -printErrorDetails ] [ -help ] 

   Where: 
   -server is the name of the Web services server in which the service
   will be installed. 
   -programObject is the integrated file system path to the ILE program or 
   service program. For example, '/QSYS.LIB/MYLIB.LIB/MYPGM.[SRVPGM or PGM]'
   -service is the name of Web service to be installed. This parameter is 
   optional. If not specified, the program object name will be used. 
   -pcml is a path to the PCML file. This parameter is optional. If not 
   specified, the program object must contain the PCML data. 
   -userid is the user profile that the Web service will run under. This 
   parameter is optional. If not specified, the Web service will run under 
   the Web services server user profile. 
   -libraryList is a list of libraries, that will be added to the library 
   list prior to invoking the Web service. Each library in the list must 
   be delimited by a colon. This parameter is optional. 
   -printErrorDetails will show additional error information, such as stack 
   traces and error codes, if the command fails. This parameter is optional.
   -help displays the command syntax. This parameter is optional. 


pour passer la commande directement depuis un CL

QSH CMD('/qibm/proddata/os/webservices/V1/server/bin/<votrescript.sh> paramètre1 paramètre2 ...')


2010, le dernier groupe PTF permet de déléguer des droits via l'administration graphique.

Sans cette délégation, il faut être *ALLOBJ et *IOSYSC FG pour administrer les serveurs mais aussi déployer les web services.

Ajoutons un utilisateur à la liste des utilisateurs autorisés :

Il faut ensuite spécifier les droits (globalement par type de serveur ou serveur par serveur)


Enfin, les Groupes PTF de 2012 (SF99115 level 23 et SF99368 level 11) améliorent le serveur de Web service pour le faire utiliser Axis 1.5 (à la place de 1.3)

(voyez ce Wiki pour accéder aux dernières nouveautés)

Une fois installées ces correctifs vous verrez apparaître une option de migration

Vous aurez aussi d'autres options :


En V6R1, et de manière intégrée au système d'exploitation, nous avons des mécanismes pour accéder à un service web depuis le langage RPG (entre autre).

on dit "consommer un service web"...

 

L'exemple fourni par IBM est basé sur le service ConvertTemp automatiquement créé lors de la création du serveur d'application

 

Allez sur la page

 

Si vous le testez, vous voyez (remarquez le paramètre param0, qui est une structure composée d'une seule zone _TEMPIN) :

 

Utilisation en PHP


Débug :

<?php

  $client = new SoapClient("http://AS400S:10030/web/services/ConvertTemp?wsdl");

  $param = array("param0" => array("_TEMPIN" => 100));

  $result = $client->converttemp($param);


  echo "<br>resultat ";

   var_dump($result);


?>

Résultat :

>

Pour accèder à la valeur

<?php

  $client = new SoapClient("http://AS400S:10030/web/services/ConvertTemp?wsdl");

  $param = array("param0" => array("_TEMPIN" => 100));

  $result = $client->converttemp($param);

  echo $result->return->_TEMPOUT;

?>



ATTENTION, sur les dernières versions du serveur de web services les noms des variables ne sont plus précédés de "_", sauf à indiquer enabled ici :




(en cas de doute, vérifiez le fichier .wsdl)

 

Si vous retournez un DS à occurrences -> DIM(xx) , tenez en compte dans votre code

Démo avec notre exemple retournant une DS INFOCENTRE à NBPROD occurrences



affiche



en .NET

Après avoir ajouté une référence web dont l'URL est "http://AS400S:10030/web/services/ConvertTemp?wsdl"

Dim wsTemp As New AS400_Temperature.ConvertTemp
Dim input As New AS400_Temperature.CONVERTTEMPInput

   input._TEMPIN = txtF.text
   Response.Write(wsTemp.converttemp_XML(input))

Par exemple sur l'événement "click" d'un bouton cmdOK (ici libellé Go)

Protected Sub cmdOK_Click(ByVal sender As Object, ByVal e As System.EventArgs)
 Dim wsTemp As New AS400_Temperature.ConvertTemp
 Dim input As New AS400_Temperature.CONVERTTEMPInput

  If txtF.text <> "" Then
     input._TEMPIN = txtF.text
     lblC.Text = wsTemp.converttemp_XML(input)
  End If
End Sub

Résultat

 

Enfin, en RPG :

1/ récupérez le fichier de définition (WSDL) en cliquant sur View definition
(sinon, pour celui-ci uniquement , il est déja présent dans /QIBM/ProdData/OS/WebServices/V1/client)

2 / il faut générer le "stub" soit le programme "proxy" faisant l'interface entre Axis et notre RPG.

pour cela nous utiliserons l'outil WSDL2WS.SH sous shell (STRQSH)

> /QIBM/ProdData/OS/WebServices/V1/Client/bin/wsdl2ws.sh
   -lc -o/myconverttemp
   /QIBM/ProdData/OS/WebServices/V1/Client/samples/ConvertTemp/ConvertTemp.wsdl


   Code generation completed.
$

 

Si vous passez la commande ls, vous devez voir :

$
> ls /myconverttemp
ConvertTempPortType.c CONVERTTEMPInput.c CONVERTTEMPResult.c
ConvertTempPortType.h CONVERTTEMPInput.h CONVERTTEMPResult.h
$

L'utilisation de ces sources C en RPG était assez complexe.


En début 2011 les PTF suivantes SI42234 (V5R40) , SI42236 (V6R10) , SI42235 (v7) apportent un nouvel utilitaire wsdl2rpg

comme le précédent, il se trouve dans QIBM/ProdData/OS/WebServices/V1/Client/bin/

> /QIBM/ProdData/OS/WebServices/V1/Client/bin/wsdl2rpg.sh
   -o/myconvertRPG
   -s/QSYS.LIB/MABIB.LIB/CONVERT.SRVPGM
   /QIBM/ProdData/OS/WebServices/V1/Client/samples/ConvertTemp/ConvertTemp.wsdl


Code generation completed. Generated files in directory
'/myconvertRPG'.

Attempting to create service program...

Service program created. Service program is
'/QSYS.LIB/MABIB.LIB/CONVERT.SRVPGM'.

$

L'option -s demande la création d'un programme de service dans la bibliothèque MABIB.

Cette fois il génère aussi du RPG, soit 6 fichiers en plus, portant le nom du type de port (ConvertTempPortType dans nos exemples)

ConvertTempPortType.CL le CL de création du *SRVPGM
ConvertTempPortType.rpgleinc fichier à inclure (dans votre programme)
ConvertTempPortType.rpgle le code d'invoquation du web service (*SRVPGM)
ConvertTempPortType_util.rpgleinc fichier à inclure (dans le source suivant)
ConvertTempPortType_util.rpgle divers utilitaires
ConvertTempPortType__xsdtypes.rpgleinc différents types de données standards

le fichier de référence est le xxxxxxxx.PortType.rpgleinc (ConvertTempPortType.rpgleinc) qui contient les définitions dont vous avez besoin, et qu'il faut inclure dans votre code :

xxxxxxxx représentant le nom du service tel que défini dans "http://AS400S:10030/web/services/xxxxxxxx?wsdl"


Compilez ce source par CRTRPGMOD.

Attention, pour des problèmes de code page, vous devrez peut-être modifier légèrement le fichier à inclure
et remplacer les @ de fin par à, sur les trois fonctions vues plus haut ou bien recompiler le *SRVPGM.

Normalement, les dernières PTF corrigent ce bug, l'opération n'est plus utile.

 

 

Si vous devez travailler en HTTPS (avec un certificat)

 

  1. Allez cherche le certificat sur le serveur concerné
  2. Installez le certficat sous Digital Certificat Manager
  3. Dans votre code, utilisez l'API axiscStubSetSecure(), après avoir ajouté le /copy
  /copy /QIBM/ProdData/OS/WebServices/V1/client/include/Axis.rpgleinc
  * qui contient
 D* axiscStubSetSecure...
D* PR EXTPROC('axiscStubSetSecure')
D* pStub * Value
D* pKeyRingFile * Value OPTIONS(*STRING)
D* pKeyRingSorP * Value OPTIONS(*STRING : *NOPASS)
D* pKeyRingLabel * Value OPTIONS(*STRING : *NOPASS)
D* pV2Cipher * Value OPTIONS(*STRING : *NOPASS)
D* pV3Cipher * Value OPTIONS(*STRING : *NOPASS)
D* pTLSCipher * Value OPTIONS(*STRING : *NOPASS) /free if stub_create_convertTempPortType; axiscStubSetSecure(WsStub.handle:
'/QIBM/USERDATA/ICSS/CERT/SERVER/DEFAULT.KDB': 'motdepasse': 'label':'NONE':'05':'NONE');

Si vous recevez HTTPTransportException: HTTPS transport error.GSKit Error is 428 - No certificate is available for SSL processing.
  ne mettez rien 3eme paramètre (remplacez motdepasse par une chaine vide)

 

Si vous rencontrez des problèmes, lancez une trace par axiscAxisStartTrace(’/tmp/axis.log’:*NULL) en début de pgm.

 

tous les détails sur ces API : http://www-03.ibm.com/systems/resources/systems_i_software_iws_pdf_WebServicesClient_new.pdf


Dernier point, vous devez linker tout ce petit monde, par :

 

Essayons le pgm : .

 

Cette nouvelle version, permet un code RPG relativement simple et lisible.


Si vous préférez utiliser SQL, la PTF SF99701 level 23 propose une consommation de web services via des fonctions dans SYSTOOLS

le but de ces fonctions est de consommer des services web plutôt orientés REST


Regardons à travers des exemples

Values SYSTOOLS.HTTPGETCLOB('http://www.volubis.fr' ,'') ;
  


Récupère dans une variable le contenu de notre page d'accueil




Si le site retourne du XML, l'utilisation de la fonction XMLTABLE permettera de ne recevoir que les données utiles

Ici, le site www.redbooks.ibm.com propose des flux RSS donnant les publications récentes


le code

SELECT *
 FROM XMLTABLE('$result/rss/channel/item' 
 PASSING XMLPARSE(
  DOCUMENT 
     SYSTOOLS.HTTPGETBLOB('http://www.redbooks.ibm.com/rss/iseries.xml','')
  ) as "result"
 COLUMNS 
  title VARCHAR(128) PATH 'title',
  description VARCHAR(1024) PATH 'description',
  link VARCHAR(255) PATH 'link',
  pubDate VARCHAR(20) PATH 'substring(pubDate, 1, 16)'
 ) AS RESULT; 
  

permet de lire les données de manière structurée :


Ce code permet de lire le fichier cours.xml , s'il est disponible via HTTP

SELECT cours, texte, motcle1,  monthname(modif) concat '-' concat year(modif)
 FROM XMLTABLE('$result/AF400/COURS' 
  PASSING XMLPARSE( 
  DOCUMENT 
   SYSTOOLS.HTTPGETBLOB('http://as400.volubis.intra/af4dir/courshtm/XML/cours.xml','')
 ) as "result"
 COLUMNS 
  cours CHAR(10) PATH 'AF4MBR',
  texte CHAR(50) PATH 'AF4TXT',
  motcle1 VARCHAR(20) PATH 'MOTCL1',
  MODIF DATE PATH 'DATOUT'
 ) AS TABLEXML;  

Ce code permet de le lire via HTTP, la page étant protégée par un mot de passe

-- LECTURE fichier XML via INTERNET avec authentification
SELECT cours, texte, motcle1, monthname(modif) concat '-' concat year(modif)
FROM XMLTABLE('$result/AF400/COURS'
PASSING XMLPARSE(
DOCUMENT
SYSTOOLS.HTTPGETBLOB('http://af400:motdepasse@as400.volubis.fr/af4dir/courshtm/XML/cours.xml','')
) as "result"
COLUMNS
cours CHAR(10) PATH 'AF4MBR',
texte CHAR(50) PATH 'AF4TXT',
motcle1 VARCHAR(20) PATH 'MOTCL1',
MODIF DATE PATH 'DATOUT'
) AS TABLEXML;

Sur la base d'un service ayant ce fichier WSDL : http://www.webservicex.net/stockquote.asmx?WSDL

et qui générère sous SoapUI :


 cette enveloppe SOAP en entrée
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET/">
  <soapenv:Header/>
    <soapenv:Body>
       <web:GetQuote>
           <web:symbol>IBM</web:symbol>
      </web:GetQuote>
  </soapenv:Body>
</soapenv:Envelope>

Appel d'un Web service, utilisation du deuxième paramètre permettant de fournir les entêtes http,
le troisème contenant la demande, soit l'enveloppe SOAP. (ici, nous demandons la valeur de l'action IBM à aujourd'hui dans une enveloppe SOAP)

-- Appel d'un web service , récupération de l'enveloppe SOAP réponse dans une variable
VALUES SYSTOOLS.HTTPPOSTCLOB('http://www.webservicex.net//stockquote.asmx',
CAST ('<httpHeader>
<header name="Content-Type" value="text/xml;charset=utf-8"/>
<header name="SOAPAction" value="&quot;http://www.webserviceX.NET/GetQuote&quot;"/>
</httpHeader>' AS CLOB(1K)),
CAST('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetQuote xmlns="http://www.webserviceX.NET/">
<symbol>IBM</symbol>
</GetQuote>
</soap:Body>
</soap:Envelope>' AS CLOB(10K)) ) ;
SoapUI nous montre l'enveoppe Soap en sortie, comme ceci :

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <soap:Body>
  <GetQuoteResponse xmlns="http://www.webserviceX.NET/">
   <GetQuoteResult>

    <![CDATA[
      <StockQuotes><Stock> <Symbol>IBM</Symbol><Last>182.46</Last><Date>11/14/2013</Date>
      <Time>12:08pm</Time><Change>-1.09</Change><Open>180.63</Open><High>182.90</High><Low>179.66</Low>
     <Volume>3474990</Volume><MktCap>198.1B</MktCap><PreviousClose>183.55</PreviousClose>
     <PercentageChange>-0.59%</PercentageChange><AnnRange>172.57 - 215.90</AnnRange><Earns>14.439</Earns>
    <P-E>12.71</P-E><Name>International Bus</Name></Stock></StockQuotes>
    ]]>

   </GetQuoteResult>
  </GetQuoteResponse>
 </soap:Body>
</soap:Envelope>

-- Appel d'un web service , récupération de l'enveloppe SOAP, "parsée"
-- il y a des espaces de nommage (xmlns) SOAP et d'autres propres au web service, d'où -> *:
-- les données extraites sont elles mêmes au format XML (on voit que l'action est à 210 $ 55 ) SELECT* FROM XMLTABLE('$result/*:Envelope/*:Body/*:GetQuoteResponse' PASSING XMLPARSE( DOCUMENT SYSTOOLS.HTTPPOSTCLOB('http://www.webservicex.net//stockquote.asmx', CAST ('<httpHeader> <header name="Content-Type" value="text/xml;charset=utf-8"/> <header name="SOAPAction" value="&quot;http://www.webserviceX.NET/GetQuote&quot;"/> </httpHeader>' AS CLOB(1K)), CAST('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <GetQuote xmlns="http://www.webserviceX.NET/"> <symbol>IBM</symbol> </GetQuote> </soap:Body> </soap:Envelope>' AS CLOB(10K)) ) ) as "result" COLUMNS resultat VARCHAR(2000) PATH '*:GetQuoteResult' ) AS TABLEXML;
-- Appel d'un web service , récupération de l'enveloppe SOAP, "parsée" pour lire le montant de l'action
-- puis découpage du XML extrait (présent dans CDATA[ ] )  à nouveau par la fonction XMLTABLE
<![CDATA[
         <StockQuotes>
           <Stock><Symbol>IBM</Symbol><Last>182.46</Last><Date>11/14/2013</Date>
           <Time>12:08pm</Time><Change>-1.09</Change><Open>180.63</Open><High>182.90</High><Low>179.66</Low>
           <Volume>3474990</Volume><MktCap>198.1B</MktCap><PreviousClose>183.55</PreviousClose>
           <PercentageChange>-0.59%</PercentageChange><AnnRange>172.57 - 215.90</AnnRange><Earns>14.439</Earns>
          <P-E>12.71</P-E><Name>International Bus</Name></Stock>
</StockQuotes> ]]>
WITH temp as (SELECT resultat
     FROM XMLTABLE('$result/*:Envelope/*:Body/*:GetQuoteResponse'
     PASSING XMLPARSE(
     DOCUMENT 
     SYSTOOLS.HTTPPOSTCLOB('http://www.webservicex.net//stockquote.asmx',
     CAST ('<httpHeader>
           <header name="Content-Type" value="text/xml;charset=utf-8"/>
           <header name="SOAPAction" value="&quot;http://www.webserviceX.NET/GetQuote&quot;"/>
           </httpHeader>' AS CLOB(1K)),
     CAST('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
            <soap:Body>
              <GetQuote xmlns="http://www.webserviceX.NET/">
               <symbol>IBM</symbol> 
              </GetQuote>
            </soap:Body>
           </soap:Envelope>' AS CLOB(10K))  ) 
     ) as "result"
     COLUMNS 
      resultat  VARCHAR(2000) PATH '*:GetQuoteResult'
     ) AS TABLEXML
   )
select * from temp, 
     XMLTABLE ('$c/StockQuotes/Stock' passing XMLPARSE(DOCUMENT RESULTAT) as "c"
     COLUMNS 
     symbol     CHAR(30)    PATH 'Symbol',
     prix 	dec(11, 2 )    PATH 'Last' 
) AS X ;


Ces fonctions peuvent être utilisées pour lire le résultat produit par XMLSERVICE (vu plus haut)

Rappel

 

Lancement d'une commande PASE

Résultat

-- Appel XMLSERVICE avec une commande PASE
Values SYSTOOLS.HTTPPOSTCLOB('http://as400/cgi-xml/xmlcgi.pgm' ,
CAST ('<httpHeader>
 <header name="Content-Type" value="application/x-www-form-urlencoded"/>
 </httpHeader>' 
AS CLOB(1K)),
CAST('db2=AS400&uid=NOBODY&pwd=nopwd&ipc=/tmp/htmlxml&ctl=*sbmjob
&xmlin=<?xml version=''1.0''?><script><sh rows=''on''>/QOpenSys/usr/bin/uname -a</sh></script>
&xmlout=500000' AS CLOB(10K)) )
Affiche
   


-- Appel XMLSERVICE avec une commande WRKACTJOB via PASE
 SELECT *
  FROM XMLTABLE('$result/script/sh/row' 
  PASSING 
  XMLPARSE(DOCUMENT 
           SYSTOOLS.HTTPPOSTCLOB('http://as400/cgi-xml/xmlcgi.pgm' ,
            CAST ('<httpHeader>
                   <header name="Content-Type" value="application/x-www-form-urlencoded"/>
                   </httpHeader>' 
           AS CLOB(1K)),
           CAST('db2=AS400&uid=NOBODY&pwd=nopwd&ipc=/tmp/htmlxml&ctl=*sbmjob
&xmlin=<?xml version=''1.0''?><script><sh rows=''on''>/QOpenSys/usr/bin/system -i wrkactjob</sh></script>
&xmlout=500000' AS CLOB(10K)) ) ) AS "result" COLUMNS ligne VARCHAR(132) PATH '.' ) AS reponse; ;
Affiche



httpGetBlobVerbose
httpGetClobVerbose
httpPutBlobVerbose
httpPutClobVerbose
httpPostBlobVerbose
httpPostClobVerbose
httpDeleteBlobVerbose
httpDeleteClobVerbose
httpBlobVerbose
httpClobVerbose
httpHeadVerbose



 Attention

Toutes ces fonctions sont livrées dans SYSTOOLS, donc "as is' et ne peuvent faire l'objet d'une demande de support

 

 

Copyright © 1995,2013 VOLUBIS