Le PCML (Program Call Markup Language), est un document généré par le compilateur pour décrire l’interface de vos programmes ou programmes de service. Il permet d’automatiser l’appel des programmes via Java ou d’autres langages.

En RPGLE,  il existe 2 méthodes pour déclarer des paramètres.

Première solution

En carte C, méthode que l’on trouve encore sur des programmes existants : les paramètres sont considérés comme en entrée/sortie dans le PCML.

C     *entry        plist                                      
C                   parm      Tempin                         10
C                   parm      Tempout                        10

PCML généré :

<pcml version="6.0">                                                      
   <!-- RPG module: TESTPCML  -->                                         
   <!-- created: 2018-03-14-09.22.22 -->                                  
   <!-- source: BERTHOIN/QRPGLESRC(TESTPCML) -->                          
   <!-- 2 -->                                                             
   <program name="TESTPCML" entrypoint="TESTPCML">                        
      <data name="TEMPIN" type="char" length="10" usage="inputoutput" />        
      <data name="TEMPOUT" type="char" length="10" usage="inputoutput" /> 
   </program>                                                             
</pcml>

Deuxième solution

En les prototypant soit en carte D soit en format full free.
On peut jouer en indiquant « const » sur les paramètres en entrée, ils seront bien uniquement en input dans le PCML.
Mais les autres paramètres resteront en entrée/sortie :

 D                 PI                        
 DTempin                         10    const 
 DTempout                        10         

ou

dcl-pi *n ;                  
  Tempin char(10) const ; 
  Tempout char(10) ;      
end-pi;  

PCML généré :

<pcml version="6.0">                                                      
   <!-- RPG module: TESTPCML  -->                                         
   <!-- created: 2018-03-14-09.22.22 -->                                  
   <!-- source: BERTHOIN/QRPGLESRC(TESTPCML) -->                          
   <!-- 2 -->                                                             
   <program name="TESTPCML" entrypoint="TESTPCML">                        
      <data name="TEMPIN" type="char" length="10" usage="input" />        
      <data name="TEMPOUT" type="char" length="10" usage="inputoutput" /> 
   </program>                                                             
</pcml>                                                               

En CBLLE, il existe une seule solution pour déclarer les paramètres

LINKAGE SECTION.                                                      
01 TEMPIN PIC X(10).                                                             
01 TEMPOUT PIC X(10).        
…                                               
PROCEDURE DIVISION USING TEMPIN  TEMPOUT.

Et les paramètres sont en entrée/sortie ….

 

 

Lors de la publication par l’interface web, on peut ajuster ces paramètres. Le plus souvent, en entrée ou en sortie, pour générer un WSDL efficace :

 

PCML obtenu après modification par l’outil de déploiement :

<pcml version="6.0">                                                      
   <!-- RPG module: TESTPCML  -->                                         
   <!-- created: 2018-03-14-09.22.22 -->                                  
   <!-- source: BERTHOIN/QRPGLESRC(TESTPCML) -->                          
   <!-- 2 -->                                                             
   <program name="TESTPCML" entrypoint="TESTPCML">                        
      <data name="TEMPIN" type="char" length="10" usage="input" />        
      <data name="TEMPOUT" type="char" length="10" usage="output" /> 
   </program>                                                             
</pcml>

 

La complexité intervient, dans le cas où l’on veut bypasser l’interface web, pour automatiser des déploiements en utilisant les scripts SH.
Nos outils permettent la modification du PCML sans intervention manuelle. Pour cela, il vous faudra générer le fichier PCML dans un fichier IFS, celui généré dans le module n’étant pas modifiable :

 CRTBNDRPG PGM(BERTHOIN/TESTPCML) 
           SRCFILE(BERTHOIN/QRPGLESRC) 
           PGMINFO(*PCML *STMF) 
           INFOSTMF('/home/PLB/testpcml.pcml')

Ces options ne peuvent pas être intégrés dans vos cartes H ou CTL-OPT

Vous devrez modifier le type de vos paramètres et indiquer votre fichier STMF dans la publication du webservice :

