CEC 2012 Vienna Forum Francophone Power IBM i ( et AS/400, iSeries, System i, ... )
Forum Francophone Power IBM i ( et AS/400, iSeries, System i,  ... )   Forum Francophone Power IBM i ( et AS/400, iSeries, System i,  ... )   Forum Francophone Power IBM i ( et AS/400, iSeries, System i,  ... )   Forum Francophone Power IBM i ( et AS/400, iSeries, System i,  ... )
18 Mai,2012, 22:40:29 *
Bienvenue, Invité. Veuillez vous connecter ou vous inscrire.
Avez-vous perdu votre courriel d'activation?

Connexion avec identifiant, mot de passe et durée de la session
Nouvelles:
 
   Accueil   Aide Règles Rechercher Partenaires Identifiez-vous Inscrivez-vous Liens Common France Common Belgique Common Luxembourg  
Pages: [1]   Bas de page
  Imprimer  
Auteur Fil de discussion: [RPGLE] Didacticiel : Créer un flux RSS en RPG CGI (1/3)  (Lu 2070 fois) Average Rating: 3
0 Membres et 1 Invité sur ce fil de discussion.
jmpenasse
Administrator
Membre Héroïque
*****
Hors ligne Hors ligne

Messages: 344




i_SilverDev http://fr.linkedin.com/in/jmpenasse
Voir le profil WWW
« le: 24 Janvier,2009, 04:27:38 »

Un programme "CGI" (Common Gateway Interface" est un programme qui sera appelé à la place d'une page web statique (.html) pour créer dynamiquement un contenu. En général ce contenu est du html, mais il peut être tout autre chose. Nous allons voir comment réaliser un programme RPG (IV ILE) pour créer un flux RSS simple affichant les derniers messages de QSYSOPR.

Ce petit didacticiel sera décomposé en 3 parties (3 sujet différents sur le forum) :
  • Cette première partie se termine à la réalisation d'un premier programme CGI avec les données en "dur"
  • La deuxième partie évoquera la configuration d'Apache pour l"appel du programme au travers d'un navigateur, ainsi que quelques "readers" de flux.
  • Enfin la troisième partie sera la réalisation complète de notre programme diffusant les derniers messages de QSYSOPR.


Flux RSS
Un flux RSS est un ensemble d'informations, généralement simples, qui est mis à jour régulièrement sur des serveurs ("le feeder") et que l'on peut consulter sur des lecteurs de flux ("reader"). Ces Lecteurs de flux peuvent être des programmes indépendants, mais de plus en plus d'outils intègrent cette technologie permettant de suivre les nouvelles de la  presse, les cours de bourse, les résultats de matchs, ou les derniers messages de forums.
Il est ainsi possible d'afficher les flux directement dans les navigateurs, sur les pages de iGoogle (création de compte nécessaire) ou maintenant dans les "widgets" de Vista (pour n'en citer que 3).
Le flux RSS n'est en faite qu'un simple fichier XML. Il peut être statique sur le serveur : il suffit de recréer régulièrement ce fichier dans le répertoire des pages web du serveur HTTP (Apache), mais il peut également être créer dynamiquement par un programme CGI ou un script (PHP, Perl, ASP, ...).


Structure RSS
Pour commencer, le mieux est de lire les explication de Wikipedia sur les RSS (et de revenir ensuite  Grin ) :
http://fr.wikipedia.org/wiki/RSS_(format)
Pour plus de détails, un des sites de référence est : http://www.rssboard.org/rss-specification
Pour ceux qui n'ont pas eut le courage d'aller s'informer, voici un exemple minimaliste de flux RSS (donné sur Wikipédia) :
Code:
<rss version="2.0">
    <channel>
        <title>Mon site</title>
        <description>Ceci est un exemple de flux RSS 2.0</description>
        <lastBuildDate>Wed, 27 Jul 2005 00:30:30 -0700</lastBuildDate>
        <link>http://www.example.org</link>
        <item>
            <title>Actualité N°1</title>
            <description>Ceci est ma première actualité</description>
            <pubDate>Tue, 19 Jul 2005 04:32:51 -0700</pubDate>
            <link>http://www.example.org/actu1</link>
        </item>
    </channel>
