, , , , Utiliser ACS pour produire des fichiers Excel depuis l’IBM i

Access Client Solutions (ACS)

Pour rappel, ACS est le successeur de Client Access et permet toujours les exports de données.

ACS est également un produit entièrement Java, et utilisable en mode ligne de commande.

Il est donc possible de le piloter sur l’IBM i. Pour cela il vous faut :

  • Avoir le produit sous licence 5770JV1 (Java) version 8 ou supérieur
  • Access Client Solutions sur l’IFS (désormais installé via PTF (7.4: SI71900 / 7.3: SI71934 / 7.2: SI71935) dans /QIBM/ProdData/Access/ACS/Base

Exemples

Il est alors possible de provoquer le transfert de données de deux façons :

  • le fichier complet
  • une requête SQL permettant la sélection, transformation, jointure …

Syntaxe :

/PLUGIN=cldownload /system=<system>
                          [/userid=<userid>]
                          {/hostfile=<library/filename> | /sql="statement"}
                          {/clientfile=<path><filename>.<extension> | /display}
                          [/<options>]

    /userid     - user id to use when connecting to the target system
    /hostfile   - Source library and file on the IBM i system for the download
                  e.g. /hostfile=QIWS/QCUSTCDT
    /sql        - specify an SQL statement
                  e.g. /sql="select CUSNUM,LSTNAM,INIT,ZIPCOD from QIWS/QCUSTCDT"
    /clientfile - Target file location for the download.
                  The format of this file will be determined by the specified
                  extension (for example, .csv .ods .xlsx .xlsx)
                  If the file extension is not specified or is of a type
                  not supported, the data will be formatted as a .csv file
    /display    - write the output to the terminal
    
    Valid options are:
       /colheadings=<1/0> - Include column headings as the first row. When specified, the column names will be the heading.
       /usecollabels      - Use column labels for the heading.

Puisque ACS est directement sur votre IBM i, on peut utiliser localhost pour la valeur /system. Cela permet également la portabilité de la commande d’une machine à l’autre.

Pour transférer tout un fichier on utilisera le paramètre /hostfile. Ici sous QSH :

cd /QIBM/ProdData/Access/ACS/Base

java -jar acsbundle.jar
/PLUGIN=cldownload /system=localhost
/hostfile=sqlsample/employee
/clientfile=/home/nb/export/employe.xlsx

Cela produit :

Remarquer le nom de l’onglet.

Pour transférer par une requête SQL :

cd /QIBM/ProdData/Access/ACS/Base

java -jar acsbundle.jar
/PLUGIN=cldownload /system=localhost
/sql="select trim(firstnme) concat ' ' concat trim(lastname), hiredate, current date - hiredate as \"Ancienneté\" from sqlsample.employee" /clientfile=/home/nb/export/employesql.xlsx

Attention à l’échappement des caractères spéciaux …

On obtient :

Des options supplémentaires vous permettent d’affiner la sortie :

  • /colheadings=<1/0> – Inclure ou non l’entête
  • /usecollabels – Utiliser les labels au lieu des noms de colonne

Ces fonctions nécessitent une version de ACS > 1.1.8.6 pour fonctionner correctement.

Comment automatiser ?

Il est relativement simple d’intégrer cette commande Java dans un programme CL. Ici en utilisant /clientfile.

Par exemple avec RUNJVA :

Ou par QSH :

Ici on a paramétré plus d’éléments pour avoir une base de programme plus générique.

Avantages ?

Access Client Solutions permet facilement d’automatiser vos conversions depuis l’IBM i, et non depuis un poste client. Cela rend beaucoup plus naturel l’intégration de ces traitements dans vos chaines, la maitrise des transferts par l’IT et non par les utilisateurs, la maitrise des flux, des versions de produits utilisées etc …

, , Comment administrer vos sessions NODEJS

Rappel

Nodejs est disponible en open source sur l’IBMi, vous pouvez l’installer à partir de l’option de ACS :
Outils / Gestion des modules open source

Pour savoir si le produit est installé sur votre machine vous devez taper :
/QOpenSys/pkgs/bin/node -v
Si NODEJS est installé vous aurez la version installée qui s’affiche

Pour lancer une session nodejs, vous devez indiquer l’adresse ip et le port d’écoute
webserver.listen(port, ip)

L’astuce qui va vous simplifier la vie c’est de passer le port en paramètre, ce qui vous permettra de lancer plusieurs sessions du même script.

Pour lancer votre session Nodejs avec votre script vous devez passer la commande suivante :

/QOpenSys/pkgs/bin/node votrescripte.js votreport

Pour réaliser ceci, un script Nodejs reçoit un tableau d’argument
0 = node
1 = votre script
2 = premier paramètre dans votre cas le port

Pour le récupérer dans votre script vous devez indiquer

port = process.argv[2] ;

Vous pouvez lancer autant de scripts que vous le voulez en gérant le port à chaque lancement !

Quand vous soumettez une session nodejs, il lance plusieurs travaux

NODE2999 QSECOFR BATCH ACTIF
QP0ZSPWT QSECOFR BATCHI ACTIF
QZSHSH QSECOFR BATCHI ACTIF

Le plus simple serait donc de tout isoler dans un sous système pour gérer, les sessions, le démarrage et l’arrêt de l’environnement

Nous avons réalisé une console qui permet de gérer tous ces aspects, vous pouvez trouver le source de cette console à l’adresse suivante :

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

Avec SQL Service vous pouvez administrer ces sessions

SELECT
* FROM TABLE(QSYS2.ACTIVE_JOB_INFO( JOB_NAME_FILTER => ‘xxx*’,
SUBSYSTEM_LIST_FILTER => ‘yyy’)) X
where job_type = ‘SBS’

xxx racine des travaux soumis

yyy sous-système de votre environnement

Ci dessous quelques site web qui peuvent vous aider .

https://www.ibm.com/developerworks/ibmi/library/i-running-node-js-web-app-trs/index.html

https://www.ibm.com/support/pages/node/1127733

https://developer.ibm.com/components/ibm-i/articles/i-native-js-app-ibmi-with-nodejs/

Lancer une commande Windows à partir de votre IBMi en session 5250

Vous pouvez exécuter une commande Windows à partir de votre IBMi en session 5250

Pour cela vous devez d’abord démarrer l’intégrateur, c’est la commande STRPCO

STRPCO
monmsg IWS4010 /* si déjà actif */

Ensuite vous demandez l’exécution de la commande comme si vous étiez sous CMD, par la commande STRPCCMD

par exemple pour tester le bloc note

STRPCCMD PCCMD(‘%windir%\system32\notepad.exe’)

La commande doit être entre quotes

Conseil :

Préférez l’utilisation de la commande START qui associera automatiquement l’extension avec l’exécutable voulu.

Exemple pour un pdf

STRPCCMD PCCMD(‘START votrepdf.pdf’) et non ‘C:\Program Files\PDFCreator\PDFCreator.exe votrepdfs.pdf’

STRPCCMD (‘calc.exe’) pour la calculatrice

Remarque :

Vous reprendrez la main quand vous aurez terminé votre session DOS
Vous ne pouvez pas intercepter de message d’erreur sur la commande STRPCCMD
La limitation de chaine de caractères est de 1023 de puis la V7R2, avant vous étiez limité à 123.
Vous pouvez monter des partages, avec NetServer c’est la commande dos net use, vous pouvez aussi demander à exécuter des fonctions ACS transfert de fichier par exemple
Le paramètre PAUSE(*YES ou *NO) vous affichera une fenêtre dos par exemple sur un .bat , mais ne change rien sur un exécutable Windows (calc.exe, notepad.exe)

Comment connaitre les tables ou PF supprimés ?

Sur L’IBMi on a du mal à matérialiser la base de données

Pourtant en gros, elle a un catalogue c’est les fichiers QADB* de QSYS…

Les fichiers SYS* de QSYS2 pointent dessus

On peut les voir par exemple

SELECT *
FROM SYSTABLESTAT where
TABLE_SCHEMA = ‘QSYS’ and TABLE_NAME
like(‘QADB%’)

Ces fichiers sont journalisés sur des journaux qui sont dans QRECOVERY

Les 2 principaux sont :

QDBJRNCOLM qui va contenir les modifications de zones
QDBJRNFILE qui va contenir les modifications de fichiers

Voici comment analyser pour connaitre les fichiers PF ou tables supprimés dans la journée.

Vous devez générer un table à partir de votre journal

DSPJRN JRN(QRECOVERY/QDBJRNFILE)
FROMTIME(votre_date 000001)
OUTPUT(*OUTFILE)
OUTFILE(QTEMP/LISTE1)

Vous devez effectuer cette requête sur le fichier que vous avez généré

SELECT JODATE, JOTIME, substr(joesd, 1, 10) as fichier ,
substr(joesd, 11, 10) as biblio ,
substr(joesd, 31, 10) as User ,
substr(joesd, 91, 2) as type ,
joesd
FROM qtemp/liste1
WHERE JOCODE = ‘R’ and JOENTT = ‘DL’
and substr(joesd, 91, 2) = ‘TB’

Conclusion :

On ne peut pas agir sur les fichiers du catalogue, c’est le système qui les gère, les seules commandes qui permettent d’interagir sur le catalogue sont :

==>RCLDBXREF
==>QSYS/RCLSTG SELECT(*DBXREF)

Par exemple, dans le cas ou vous commencez à avoir des messages sur la base de données, ou un nombre très important d’enregistrements supprimés dans les fichiers du catalogue …

, , Comment suivre l’évolution des pools mémoire ?

Rappel


Les pools partagés sont des espaces mémoire dans lequel les sous-systèmes place des travaux.
*MACHINE Utilisé par les fonctions internes du pool machine
liste des pools
*BASE Pool système par défaut
*INTERACT Travail interactif
*SPOOL Impression
*SHRPOOL1 à *SHRPOOL60 pools spécifiques
et sur ces pools il y a 2 valeurs importantes à ajuster, la taille et le niveau d’activité.

Ajustement

Il existe une valeur système pour ajuster automatiquement ces pools
La valeur système QPFRADJ à 2 ou à 3 permet de mettre en place cet ajustement automatique la différence étant un ajustement à l’IPL avec la valeur 2.
Ce mécanisme fonctionne très bien …
l’ajustement par défaut est fait toutes les 60 secondes ce qui la plupart temps convient bien.
Si vous voulez ajuster ce temps vous pouvez créer une dtaara :
CRTDTAARA DTAARA(QUSRSYS/QPFRADJWT) TYPE(*DEC) LEN(3 0) VALUE(60) vous pouvez indiquer une valeur en seconde de 20 à 120.

Mais on a aucune visibilité sur l’ajustement sur une période données, exemple mon pool de base une journée.

Voici comment on peut faire :


Il faut créer un récepteur de journal, il peut être dans une bibliothèque privée, et vous pouvez choisir son nom
CRTJRNRCV JRNRCV(QUSRSYS/QPFRADJ)
Il faut créer le journal QPFRADJ qui pointe sur votre récepteur
CRTJRN JRN(QSYS/QPFRADJ) JRNRCV(QUSRSYS/QPFRADJ)
Il vous faut un fichier pour faire votre analyse, le fichier qui contient la structure est QAWCTPJE
CRTDUPOBJ OBJ(QAWCTPJE) FROMLIB(QSYS) OBJTYPE(FILE) TOLIB(votrebib) NEWOBJ(QPFRADJ) récupérer les informations du journal DSPJRN JRN(QSYS/QPFRADJ) ENTTYP(TP) OUTPUT(OUTFILE) OUTFILE(votrebib/votrefic)
Créer un fichier à exporter.
create table qtemp/analyse as(
SELECT TPTIME as heure , TPCSIZ as taille
FROM votrebib/votrefic WHERE
TPPNAM = ‘*BASE ‘ and tpdate = ‘070320’
) with data
dans notre cas le pool de base, le 7 mars 2020
vous devez ensuite exporter ce fichier pour faire un diagramme, par exemple sous excel .

Remarque :

Il ne faut pas utiliser des pools privés qui ne seront pas ajustés.
Vous devez faire le ménage sur les récepteurs de journaux que vous créez.
Et règle fondamentale, si on fait de l’ajustement, on fait une mesure avant et une mesure après sur des périodes significatives !

Sauvegarde et Restauration des webservers

Pour Sauvegarder et Restaurer un server de webservices vous pouvez utiliser les scriptes QSH prévus à cet effet.

Sauvegarde

saveWebServicesServer.sh
-server ‘server’
-saveFile ‘savf’ (‘/qsys.lib/libsavf.lib/savf.file’)

Restauration

restoreWebServicesServer.sh
-fromServerDirectory ‘server-directory’ (‘/www/server’)
-saveFile ‘savf’ (‘/qsys.lib/libsavf.lib/savf.file’)

Remarque :

Le seul support est le SAVF

Mais comment restaurer un serveur de webservices, si vous n’avez que les répertoires de l’IFS.

Il faut savoir qu’un webserveur de webservices c’est 3 choses :

– des répertoires de configuration (dans /www/)
– une instance APACHE déclarée dans http server (fichier QATMHINSTC qui contient un membre pour chacun instance)
– un enregistrement dans LWI ou Liberty.

Il vous faudra donc respecter les étapes suivantes

1) Restauration des répertoires de L’IFS

  • RST DEV(‘/qsys.lib/qgpl.lib/savfIFS.file’)
    OBJ((‘/www/YOURSERVER’))
    Vous pouvez restaurer l’IFS à partir d’autres supports…