installWebService.sh                                               
   ...         
   -pcml '/home/PLB/testpcml_modifie.pcml'

 

 

Versions

PCML a subi quelques évolutions il en est actuellement la version 7 depuis fin 2017. La version usuelle est toujours la 6 aujourd’hui. Cette dernière est indiquée dans le tag PCML :

<pcml version="6.0">

 

Les principales évolutions

  • PCML version 2.0 or higher
    « entrypoint »
    « passby »
    « returnvalue »

 

  • PCML version 3.0 or higher
    « bidistringtype »
    « threadsafe »

 

  • PCML version 4.0 or higher
    « chartype »
    « epccsid »
    « trim »

 

  • PCML version 6.0 or higher
    « dateformat »
    « dateseparator »
    « timeformat »
    « timeseparator »

 

  • PCML version 7.0 or higher
    « varchar »

Remarque :

Vous n’obtenez pas la même syntaxe si vous générez directement le programme.

CRTBNDRPG ...

<program name="TESTPCML" path="/QSYS.LIB/BERTHOIN.LIB/TESTPCML.PGM"

ou si vous générez d’abord le module

CRTRPGMOD ...

<program name="TESTPCML" entrypoint="TESTPCML">

Soit pour un module

<pcml version="6.0">                                                     
   <!-- RPG module: TESTPCML  -->                                        
   <!-- created: 2018-03-14-09.22.22 -->                                 
   <!-- 2 -->                                                             
   <program name="TESTPCML" entrypoint="TESTPCML">                       
   ...
</pcml>

et pour un programme

<pcml version="6.0">                                                     
   <!-- RPG module: TESTPCML  -->                                        
   <!-- created: 2018-03-14-09.22.22 -->                                 
   <!-- source: BERTHOIN/QRPGLESRC(TESTPCML) -->                         
   <!-- 1 -->
   ...
</pcml>

 

 

La version par défaut est PCML 6, pour utiliser la version 7, vous devez le spécifier explicitement.

De plus, cela nécessite : PTF SI66150 (7.3) ou SI66149 (7.2) du 10/11/2017.

 

Pour l’utiliser

  • Soit par une variable d’environnement
  ADDENVVAR ENVVAR(QIBM_RPG_PCML_VERSION) VALUE(7.0) LEVEL(*SYS)
  • Soit par CTL-OPT
  ctl-opt pgminfo(*pcml:*module:*dclcase:*v7) ;

 

La différence V6/V7 porte sur la gestion des VARCHAR

V6 : VARCHAR considéré comme une DS

<struct name="STRIN" usage="input">
   <data name="length" type="int" length="2" precision="16" usage="inherit" />
   <data name="string" type="char" length="length" usage="inherit" />
</struct>

 

V7 : supporté nativement via le type « varchar »

<data name="STRIN" type="varchar" length="25" usage="input" />

 

Cet article est le premier d’une série à suivre sur le PCML, rendez-vous très vite !

La TR4 de la 7.3, ou la TR8 de le 7.2, apporte une petite modification aux commandes

  • CRTBNDCL
  • CRTCLMOD
  • INCLUDE

Ces commandes supportent désormais le paramètre SRCSTMF : compilation d’un CL dont le source est dans l’IFS, comme le font les commandes CRTBNDRPG et CRTRPGMOD actuellement.

L’évolution peut paraître anecdotique, mais elle permet une meilleure intégration des développement Open Source, basés sur Git ou autres gestionnaires externes de sources.

 

Vous devez installer la PTF 5700SS1 SI66797 (7.3) afin de disposer de cette fonctionnalité.

 

Exemple :

Concrètement, le source est copié dans un fichier de QTEMP avant d’être compilé de façon classique :

 

Si vous utilisez des INCLUDE, cette commande est également modifiée, et vous avez la possibilité d’indiquer un répertoire contenant vos sources dans l’IFS.

 

Une remarque concernant l’intégration dans RDi :

  • impossible de compiler depuis l’IFS directement, il vous faut définir une action utilisateur (comme pour le RPGLE)
  • je vous conseille de modifier le formatage automatique de code CL pour ne pas dépasser 80 colonnes (le compilateur tronque à 80 caractères)

 