</rss>

Cet exemple ne comprend qu'un élément (item) à diffuser. Mais bien sûr le but est d'en mettre plusieurs. Le principe des RSS est de ne mettre qu'un nombre restreint (les dernières infos importantes). En général de 10 à 15.

Nous allons donc faire un programme RPG qui va créer ce texte XML en répétant les blocs "<item>...</item>' pour les 10 derniers messages de QSYSOPR.
Mais avant d'aller chercher les messages de QSYSOPR, faisons un petit programme qui ne fait qu'envoyer l'équivalent de l'exemple ci-dessus.


RPG CGI
Un programme RPG CGI est en fait un programme RPG 4 tout ce qu'il y a de plus normal, sauf qu'il va utiliser une API particulière : QtmhWrStout. Cette API permet de stocker des caractères dans un buffer internes et de les transmettre ensuite au serveur Apache pour qu'il les fournisse au navigateur de l'utilisateur.
D'autres APIS existent pour recevoir les informations ("paramètres") transmis lors de la demande de l'utilisateur, mais nous ne les aborderons pas ici.
Cette api QtmhWrStout a une contrainte : vous l'aurez remarqué, son nom fait plus de 10 caractères. Ce n'est donc pas un programme (*PGM). En effet c'est une procédure d'un service programme (*SRVPGM). Cela signifie que nous devons l'utiliser dans un programme ILE. RPG IV est un langage ILE, RPG/400 (RPG III) ne l'est pas (c'est de l'OPM).


"Cycle" CGI
Il est relativement facile pour des développeurs ayant l'expérience du RPG II de comprendre le fonctionnement des programmes CGI. En effet cela s'apparente, dans une certaine mesure, à un fichier écran en "Primaire". Donc, lu et écrit automatiquement par le Cycle RPG.
C'est pourquoi l'on parle souvent de "Cycle" CGI.
En effet, un programme CGI est déclenché par la demande d'une URL (les liens Htt p://www...). Il peut y avoir ou non des paramètres ou des infos saisies par l'utilisateur qui devront être traitées par le programme. Notre programme CGI n'affiche donc pas  l'"écran " au démarrage, cela a déjà été fait précédemment.

