, , Utilisez DRDA sur #IBMi

Dans ACS vous avez des exemples comme si dessous

Vous indiquer le nom de votre base de données distantes et vous exécuter votre requête sur le système distant.

derrière cette requête ce cache un protocole nommé DRDA , comme ODBC il permet de ce connecté à une base de donnée distante.

Nous allons voir comment le mettre en œuvre .

sur le système source
Vous devez créer une entrée pour la base de données

le plus simple c’est de passer par la commande WRBRDBDIRE , vous ajouterez une connexion IP à votre système distant.

Sur le système cible
Vous devez paramétrer le service par la commande CHGDDMTCPA , il faut avoir le même mode d’authentification que la base de données distante, par défaut user + mot de passe
vous devez démarrer le service STRTCPSVR *DDM

voila c’est tout
vous pouvez à partir de votre système source faire un connect SQL sur votre système cible si vous avez un mot de passe.

Si vous ne voulez pas renseigner de mot de passe comme dans les exemples ACS vous allez devoir utiliser sur votre système source les postes poste d’authentification serveur.
Pour les ajouter vous avez la commande ADDSVRAUTE, vous devrez également avoir mis la valeur système QRETSVRSEC à ‘1’ pour que vos mots de passe soit enregistrés

il est conseillé d’ajouter un poste générique, par exemple QDDMDRDASERVER en indiquant un user et un mot de passe du système cible !

il n’y a pas de commande WRKSRVAUTE mais vous pouvez en trouver une ici https://github.com/Plberthoin/PLB/tree/master/GTOOLS/

Exemple :

A partir de ce moment la mot de passe sera passé directement.

Vous pouvez facilement, par des services sql comparer 2 partitions (valeurs systèmes, fonctions , etc …)

Remarques

Les noms doivent être en majuscule
il est conseillé de mettre un programme d’exit de contrôle
Attention, vous pouvez vous connecter avec un utilisateur *disabled
Les fichier DDM sur IP s’appuient sur cette technologie

, Prompt override program

Le programme de substitution d’invite (prompt override program) vous permet de pouvoir précharger les valeurs d’une commande afin de pouvoir modifier les paramètres existants. Comme les commandes CHGUSRPRF, CHGCMD etc…

Dans mon exemple, j’ai créé une commande CHGCLIENT afin de pouvoir modifier le libellé et le pays d’un client. Je veux que l’utilisateur saisisse le numéro du client et que ma commande récupère les valeurs actuelles. On est d’accord qu’il faudrait rajouter plus de contrôles mais c’est pour montrer le fonctionnement.

Tout d’abord il faut créer la commande en précisant le mot clé KEYPARM(*YES) sur les paramètres clé.

Ecrire ensuite le programme de récupération des données du client (CHGCLIENTO). Dans mon exemple c’est un programme RPG mais vous pouvez faire un programme CL.

Il doit recevoir en paramètres :
1. Le nom de la commande (alpha de 10)
2. Les paramètres clés (numéro client pour moi)
3. La suite des paramètres de la commande (LIBELLE et PAYS). Il faudra préciser la taille du paramètre en hexa en début de variable.

Ecrire le programme de traitement de la commande (CHGCLIENT).

Il ne vous restera plus qu’à créer votre commande en précisant le paramètre PMTOVRPGM

Exemple : CRTCMD CMD(CURLIB/CHGCLIENT) PGM(CURLIB/CHGCLIENT) TEXT(‘Modification client’) PMTOVRPGM(*CURLIB/CHGCLIENTO)

Au lancement de la commande, vous saisissez le numéro du client et les autres informations seront chargées.

, , , Convertir un SAVF en PF

il faut savoir qu’un fichier SAVF est un fichier PF de 528 de long.

Vous pouvez avoir besoin pour différentes raisons de convertir SAVF en PF pour manipuler plus simplement par SQL, pour contourner des restrictions d’utilisations etc ..

Vous trouverez ici 2 commandes qui vont vous permettent de réaliser cette opération : https://github.com/Plberthoin/PLB/tree/master/CPYSAVF

Copier un SAVF dans un PF

Voir le PF