Nul doute que cette fonctionnalité va permettre rapidement l’adoption de l’IFS. D’autres alternatives existent déjà, principalement dans le projet Open Source OSSILE https://github.com/OSSILE/OSSILE/tree/master/main/crtfrmstmf. Ce dernier garde tout son sens pour compiler depuis l’IFS n’importe quel source pour lequel le compilateur ne propose que les fichiers sources classiques (DSPF, …).

 

Suite à vos retours et demandes, nous avons fait évoluer le logiciel d’administration des web services.
Principales Nouveautés de la 1.0.2
  • Abandon de XMLSERVICE, cette version fonctionne sans ce produit
  • Les commandes copiées sont mises dans /webservice/local/models, ce qui est plus lisible  pour la version multi serveurs
  • Vous avez un bouton <FILE> sur la gestion des services et des serveurs qui permet de produire une table qui liste vos ressources
  • Vous trouverez de nouveaux exemples dans le fichier source SAMPLESRC qui contient des exemples d’automatisations
  • Nous avons créer un outil de migration qui vous paramétra de garder vos logs et surtout votre paramétrage
Et surtout, nous avons réécrit une version 6.1 pour tous ceux qui ne sont pas encore en version 7.*. Cette version dispose des même fonctions que la la version standard, mais n’évoluera sans doute pas, les nouveautés n’étant livrées qu’en version 7.*.

 

La console évolue, et passe désormais en version 1.0.1 : http://www.gaia.fr/download/utilitaires/webconsole.zip.

Pour prendre en compte vos retours et commentaires, cette version apporte principalement sur la capacité de gérer plusieurs partitions depuis un système. Vous retrouverez les informations de la version précédente (cf notre article de lancement http://www.gaia.fr/console-pour-serveurs-de-services-web/).

Nous continuons à faire évoluer cet outil, et à prendre en compte vos besoins. Une des prochaines phases sera le passage en Open Source !

 

Continuez à nous transmettre vos remarques et besoins.

 

L’utilisation toujours plus importante de web services nous amène à devoir manipuler en RPG des données sous forme XML et JSON, pouvant représenter différents types de données, simples ou complexes.

Mais lorsqu’il s’agit de données binaires (image ou document pdf par exemple), ces informations doivent être converties en Base64 qui procure une représentation alphabétique de données binaires.

Voir la définition Wikipédia : https://fr.wikipedia.org/wiki/Base64

 

Afin de pouvoir encoder ou décoder ces valeurs depuis un programme RPG, nous devons nous appuyer sur des outils, chacun ayant ses avantages ou limitations :

Nous proposons de voir ici une méthode avec Java, qui a la particularité de pouvoir être piloté directement par RPG.

Depuis Java 8, le runtime fournit les fonctions Base64 : https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html

Toutefois, cette classe utilise des classes internes Java (classe dans la classe), dont le prototypage n’est pas documenté pour le RPG.

 

Voici un exemple d’utilisation simple en Java :

Produit la sortie suivante :

Ici, Base64.Encoder et Base64.Decoder sont les classes internes.

Voir la définition Wikipédia : https://fr.wikipedia.org/wiki/Classe_interne

 

Voici un programme RPG qui implémente l’utilisation de ces mêmes classes :

Produit le résultat suivant :

 

En RPG, les classes Java internes se déclarent avec $ et ne sont utilisables que via la classe mère.

Pour utiliser cette fonctionnalité Base64, il vous suffit d’avoir une JVM 8 :

  • vérifier la disponibilité sur votre système par GO LICPGM, produit JV1
  • java *version en ligne de commande pour connaitre la JVM par défaut
  • regarder la variable d’environnement JAVA_HOME si existante

 

L’utilisation de Java permet de dépasser la limite des 4Ko facilement. La nouvelle limite est maintenant la taille maximale d’une variable RPG (16Mo), qui s’avère suffisante dans les situations classiques.

Bon développement !