2) Autorisation de la branche du server au profil QTMHHTTP

Le profil QTMHHTTP est le profil utilisé par http server pour la plupart de ses opérations. Il doit avoir un droit explicite sur ces fichiers.

  • CHGAUT OBJ(‘/www/YOURSERVER/*’)
    USER(QTMHHTTP)
    DTAAUT(*RWX)
    OBJAUT(*ALL)
    SUBTREE(*ALL)

Remarque :

Cette étape peut être facultative si vous avez une sauvegarde avec les droits privées paramètres PVTAUT(*YES) de vos commandes SAVXXX.

Il vous faudra préciser dans la commande RST … le paramètre PVTAUT(*YES)

3) Création du membre de l’instance APACHE dans le fichier QATMHINSTC de QUSRSYS.

En utilisant la commande

wrkmbrpdm qusrsys/QATMHINSTC

Dupliquer un membre existant en lui donnant le nom de votre server YOURSERVER
puis modifier le contenu en lui indiquant le nom de votre serveur
-apache -d /www/YOURSERVER -f conf/httpd.conf

Cette modification peut-être faite, via l’option 18, par SQL, par script…

 

4) Enregistrement de votre serveur dans liberty ou LWI

Sous LWI

java -cp /QIBM/ProdData/OS400/jt400/lib/jt400Native.jar:/QIBM/ProdData/OS/OSGi/LWI81/native/iasadmin.jar com.ibm.lwi.admin.IntegratedServerAdmin -registerServer YOURSERVER /www

Remarque :
La version de votre lwi ici 8.1, dépend de votre système pour la connaitre :
Se mettre sous qsh
cd /QIBM/ProdData/OS/OSGi
puis ls
o


par exemple ici la version est 6.0
donc la commande devient
java -cp /QIBM/ProdData/OS400/jt400/lib/jt400Native.jar:/QIBM/ProdData/OS/OSGi/LWI60/native/iasadmin.jar com.ibm.lwi.admin.IntegratedServerAdmin -registerServer YOURSERVER /www

Sous Liberty

java -cp /QIBM/ProdData/OS400/jt400/lib/jt400Native.jar:/QIBM/ProdData/OS/OSGi/shared/lib/iasadmin.jar com.ibm.lwi.admin.IntegratedServerAdmin -registerServer YOURSERVER /www

Vous avez un fichier de propriétés, il est dans le répertoire LWI correspondant :

Votre serveur est opérationnel et vous pouvez l’utiliser à nouveau.

Les fichiers de référence des serveurs enregistrés se trouvent :
En 6.1, dans /QIBM/UserData/OS/OSGi/registry/registry.data pour Lwi

À partir de la 7.1,  dans /QIBM/UserData/OS/OSGi/registry/iasregistry.data pour Liberty

Vous pouvez désormais arrêter et redémarrer votre serveur.
ENDTCPSVR *HTTP HTTPSVR(YOURSERVER)
STRTCPSVR *HTTP HTTPSVR(YOURSERVER)

Exemple de requêtes SQL pour retrouver des informations

Liste des instances apaches démarrées

SELECT DISTINCT SERVER_TYPE
FROM TABLE(QSYS2.ACTIVE_JOB_INFO(
SUBSYSTEM_LIST_FILTER => ‘QHTTPSVR’)) X_table

WHERE function = ‘QZSRHTTP’

Liste des instances HTTP déclarées

SELECT TABLE_PARTITION as MEMBER FROM SYSPARTITIONSTAT
WHERE TABLE_NAME = ‘QATMHINSTC’ AND TABLE_SCHEMA = ‘QUSRSYS’

Remarque :

Admin n’a pas d’instance dans ce fichier

La jonction entre les tables pour voir celles qui ne sont pas démarrées

SELECT DISTINCT SERVER_TYPE, TABLE_PARTITION
FROM SYSPARTITIONSTAT a
Join TABLE(QSYS2.ACTIVE_JOB_INFO(
SUBSYSTEM_LIST_FILTER => ‘QHTTPSVR’)) B
on B.server_type = ‘QIBM_HTTP_’ concat TABLE_PARTITION
and TABLE_NAME = ‘QATMHINSTC’
AND TABLE_SCHEMA = ‘QUSRSYS’
where function = ‘QZSRHTTP’

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, …).