Copier un PF dans un SAVF

Voir le Résultat

Pour voir ce résultat taper la commande DSPSAVF , Voir WRKSAVF si vous avez installez notre outil

Remarque :

Outil simple mais efficace qui peut rendre des services à des administrateurs

, Utilisez un booléen dans une commande

Voici un exemple classique, vous devez définir dans vos commandes, un paramètre qui peut prendre comme valeur oui ou non par exemple

Généralement vous allez faire comme ceci

dans la commande

PARM KWD(CRTFILE) TYPE(CHAR) LEN(4) RSTD(YES) +
DFT(NO) VALUES(NO *YES) PROMPT('Création du +
fichier')


dans le programme

         PGM        PARM(.... &CRTFILE)
/* Paramètres */
//
DCL &CRTFILE *CHAR 4
//
IF COND(&CRTFILE = '*YES' ) THEN(DO)
//
ENDDO

Voici une solution en utilisant un booléen dans le programme

dans la commande

        PARM       KWD(CRTFILE) TYPE(*CHAR) LEN(4) RSTD(*YES) + 
                     DFT(*NO) VALUES(*NO *YES) SPCVAL(('*YES' + 
                     '1') ('*NO' '0')) PROMPT('Création du +    
                     fichier')                                  

dans le programme

         PGM        PARM(.... &CRTFILE)
/* Paramètres */
//
DCL &CRTFILE *LGL
//
IF COND(&CRTFILE) THEN(DO)
//
ENDDO

L’astuce consiste à indiquer une valeur à renvoyer dans la commande ici on se borne à ‘0’ et ‘1’ ce qui peut être interprété par votre programme comme un booléen

L’intérêt d’utiliser un booléen c’est d’avoir un code simplifier , un peu comme les indicateurs qui simplifient la lecture d’un code RPGLE ou CLLE

, Simplifiez vous la gestion de vos SAVF

Vous avez tous trop de SAVF sur vos systèmes voici une commande qui va vous aider à les manager : WRKSAVFD.


Bibliothèque :

  • *ALL si vous souhaitez avoir la liste de tous les SAVF existants sur votre machine.
  • Nommez la bibliothèque si vous ne souhaitez afficher QUE les SAVF de cette dernière.

Confirmer si suppression :

  • *YES, par défaut, vous permettra de valider par « entrée » pour chaque fois ou vous aurez sélectionner l’option 4 : Supprimer dans l’écran suivant.
  • *NO, pour supprimer sans passer par un écran de validation de la suppression demandée lors de l’option 4 : Supprimer dans l’écran suivant.

Une option 5 : Gérer vous envoi sur la commande précédemment expliquée ici .

Vous trouverez les sources sur le GitHub Gaia-Mini-Systemes .

, , Gérer les *SAVF (WRKSAVF)

Il existe une commande DSPSAVF qui permet de visualiser le contenu d’un Save File (SAVF), elle est très utile et nous nous sommes demandés si nous pouvions améliorer son ergonomie.
Depuis l’intégration des Technical Release 7.5 TR2 et 7.4 TR8, de nouvelles vues et tables de fonctions permettent d’obtenir des informations à propos des SAVF et de leur contenu.

Nous avons ainsi créé WRKSAVF, une commande qui permet de lister le contenu d’un SAVF (comme DSPSAVF) mais avec des fonctionnalités supplémentaires :

  • Explorer les *SAVF d’une bibliothèque
  • Restaurer directement un objet depuis cette liste

Lors du lancement de la commande WRKSAVF, vous devez choisir le fichier SAVF dans la bibliothèque souhaitée. Si vous souhaitez accéder à la liste des SAVF existants, renseignez *ALL en nom de fichier et nommez votre bibliothèque.


Ensuite, vous n’avez qu’à sélectionner le SAVF de votre choix pour accéder à ses informations essentielles.

C’est à ce moment que la vue QSYS2.SAVE_FILE_INFO nous permet de récupérer des informations importantes telles que:

  • La date à laquelle le SAVF a été sauvegardé.
  • Le nombre d’objets contenus dans ce SAVF.
  • Si les données ont été compressées à la sauvegarde.
  • Etc. (je vous invite à consulter la documentation IBM i, les informations y sont nombreuses).

La deuxième vue qui nous intéresse est QSYS2.SAVE_FILE_OBJECTS, qui nous donne plus d’informations sur l’objet à l’intérieur du SAVF :

  • Le type de l’objet.
  • L’attribut de l’objet.
  • La bibliothèque d’origine de l’objet.
  • Le propriétaire de l’objet.
  • La taille de l’objet.
  • Etc. (ici encore, je vous renvoie à la documentation IBM i pour de plus amples informations ).

Une fois sur l’écran de gestion du contenu d’un SAVF, il vous est possible de filtrer son contenu :

  • Par nom, en indiquant par exemple que vous souhaitez afficher les objets commençant par « TEST »
  • Par type, l’utilisation de F4 vous permet de choisir parmi les types existants pour les objets de ce SAVF ou en saisissant le type voulu.
  • Il est alors possible de restaurer un objet en indiquant l’option 1.

Attention, la bibliothèque de restauration (RSTLIB) choisie par défaut est la bibliothèque de l’objet sauvegardé, il ne vous reste alors qu’à renseigner celle de votre choix pour y restaurer l’objet.

Une fois la demande de restauration exécutée, un message de complétion au pied du SFL vous indiquera :

  • Que tout s’est bien déroulé.
  • Que tout s’est bien déroulé, avec modification de sécurité.
  • Que la restauration a échoué.

Sources disponible : https://github.com/Gaia-Mini-Systemes/GSAVF

, Les programmes de contrôle de validité sur IBM i

Il est possible d’effectuer un contrôle sur les paramètres passés dans une commande avant que le programme de traitement ne soit exécuté et d’envoyer un message de diagnostic au sein même de la commande en cas d’erreur.

Documentation IBM sur le sujet : https://www.ibm.com/docs/fr/i/7.5?topic=commands-validity-checking-program-cl-command

Introduction

Pour ajouter des contrôles sur les paramètres d’une commande (en plus des contrôles inclus dans celle-ci), on peut lui affecter un programme de contrôle de validité créé en amont.

Ce programme recevra tous les paramètres de la commande et on pourra y réaliser divers contrôles/tests avant l’exécution du programme de traitement. Il permet également d’envoyer des messages de diagnostic pour que l’utilisateur puisse ajuster la saisie de ses paramètres.

Pour assigner le programme de contrôle de validité à la commande, on indique son nom dans le paramètre VLDCKR de la commande CRTCMD (lors de la compilation de la commande).

Cas d’exemple

Prenons le cas où nous souhaitons créer une commande simple qui permettrait de récupérer une extraction CSV des ventes réalisées par un utilisateur sur une année donnée.

On souhaitera donc vérifier deux choses :

  • L’utilisateur doit exister sur la machine
  • L’année choisie doit être comprise dans une période de 10 ans avant l’année en cours

On commence donc par créer la commande GETUSRVEN qui recevra ces deux paramètres :

Une fois la commande prête on peut préparer le programme de contrôle de validité.
Pour cet exemple on créera un programme VGETUSRVEN (CLLE) :

Dans ce programme, on récupère les différents paramètres de la commande GETUSRVEN et la date actuelle en décimal.

On procède ensuite aux contrôles :

  • De l’utilisateur

Ici on utilise une suite de requêtes SQL pour vérifier que l’utilisateur existe sur la machine.

En cas d’absence d’utilisateur correspondant au paramètre de notre commande, on utilise la commande SNDPGMMSG (MSGTYPE *DIAG) avec le code message CPD0006 (conçu pour être utilisé dans des programmes de contrôle de validité).

On peut indiquer le message de notre choix dans le paramètre MSGDATA, mais attention, les quatre premiers caractères étant réservés il faut commencer son message par ‘0000’.

Une fois le message de diagnostic indiqué on réutilise la commande SNDPGMMSG (MSGTYPE *ESCAPE) avec le code message CPF0002 ce qui permettra d’indiquer à l’appelant que des erreurs ont été trouvées et de suspendre l’exécution de la commande.

  • De l’année choisie

On applique ici la même méthode que précédemment, en vérifiant que l’année n’est pas antérieure de 10 ans par rapport à l’année en cours, et qu’elle n’est pas supérieure.

On peut maintenant compiler le programme VGETUSRVEN (commande CRTBNDCL).

Enfin on compile la commande GETUSRVEN en spécifiant VGETUSRVEN dans le paramètre VLDCKR de la commande CRTCMD.

On peut maintenant essayer la commande, et constater les messages de diagnostic en cas de mauvaise saisie :

Il est également possible de voir quel programme de contrôle de validité est utilisé pour une commande (s’il y en a un) avec la commande DSPCMD CMD(nom de la commande) :

, , , Effacer la log de votre travail

Vous faites le l’administration, le plus souvent en 5250 sous l’écran de commandes IBMI
==> call QCMD

Vous voulez effacer la log que vous voyez par la commande DSPJOBLOG.

La première solution consiste à vous déconnecter, du coup la log est effacée ou transformée en spool.

Cette méthode efface tout le contexte mis en place, liste de bibliothèques , variables d’environnement, objets dans QTEMP que vous avez peut être mis beaucoup de temps à construire dans vos tests.

L’idée c’est d’avoir une solution moins radicale qui permette de n’effacer que la log de votre travail, c’est pourquoi vous devriez avoir dans vos tools un outil comme celui la

Une commande qu’on a appelé astucieusement CLRLOG que vous pouvez trouver ici

https://github.com/Plberthoin/PLB/tree/master/CLRLOG

Comme le code est simple on le remet ici

On utilise la commande RMVMSG qui n’est utilisable que dans un programme CLLE

Le programme en CLLE

 PGM /*------------------------------------*/        
 /* Supprime les messages de votre log     */        
 /* Ne supprime pas les messages *PGMQ     */        
 /*----------------------------------------*/        
              RMVMSG     PGMQ(*ALLINACT) CLEAR(*ALL) 
              RMVMSG     PGMQ(*EXT) CLEAR(*ALL)      
 ENDPGM                                              

La commande

 /* Supprime les messages de votre log     */ 
CMD        PROMPT('Clearer la log de votre job') 

Remarque :

Cette commande n’efface pas les messages de type *PGMQ

, , , Exemple de panel liste

C’est une solution à base d’UIM qui permet de gérer des sous fichiers sans écran DDS, en utilisant un panel de groupe et des API pour le manipuler.

Toutes les commandes WRKXXX de votre IBMi sont codées avec cette solution.

Nous allons vous présenter un exemple pour les PF par exemple vous trouverez le code sur github ici https://github.com/Plberthoin/PLB/tree/master/WRKPF

Cet article est inspiré à l’origine d’un article de mcpressonline, j’ai remis le RPG à jour

Vous devrez avoir un PNLGRP avec la structure suivante, pour indiquer les listes

:PNLGRP.

:CLASS.
:ECLASS.

:VAR.

:VARRCD.

:LISTDEF.

:KEYL.
:KEYI.
:EKEYL.

:PANEL.
.
.
:LIST.

:LISTACT.
:LISTCOL.
:LISTVIEW.
.
.
.
:ELIST.
.
:CMDLINE.
.
:EPANEL.
.
.
.
:HELP.
.
.
.
:EHELP.

:EPNLGRP.

Vous aurez un programme ici en RPG qui va utiliser les API suivantes :

Api Utilisation

QUIOPNDA Ouverture du panel création du Handle
QUIPUTV Renseignement variable
QUIADDLE Ecriture d’un poste dans la liste
QUIDSPP Affichage du panel
QUIDLTL Suppression du contenu de la liste
QUICLOA Fermeture du panel

Rappel, vous pouvez chercher les APIs disponibles sur votre IBMi avec API-FINDER disponible

ici https://www.ibm.com/docs/en/i/7.5?topic=interfaces-api-finder

Conclusion

C’est une solution standard qui ne nécessite pas de DSPF, mais qui nécessite de connaitre un peu le langage UIM.
Avec un squelette de PNL et de programme on peut créer des outils WRKXXX rapidement, idéal pour les outils d’administration par exemple

, , Récupérer les logs d’une commande shell QSH

Interrogation SQL des tables système


Le passage de commandes shell est tout à fait possible dans les programmes de CL (langage de contrôle sur IBM i) via QSH CMD(&maCommande). Si dans une session QSH (STRQSH) l’état des logs s’affiche, nous n’avons pas ces retours quand les commandes shell sont passées via un programme CL.

plus d’informations sur le shell QSH sous IBM i : LE SHELL INTERPRETER

Contexte

Les deux écrans suivants permettent de tester l’authentification à Github (plateforme de versionnage du code, de contrôle et de collaboration ) ; ce travail servira d’exemple à notre article :

  • Commandes manuelles, dans une session QSH avec les logs (en rouge)
  • Commande automatisée dans un programme CL, sans retour de logs

Il existe tout de même un moyen pour récupérer les logs d’une commande shell passée via un programme CL ; l’interrogation des tables système par requête SQL.

Principe

Par un programme CL, les commandes QSH sont soumises dans un travail via SBMJOB

Plusieurs paramètres sont nécessaires :

  • la commande QSH (ici &QSH)

  • le travail doit être identifiable par un nom &JOBNAME, une bibliotheque &LIB, une file de travail &JOBQ, une file de sortie &OUTQ et un utilisateur &USER ; que l’on peut déclarer de cette manière

les noms de variables et leurs valeurs sont arbitraires

  • l’instant t de l’exécution &TIMESTAMP

Ce sont ces paramètres qui alimentent notre requête SQL, et nous permettent de trouver les logs.

VUE qsys2.output_queue_entries

La première composante de notre requête SQL est la récupération des infos du travail en fonction des paramètres, expliqués ci-dessus, via la vue système qsys2.output_queue_entries.

Encapsulation et récupération de la liste des logs d’un travail

Nous récupérons la dernière ligne entrée dans qsys2.output_queue_entries (ORDER BY create_timestamp DESC FETCH FIRST ROW ONLY) que nous encapsulons dans un WITH ; ce qui correspond aux identifiants associés au dernier travail lancé par le programme CL.

Le résultat du WITH (alias lastLog ici) est passé dans un SELECT sur la vue systools.spooled_file_data pour récupérer la liste des spools associés à la commande QSH (variable &QSH dans notre exemple): WHERE spooled_data like trim(:log) || '%'.

Nous obtenons les spools associées à une (ou plusieurs) commandes QSH lancé(es) via un programme CL

Intégration dans un programme

A ce niveau, nous sommes capable d’obtenir les logs générées par une commande QSH pour consultation ; en passant nos requêtes SQL dans un exécuteur de script. Voyons maintenant comment il est possible d’obtenir ces logs par un programme et d’adapter le traitement en fonction de leurs valeurs.

Programme CL

L’idée est d’avoir notre programme CL (ici ggitAuth.clle) qui :

  • soumet le travail,

  • appelle un programme SQLRPGLE qui retourne la log (ici getqshlog.sqlrpgle),

  • effectue le traitement en fonction de la valeur de la log retournée par le programme SQLRPGLE.

Programme SQLRPGLE

Le programme SQLRPGLE reçoit en paramètre :

  • la valeur de la log ciblé log,
  • la file de sortie OUTQ,
  • la file de travail JOBQ,
  • le nom du travail JOBNAME,
  • le temps d’exécution TIMESTAMP.

Par un exec sql, nous retrouvons l’interrogation de table vue précédemment. Celle-ci est intégrée dans une boucle pour gérer le délai d’écriture dans la table au moment du passage de la commande QSH :

Enfin nous mettons dans une variable la valeur de la log ; qui prend ‘Log not found’ en cas d’échec de la requête (sqlCode <> 0).


En résumé

Il est possible dans un environnement IBM i d’exécuter des commandes shell comparables à ce qui peut se faire sur UNIX. Les logs générées par ces commandes sont consultables par interrogation de tables SQL. Pour aller plus loin, la récupération des logs pour analyse dans un programme permet la prise de décision dans ce dernier.