Tout ce qu'il va devoir faire c'est :
  • analyser les infos en entrée, si nécessaire (nous n'aborderons pas ce point),
  • puis collecter des données dans le système (Fichiers, dtaaras, appels d'autres programmes... du grand classique !)
  • et ensuite créer une grande chaine de caractères mélangeant du HTML et/ou du XML et/ou javascript, etc avec les données récupérées. Cette chaine sera transmise (en une ou plusieurs fois) à l'API QtmhWrStout, qui va stocker le tout dans ses buffer.
ET C'EST TOUT !
Car à la fin du programme, et seulement à ce moment là, le système transmettra (après conversion EBCDIC/ASCII si besoin) au serveur apache le fruit de notre labeur.
Notre programme ne reste donc pas actif. C'est là le gros soucis des pages Web. Le protocole HTTP n'est pas conçu pour faire du conversationnel. La notion de session n'existe pas de base. Il faut soit rajouter des mécanismes lourd pour gérer ça (serveurs d'applications) soir le gérer soi même avec plus ou moins d'aide d'Apache. Mais c'est également un autre problème que nous ne développerons pas ici, car cela ne nous concerne pas pour les flux RSS.


Accéder à l'API QtmhWrStout
Pour pouvoir utiliser l'API QtmhWrStout, il va falloir indiquer au programme qu'il devra la chercher dans un service programme (QHTTPSVR/QZHBCGI). Nous pourrions indiquer cela dans les paramètres de compilation, mais il faudrait refaire l'opération à chaque compil.
Il y a donc un mécanisme qui permet d'enregistrer dans un "Répertoire de liage" (objet *BNDDIR) les objets nécessaires au programme.
Nous allons donc créer un répertoire de liage dans QGPL (ou ailleurs, du moment que le compilateur à la bib en libl) et enregistrer dedans le nom du SRVPGM. Ce répertoire de liage ne sert qu'à la compil. Pas à l'exécution.
Les commandes sont :
Code:
CRTBNDDIR  BNDDIR(QGPL/HTTP) TEXT('Apis HTTP')            
ADDBNDDIRE BNDDIR(QGPL/HTTP) OBJ((QHTTPSVR/QZHBCGI *SRVPGM)

Ensuite la première ligne de notre programme RPG pourra être une spécification H indiquant ce répertoire de liage (qualifié ou non).
Code:
H BNDDIR('HTTP')  

Comme l'API est une procédure, nous allons devoir en faire le "prototype". C'est, grosso modo, la liste des paramètres de la procédure. Comme le nom de l'API est trop difficile à mémoriser (en tout cas pour moi...) j'en profite pour lui donner un nom plus parlant : WriteToWeb.
Code:
D WriteToWeb      PR                  extProc('QtmhWrStout')  
D  WebData                   32000A   Const OPTIONS(*VARSIZE)
D  WebDataLen                   10I 0 Const                  
D  apiError                     16A   OPTIONS(*VARSIZE)      

Je ne vais pas vous décrire chaque ligne, donc voilà le premier programme CGI simple :

Code:
* ---------------------------                                  
 * Creation flux RSS. Doc Reference RSS :                        
 *   http://www.rssboard.org/rss-specification                  
 *   en plus simple : http://fr.wikipedia.org/wiki/RSS_(format)  
 * ---------------------------                                  
 * -- Lien vers les APIs HTTP -----                              
 *  Si elle n'existe pas déjà, la BNDDIR doit être créée :      
 *    CRTBNDDIR  BNDDIR(QGPL/HTTP) TEXT('Apis HTTP')            
 *    ADDBNDDIRE BNDDIR(QGPL/HTTP) OBJ((QHTTPSVR/QZHBCGI *SRVPGM)
 * ---------------------------                                  
H BNDDIR('HTTP')                                                
H Option(*SrcStmt:*NoDebugIO)  DftActGrp(*no)                    
                                                                
 * Prototypes Apis HTTP --------------------------------        
 * * QtmhWrStout : envoi vers le web                            
D WriteToWeb      PR                  extProc('QtmhWrStout')    
D  WebData                   32000A   Const OPTIONS(*VARSIZE)    
D  WebDataLen                   10I 0 Const                      
D  apiError                     16A   OPTIONS(*VARSIZE)          
                                                                
D LF              C                   Const(X'15')              
D apiError        S             16A   Inz(*ALLX'00')            
D Buffer          S          32000A   Varying                    
                                                                
 /Free                                                          
    *INLR = *ON;                                                
                                                                
  // --- En tête -----------------------------                  
                                                                
    Buffer = 'Content-type: text/xml' + LF + LF ;                
    WriteToWeb(Buffer : %len(Buffer) : apiError);                
                                                                
    Buffer = '<?xml version="1.0" encoding="iso-8859-1"?>' + LF;
    Buffer = Buffer + '<rss version="2.0">' + LF;                
    Buffer = Buffer + '<channel>' + LF;                          
                                                                
    Buffer = Buffer + '<title>Flux RSS de test</title>' + LF;    
    Buffer = Buffer + '<description>'                            
                    + 'La description, blablabla...'            
                    + '</description>' + LF;                    
    Buffer = Buffer + '<link>http://www.experia.com</link>' + LF;
    WriteToWeb(Buffer : %len(Buffer) : apiError);                    
                                                                      
  // --- Lignes ------------------------------                        
                                                                      
    Buffer =          '<item>' + LF;                                  
    Buffer = Buffer + ' <title>Titre élément </title>' + LF;          
    Buffer = Buffer + ' <description>Blublublu...</description>' + LF;
    Buffer = Buffer + '</item>' + LF;                                
    WriteToWeb(Buffer : %len(Buffer) : apiError);                    
                                                                      
  // --- Fin ---------------------------------                        
                                                                      
    Buffer =          '</channel>' + LF;                              
    Buffer = Buffer + '</rss>' + LF;                                  
    WriteToWeb(Buffer : %len(Buffer) : apiError);                    
                                                                      
 /End-Free                                                            

Il n'y a que 58 lignes, lignes vides et commentaires compris. Pas bien compliqué, donc.   Wink

Il y a seulement un point particulier à expliquer.
La première ligne ligne transmise au serveur est un "header" et indique le type de contenu de ce qui va suivre.
Pour une page web normal, ce header est : "Content-type: text/html". Dans notre cas, nous allons envoyer du XML, donc nous mettons : "Content-type: text/xml".
Cette ligne doit impérativement être suivie de 2 caractères "fin de ligne" qui en hexa sont X'15'.
Comme nous allons mettre des fins de ligne un peu partout pour que notre code xml soit plus présentable, nous définissons une constante :
Code:
D LF              C                   Const(X'15')  

Vous voyez donc que dans le source nous faisons appel plusieurs fois à l'API. Elle n'affiche rien. Elle ne fait qu'engranger les caractères que nous transmettons. Pour que l'affichage se fasse il faut que le programme se termine.


Tester le programme
Une fois compilé, nous avons bien envie de le tester. Il n'est pas possible de l'appeler par le navigateur sans faire un minimum de configuration dans Apache.
Mais nous pouvons cependant appeler notre programme grâce à une petite astuce (en fait, c'est surtout grâce à la richesse de l'AS/400 Smiley ).
Si vous faites un CALL MONCGI1 en ligne de commande vous allez peut-être (si votre AS n'est pas "trop" rapide) voir apparaitre et disparaitre un écran. Malheureusement il ne reste pas.
Pour voir le résultat de notre programme, il faut l'appeler dans une console "UNIX" (c'est un abus de langage, mais ce n'est pas important).
Pour cela en ligne de commande il faut taper QSH (ou STRSQH) pour arriver sur cette console qui ressemble beaucoup à notre QCMD, mais qui est un "shell" unix.
Nous allons donc appeler notre programme d'ici. Mais ce n'est pas si simple, car il faut indiquer son "chemin" de type "IFS".
Cela va donner quelque chose comme :
/QSYS.LIB/ma-bib.LIB/moncgi1.PGM
mettez le bon nom de bibliothèque à la place de "ma-bib" en gardant le .LIB à la fin et pareil pour le nom de programme.
Faites "entrée" et normalement voici ce qui devrait apparaître :
Code:
 $                                                          
> /QSYS.LIB/ma-bib.LIB/moncgi1.PGM                          
  Content-type: text/xml                                    
                                                            
  <?xml version="1.0" encoding="iso-8859-1"?>                
  <rss version="2.0">                                        
  <channel>                                                  
  <title>Flux RSS de test</title>                            
  <description>La description, blablabla...</description>    
  <link>http://www.experia.com</link>                        
  <item>                                                    
   <title>Titre élément </title>                            
   <description>Blublublu...</description>                  
  </item>                                                    
  </channel>                                                
  </rss>                                                    
  $                                                          
                                                            
===>                                                        

 Cheesy C'est gagné ! le plus dur est fait. Le programme marche !

Pour la suite, revenez nous voir régulièrement  ange

Et pour les remarques, critiques (ou remerciements  Grin) et questions, c'est le lien "Répondre", abusez-en !

Jean-Michel
« Dernière édition: 24 Janvier,2009, 04:57:25 par jmpenasse » Journalisée

Il y a 10 sortes de gens : Ceux qui comprennent le binaire et les autres ...
Jathoba
Néophyte
*
Hors ligne Hors ligne

Messages: 2


Voir le profil
« Répondre #1 le: 19 Janvier,2011, 11:50:52 »

Merci à toi pour ce post, c'est exactement ce que je cherchais !
Journalisée
hermelin
Néophyte
*
Hors ligne Hors ligne

Messages: 2


Voir le profil
« Répondre #2 le: 19 Janvier,2011, 13:25:32 »

Merci ! j'attends la suite avec impatience.
Journalisée
jmpenasse
Administrator
Membre Héroïque
*****
Hors ligne Hors ligne

Messages: 344




i_SilverDev http://fr.linkedin.com/in/jmpenasse
Voir le profil WWW
« Répondre #3 le: 19 Janvier,2011, 18:03:22 »

Bonjour et bienvenue aux nouveaux !

Ravi que ce sujet vous intéresse !
Au moment de la publication de ce sujet, il n'y avait pas eut de réaction, donc je n'avais pas fait la suite promise. Il va me falloir faire quelques fouilles pour rédiger cette suite.
... dès que j'aurai un peu de temps.
Mais si vous avez des questions précises n'hésitez pas !
Journalisée

Il y a 10 sortes de gens : Ceux qui comprennent le binaire et les autres ...
hermelin
Néophyte
*
Hors ligne Hors ligne

Messages: 2


Voir le profil
« Répondre #4 le: 19 Janvier,2011, 19:10:18 »

je n'avais pas vu que le sujet initial datait mais cela va m'aider dans mes projets futurs ! Cela m'a permit de sortir de ma torpeur car je lis ce forum depuis plus d'un an  Wink
Je viens de tester et ca marche très bien sur ma V5R2  Smiley

Hermelin,
Journalisée
Delvekior
Néophyte
*
Hors ligne Hors ligne

Messages: 2

OS:
Windows Vista/Server 2008 Windows Vista/Server 2008
Navigateur:
MS Internet Explorer 8.0 MS Internet Explorer 8.0


Voir le profil
« Répondre #5 le: 08 Août,2011, 12:23:14 »

Bonjour,

Merci pour un début de tutoriel aussi clair !

J'ose espérer, jmpenasse, qu'une suite reste envisagée...

Pourrais-tu nous rassurer (ou malheureusement nous inquiéter) sur ce point ?

Merci d'avance !
Journalisée
jmpenasse
Administrator
Membre Héroïque
*****
Hors ligne Hors ligne

Messages: 344


OS:
Windows XP Windows XP
Navigateur:
Firefox 6.0 Firefox 6.0



i_SilverDev http://fr.linkedin.com/in/jmpenasse
Voir le profil WWW
« Répondre #6 le: 08 Août,2011, 13:51:38 »

Bonjour et bienvenue !

Désolé, mais le temps est ce qu'il me manque le plus. Je n'ai pas encore eut le temps de m'y remettre  Embarrassed
Mais je ne désespère pas  Wink
Journalisée

Il y a 10 sortes de gens : Ceux qui comprennent le binaire et les autres ...
Delvekior
Néophyte
*
Hors ligne Hors ligne

Messages: 2

OS:
Windows Vista/Server 2008 Windows Vista/Server 2008
Navigateur:
MS Internet Explorer 8.0 MS Internet Explorer 8.0


Voir le profil
« Répondre #7 le: 08 Août,2011, 17:47:27 »

C'est normal, c'est une denrée rare pour tous !  Wink

Bon courage, et n'hésite pas à faire un truc plus condensé que celui ci-dessus en avant-goût : le paramétrage d'APACHE et le programme complet "brut", quitte à retravailler ensuite la présentation et les explications par rapport à ce que tu as déjà mis en ligne !

J'espère te lire (relativement) bientôt !  ange
Journalisée
Pages: [1]   Haut de page
  Imprimer  
 
Aller à:  


Propulsé par MySQL Propulsé par PHP Common France © 2008, 2009  
AS/400, AS400, iSeries, i5, Power i sont des marques déposées d'International Business Machines Corp.

Powered by SMF 1.1.16 | SMF © 2006-2008, Simple Machines
SMFAds for Free Forums
SMF customization services by 2by2host.com
XHTML 1.0 Transitionnel valide ! CSS valide !
SimplePortal 2.1.1