, Produits sous licence : IBM simplifie !

Dans la suite logique des annonces de la disponibilité de l’IBM i en mode abonnement pour les Power9 et Power10, IBM continue le déplacement des licences de l’offre perpétuelle à l’offre abonnement. Tout le détail ici https://www.ibm.com/docs/en/announcements/i-operating-system-now-offers-subscription-licensing-all-software-tiers-power9-power10-processors.

Bien entendu cela favorise la capacité à proposer des offres Cloud !

De ce point de vue c’est une opportunité importante dans la modernisation des infrastructures, et surtout la perspective d’avoir à terme un parc (plus) à jour.

D’autres raisons peuvent être sous-jacentes : la capacité à planifier et prédire un chiffre d’affaire par exemple. Du côté du client cela impacté également les budgets IT (amortissement vs consommation). Laissons cela de côté pour l’instant.

Comment

En synthèse, IBM travaille sur la proposition d’un abonnement IBM i + SWMA (maintenance logicielle). Le parti-pris est une équivalence de budget à 4 ans.

Cf https://www.itjungle.com/2023/09/18/the-subscription-pricing-for-the-ibm-i-stack-so-far/

Ainsi, si vous conservez vos machines 4 ans ou moins : pas de budget supplémentaire. Si vous conservez vos systèmes plus longtemps, le coût augmente. De même, il deviendra difficile de conserver des systèmes hors maintenance (mais quel intérêt ?).

D’un autre côté, IBM rend gratuit un grand nombre de produits sous licence : pour les clients les utilisant c’est également une source d’économie. Pour les autres, c’est l’opportunité de disposer de fonctions supplémentaires.

Logiciels sous licence désormais inclus avec la licence IBM i

  • Administration Runtime Expert, also called Application Runtime Expert (5733-ARE)
  • CICS Transaction Server (5770-DFH)
  • HTTP Server (5770-DG1)
  • Facsimile Support for i (5798-FAX)
  • Developer Kit for Java (5770-JV1)
  • Managed System Services (5770-MG1)
  • Network Authentication Enablement (5770-NAE)
  • System Manager (5770-SM1)
  • TCP/IP Connectivity Utilities (5770-TC1)
  • Transform Services (5770-TS1)
  • Universal Manageability Enablement (5770-UME)

Logiciels sous licence gratuit (à commander à part)

  • Web Enablement: includes selected versions of WebSphere Application Server (5733-WE3, 5722-WE2)
  • Cryptographic Device Manager (5733-CY3)
  • OmniFind Text Search Server for DB2 for I (5733-OMF)

Logiciels sous licence payants

  • BRMS (5770-BR1)
  • Rational Development Studio (5770-WDS)
  • PowerHA SystemMirror for i (5770-HAS)
  • Cloud Storage Solutions (5733-ICC)
  • Db2 Mirror (5770-DBM)
  • Rational Developer for i
  • ARCAD Observer for IBM i (5733-AO1)
  • ARCAD RPG Converter for IBM i (5733-AC1)
  • IBM i Modernization Engine for Lifecycle Integration (“Merlin” via Passport Advantage)
  • IBM i Optional Features: Db2 Data Mirroring – Opt 48

Retrouver les détails chez IBM : https://www.ibm.com/docs/en/announcements/continues-simplify-i-portfolio-licensed-software-withdrawal-selected-i-lpps-i-optional-features?region=EMEA

Cas de DB2 Web Query

Une nouvelle plus surprenant : fin de la commercialisation de DB2 Web Query depuis le 10 octobre 2023 ! Cf https://www.ibm.com/docs/en/announcements/db2-webquery-eom

Alors même qu’une nouvelle version est disponible depuis fin 2022 : https://www.ibm.com/docs/en/announcements/db2-web-query-i-24

DB2 Web Query a en réalité été initialement développé par Information Builders sous le nom WebFOCUS. En 2020, il a été racheté par TIBCO (https://www.tibco.com/press-releases/2021/tibco-completes-acquisition-information-builders). Il semble donc que la relation commerciale entre IBM et TIBCO ne permette plus cette participation.

Malheureusement, ce sont les utilisateurs de DB2 Web Query qui en pâtissent, IBM ne proposant pas de produit aux fonctionnalités équivalentes.

Ce sera également un manque aux possibilités de l’IBM i : DB2 Web Query est la solution de BI, d’exploitation des données métier. Or les plus fortes valeurs ajoutées de l’IBM i sont aujourd’hui sa base de donnée DB2 et la capacité à traiter des workload business.

Même si le nombre d’utilisateurs de DB2 Web Query était limitée, c’est assurément une mauvaise nouvelle.

Sécurisez vos services IBM i ! Nous ne le répéterons jamais suffisamment : vous devez crypter les accès au telnet 5250, au serveur de base de données etc … Bref partout où transitent aussi bien vos profils/mots de passe que vos informations métier.

Nous prenons ici l’exemple de telnet, le plus visuel.

Pour crypter vos connexions telnet : https://www.ibm.com/docs/en/i/7.5?topic=server-assigning-certificate-telnet

En synthèse :

  1. Importer ou créer un certificat dans DCM (Digital Certificate Manager)
  2. Associer ce certificat aux services à sécuriser : TELNET ici mais aussi CENTRAL, SIGNON, DATABASE …
  3. Ne pas oublier de permettre la connexion sécurisée à telnet :
Permettre l'accès non sécurisé et sécurisé (ports 23 et 992) :
CHGTELNA ALWSSL(*YES) 

Permettre l'accès sécurisé uniquement (port 992 uniquement) :
CHGTELNA ALWSSL(*ONLY)

Dès lors vous pouvez vous connecter avec ACS en mode sécurisé. Soit en indiquant au niveau de la configuration dans l’émulateur 5250 (menu Communication puis Configuration) :

Soit au niveau de la connexion système dans sa globalité :

A la prochaine connexion vous obtenez :

Mais comment ces certificats sont-ils gérés par ACS ?

Principe d’un certificat, chaîne de certification

Un certificat est une clé de cryptage permettant de chiffrer les données entre un serveur et un client.

La question est de savoir comment faire confiance à un certificat (celui de votre banque par exemple ?).

Un certificat est lui-même signé, c’est à dire validé, par une autorité de certification à laquelle nous faisons confiance.

Exemple avec les informations issues d’un navigateur :

Le navigateur fait confiance à www.volubis.fr car le certificat est lui-même signé par « Gandi Standard SSL CA 2 » et « USERTrust RSA Certification Authority » qui sont eux connus du navigateur :

D’autres critères entrent en compte comme la durée de validité par exemple

Pour un certificat non reconnu par votre navigateur, vous avez :

Validation par Access Client Solutions

ACS va utiliser la même mécanique : si l’autorité de certification est connue de ACS, alors le certificat est validé.

Si l’autorité n’est pas connue : demande à l’utilisateur de valider ou non l’accès.

Access Client Solutions utilise plusieurs magasins de certificats pour stocker les autorités :

  • le magasin lié à votre JVM qui exécute ACS
  • un magasin propre à ACS en complément

Magasin lié à la JVM

Pour trouver la JVM utilisée par ACS :

Java utilise par défaut un magasin de certificats JAVA_HOME\lib\security\cacerts. Ce magasin est protégé par un mot de passe (défaut = changeit)

Remarque :

Cette configuration par défaut peut être modifiée par fichier de configuration ou arguments de démarrage de la JVM.

Ou outil de gestion des certificats est fourni avec votre JVM : keytool (cf https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html)

Exemple :

Nous retrouvons bien notre autorité primaire « USERTrust RSA Certification Authority » :

Magasins liés à ACS

Par défaut, chaque utilisateur d’ACS dispose de son propre magasin de certificat (complémentaire à celui de l’environnement Java ci-dessus).

Dans les préférences vous retrouvez l’emplacement des configurations :

Access Client Solutions dispose également d’un outil de gestion des certificats pour son propre magasin uniquement : menu « Outils » puis « Gestion des clés » :

Cela vous permet d’importer, supprimer, voir vos certificats.

Remarque :

Cette configuration par défaut peut être modifiée par fichier de configuration AcsConfig.properties : permet d’indiquer l’emplacement du magasin de certificats.

Cas d’un certificat « internet »

Si vous avez acheté votre certificat auprès d’un organisme certificateur (Gandi pour nous, mais aussi OVH, Sectigo … Let’s encrypt gratuit), Access Client Solutions ne devrait rien vous demander et accepter directement le certificat : les autorités présentes dans le magasin associé à votre JVM permettent la validation.

Vous pouvez rencontrer des problèmes avec d’anciennes installations de Java non mises à jour : les nouvelles autorités de certification ne seront pas présentes. Bien sûr cela n’arrive jamais.

Cas d’un certificat « local »

Pour un certificat que vous avez généré sur votre IBM i, ou autre plateforme dans votre SI, si vous disposez de vos propres autorités de certification internes (fréquent dans les sociétés de grande taille) : Access Client Solutions ne dispose pas des autorités permettant la validation !

Remarque :

Si vos équipes de déploiement des postes client livrent les autorités de certification dans le magasin de la JVM, vous revenez dans le cas précédent.

A la première connexion, vous avez ce message :

Non : vous refusez la connexion

Oui : l’autorité de certification est ajoutée au magasin de certificats d’ACS.

Après avoir répondu « Oui » :

Aucun message affiché lors des prochaines connexions.

Changement de certificat

Comment faire en sorte que la sécurisation de vos services ou un changement de certificat soit transparent pour vos utilisateurs ?

Nous savons que demander à des centaines d’utilisateurs de répondre « Oui » peut générer un support très important aux équipes et être anxiogène.

Mise en place

Au-delà du certificat, il faut procéder aux changements de configurations : au niveau de la définition du système et/ou de la session 5250.

Pour le certificat, plusieurs solutions :

  1. Vous disposez d’un poste modèle sur lequel vous avez installé ACS, et importez manuellement l’autorité de certification. Il vous suffit alors de déployer le fichier cacerts de ACS sur les différents postes.

Ce dernier est ici : "C:\Users\{USER}\Documents\IBM\iAccessClient\Private\{USER}\cacerts"

  1. Dans le fichier de configuration AcsConfig.properties : vous pouvez indiquer un fichier cacerts mutualisé sur un lecteur réseau par exemple :

  1. Injection du certificat en mode commande

ACS dispose de commande, avec option silencieuse :

/PLUGIN=certdl => demande à downloader l’autorité de certification et l’importer dans le magasin

/SYSTEM=nom système configuré => depuis le système en question

A intégrer dans vos outils de déploiement pour exécution sur chaque poste client ! Le certificat est ensuite visible dans le menu « Outils » puis « Gestion des clés ».

Renouvellement

  1. Le certificat est issu de la même autorité de certification que le précédent : rien à faire ! C’est l’autorité qui est stockée, pas le certificat lui-même
  2. Le certificat est issu d’une autre autorité (autre fournisseur, autorité précédente périmée ou invalidée) : il faut injecter l’autorité dans le magasin de certificat (cf Mise en place)

En synthèse : pas de difficulté, plusieurs solutions en fonction de votre organisation et outillage !

N’oubliez pas de renouveler vos certificats avant la date d’expiration …

Je n’ai pas voulu mettre optimisation dans le titre de l’article, c’est pourtant bien ce qui nous est souvent demandé.
Avant de chercher à optimiser les requêtes, il est utile de vérifier que quelques bonnes pratiques de base sont respectées dans l’écriture de la requête !

Dans le cas traité, on s’intéresse particulièrement à plusieurs éléments :

  • critères de jointure
  • critères de sélection
  • critères de groupage
    Objectif recherché : que tous ces critères soient exprimés, si possible, sans calcul !
    Une zone calculée ne peut être prise en charge via un index par l’optimiseur … nous allons donc réécrire tout ce qui a été écrit d’une façon « humaine » !

Exemple

La requête utilisée dans cet article est un extrait d’un requête réelle, pour laquelle les noms de tables et colonnes ont été modifiées …

Critère de jointure

Ce point n’impacte que peu les performances, car le moteur SQL réécrit la requête pour nous, mais apporte plus de lisibilité.
On évite ce genre de syntaxe (produit cartésien) :

SELECT …
FROM ADHENT,
     ADHDET
WHERE (ADHENT.GJCMP = ADHDET.GACMP#
              AND ADHENT.GJGL# = ADHDET.GAGL#A
              AND ADHDET.GAACCD = '1')
          AND ((ADHDET.GATYPE IN (
                      'EX',
                      'IN'
                  ))

Pour exprimer sur la jointure les critères :

select ADHENT.*
from ADHENT
join ADHDET ON (ADHENT.GJCMP = ADHDET.GACMP#
AND ADHENT.GJGL# = ADHDET.GAGL#A
AND ADHDET.GAACCD = '1')
WHERE (ADHDET.GATYPE IN (
'EX',
'IN'
)) ;

Critères de sélection

Requête de départ :

select ADHENT.*
from ADHENT
join ADHDET ON (ADHENT.GJCMP = ADHDET.GACMP#
AND ADHENT.GJGL# = ADHDET.GAGL#A
AND ADHDET.GAACCD = '1')
WHERE ADHDET.GATYPE IN ( 'EX', 'IN' )
AND (ADHENT.GJACMO <> 13)
AND ADHENT.GJCMP IN ('10')
AND CASE
WHEN ADHENT.GJJLDT = 0 THEN '01/01/9999'
ELSE DATE( SUBSTR(ADHENT.GJJLDT, 5, 2) || '/' ||
SUBSTR(ADHENT.GJJLDT, 7, 2) || '/' ||
SUBSTR(ADHENT.GJJLDT, 1, 4))
END BETWEEN '2016-01-01' AND '2017-12-31'
AND SUBSTR(ADHENT.GJGL#, 1, 6) BETWEEN '615540' AND '615540'
AND CASE
WHEN TRIM(ADHENT.GJLTG#) = '' THEN 'N'
ELSE 'Y'
END = 'N'

Il est possible de remplacer toutes les valeurs calculées et de les inverser !

   AND CASE
         WHEN ADHENT.GJJLDT = 0 THEN '01/01/9999'
         ELSE DATE( SUBSTR(ADHENT.GJJLDT, 5, 2) || '/' ||
                    SUBSTR(ADHENT.GJJLDT, 7, 2) || '/' ||
                    SUBSTR(ADHENT.GJJLDT, 1, 4))
       END BETWEEN '2016-01-01' AND '2017-12-31'

Devient  :

AND ADHENT.GJJLDT between int(date('2016-01-01')) AND int(date('2017-12-31'))

Sélection sur code :

   AND SUBSTR(ADHENT.GJGL#, 1, 6) BETWEEN '615540' AND '615540'

Devient :

AND ADHENT.GJGL# BETWEEN '615540' ||'0000000000' AND '615540' || '9999999999'

Sélection sur code :

   AND CASE
         WHEN TRIM(ADHENT.GJLTG#) = '' THEN 'N'
         ELSE 'Y'
       END = 'N'

Devient :

AND ADHENT.GJLTG# = ''

Ce dernier exemple illustre bien la capacité du cerveau humain à raisonner et non pas à exprimer des critères techniques !

Critères de groupage (et mise en forme)

Le groupage est souvent effectué en dernier, c’est-à-dire après l’ensemble des jointures. Vous êtes alors contraints d’ajouter un nombre important de colonnes dans le groupage, colonnes faisant l’objet de mise en forme pour un affichage adapté à l’utilisateur, et donc sur des zones calculées !
Nous proposons l’inverse :

  • d’abord on calcule les données, nécessitant groupage
  • ensuite on va chercher, par des jointures, des éléments complémentaires et on met en forme (calcul) les valeurs
    Pour cela les CTE (Common Table Expressions) nous sont d’un grand secours.

Par exemple :

with tmp as (
   SELECT ADHENT.GJCMP,
          ADHENT.GJGL#,
          ADHENT.GJJLTP,
          ADHENT.GJJLCD, 
          ADHENT.GJJLNO,
          ADHENT.GJINV#, 
          ADHENT.GJDESC,
          ADHENT.GJJLDT,
          ADHENT.GJMVM#,
          ADHENT.GJTYPE,
          ADHENT.GJLTG#,
          ADHENT.GJLTGD,
          SUM(ADHENT.GJAMT$) as somme1,
          SUM( CASE
                 WHEN ADHENT.GJAMT$ > 0.00 THEN ADHENT.GJAMT$
               END) as somme2,
          SUM(
               CASE
                 WHEN ADHENT.GJAMT$ < 0.00 THEN (-1 * ADHENT.GJAMT$)
               END) as somme3
   from ADHENT
   join ADHDET ON ...
   WHERE ...
   GROUP BY ADHENT.GJCMP,
            ADHENT.GJGL#,
            ADHENT.GJJLTP,
            ADHENT.GJJLCD,
            ADHENT.GJJLNO,
            ADHENT.GJINV#,
            ADHENT.GJDESC,
            ADHENT.GJJLDT,
            ADHENT.GJMVM#,
            ADHENT.GJTYPE,
            ADHENT.GJLTG#,
            ADHENT.GJLTGD )

select tmp.GJCMP,
        SUBSTR(tmp.GJGL#, 7, 4),
        SUBSTR(tmp.GJGL#, 1, 6),
        tmp.GJJLTP,
        tmp.GJJLCD || '-' || RIGHT(CONCAT('00000000', TRIM(CHAR(tmp.GJJLNO))), 8),
        tmp.GJJLNO,
        TRIM(tmp.GJINV#),
        tmp.GJDESC,
        CASE WHEN tmp.GJJLDT = 0 THEN '01/01/9999'
             ELSE DATE( SUBSTR(tmp.GJJLDT, 5, 2) || '/' ||
                        SUBSTR(tmp.GJJLDT, 7, 2) || '/' ||
                        SUBSTR(tmp.GJJLDT, 1, 4))
        END,
        tmp.GJMVM#,
        TRIM(tmp.GJTYPE),
        tmp.GJLTG#,
        tmp.GJGL#,
        ADHCMP1.ZLARGN,                 
        TRIM(ADHCMP2.ZRNAME),           
        CASE WHEN tmp.GJLTGD = 0 THEN '01/01/9999'
             ELSE DATE( SUBSTR(tmp.GJLTGD, 5, 2) || '/' ||
                        SUBSTR(tmp.GJLTGD, 7, 2) || '/' ||
                        SUBSTR(tmp.GJLTGD, 1, 4))
        END,
        somme1,
        somme2,
        somme3
 from tmp 
   LEFT OUTER JOIN ADHCMP1 ON ADHCMP1.ZLCMP  = tmp.GJCMP
                           AND ADHCMP1.ZLLOC  = SUBSTR(tmp.GJGL#, 7, 4)
   LEFT OUTER JOIN ADHCMP2 ON ADHCMP1.ZLCMP  = ADHCMP2.ZRCMP
                           AND ADHCMP1.ZLIRGN = ADHCMP2.ZRRGN ;

Avec ces quelques règles, simples dans leur principe, vous vous assurez que le moteur SQL pourra utiliser pleinement vos index. Cela ne signifie pas qu’il ne sera pas nécessaire d’optimiser par la suite.

Pour finir le cas concret évoqué ici :
– 4 fichiers dans la jointures :
– 500 Millions , 1 Million, 1.000 et 70 enreg
– 4.600 enreg en retour

Requête d’origine : 2 min 40 s (ce qui est déjà très bien, avec un scan de table sur le plus gros fichier).
Après réécriture : 40 ms

Bien sûr, les index nécessaires étaient déjà en place pour atteindre ce niveau de temps de réponse.

Encore une fois, SQL est le meilleur moyen d’accéder à la donnée, aussi complexe soit elle.

Par le meilleur, j’entends :

  • le plus simple : écrire un programme RPG/COBOL équivalent demanderait une quantité de code importante (et donc probabilité de bug)
  • le plus efficace (40 ms) : à condition que l’on donne à SQL les moyens d’être efficace

En conclusion : travailler d’abord sur la donnée, occupez vous ensuite de la mise en forme !

, , Les Fichiers Markdown

Ce son des fichiers qui ont l’extension MD, ce format a été créer par John Gruber, son but était de produire des fichiers formatés très simple à administrer un peu comme RTF mais encore en plus simple.

Ce format a été adopté dans le monde open source comme un standard, par exemple les gens qui publient sur Github, mettrons un readme.md pour décrire leurs publications.
https://gist.github.com/JulienRAVIA/1cc6589cbf880d380a5bb574baa38811

La syntaxe est très simple vous pouvez l’apprendre ici :

https://blindhelp.github.io/recapitulatifsyntaxemarkdown.html

Par exemple, pour mettre des titres vous devrez utiliser le caractère #

Si la syntaxe est relativement simple, nous vous conseillons d’utiliser un éditeur pour commencer

Celui que nous utilisons s’appelle JOPLIN (Merci à Yvon qui nous l’a fait découvrir)

Vous pouvez le télécharger là https://joplinapp.org/

(il existe sous forme d’extension pour VSE également, et même sur téléphone)

L’utilisation est très simple, et relativement classique pour les utilisateurs de produits Windows

Vous avez une barre avec les différents éléments que vous voulez intégrer.

L’outil est WYSIWYG ce qui permet de voir en temps réel ce que vous voulez faire

il dispose également de nombreuses possibilités d’exportation comme HTML et PDF

Conclusion :

C’est un format simple à utiliser et c’est un standard pour les nouveaux qui arrivent sur notre plateforme.
il est donc fortement conseillé de vous y mettre, et l’effort n’est pas important au regard de ce qu’il peut rapidement vous apporter.

Vous pourrez facilement faire des docs techniques de qualité et les exporter, il existe de nombreuses extensions pour vous aider

Sites à connaitre

https://fr.wikipedia.org/wiki/Markdown

https://www.markdownguide.org/basic-syntax/

https://www.ionos.fr/digitalguide/sites-internet/developpement-web/markdown/ (en français)

Les annonces de la TR1 de la 7.5 ou TR7 de la 7.4 sont sorties et disponibles ici https://www.ibm.com/support/pages/node/1119129/


• Voici selon nous 5 nouveautés à suivre dans cette Technology Refresh

• 1) La possibilité de faire des mises à jour sur des flux json avec la fonction JSON_UPDATE , ça fait longtemps que nos équipes râlaient, parce qu’elles devaient faire du bricolage quand on travaillait sur du flux json.


• 2) La possibilité d’exécuter des fonctions table remote, par exemple avec le service REMOTE TABLE, un object_statistics sur une partition distante. Ça peut avoir du sens pour automatiser des contrôles de cohérence.


• 3) Les nouvelles fonctions table, SYSTOOLS.AUDIT_JOURNAL_xx qui permettent de traiter les postes d’audit et plus globalement les nouveautés sur les audits comme la disponibilité d’IDS dans Navigator for i qui n’était pas présent dans la nouvelle interface.


• 4) SELF (SQL Error Logging Facility) qui va permettre de mettre au point les traitements SQL en attrapant de manière plus fine les erreurs et en pouvant les suivre dans le temps sans passer par un mode de debug parfois trop bavard en log.


• 5) Les nouveaux services pour administrer Object Connect (vous savez les commandes SAVRSTxxx, CHANGE_OBJECTCONNECT et OBJECTCONNECT_INFO), un petit rappel, Object Connect peut désormais fonctionner en IP. Disponible par PTF et c’est la dernière fonction SNA qui n’avait pas d’équivalent ip. Ces nouveaux services permettront d’administrer et d’avoir des informations sur ce qui s’exécute dans les échanges inter-machines.


• Rendez-vous en décembre pour les premiers tests.

, , Base64 en SQL avec les nouvelles fonctions de QSYS2 !

La 7.4 TR5 (et 7.3 TR11) ont apporté de nouvelles fonctions http dans QSYS2 en remplacement de celles fournies dans SYSTOOLS (cf https://www.volubis.fr/Pausecaf/PAUSECAF88.html).

Dans le même temps, nous avons droit à un refresh des fonctions utilitaires.

Parlons donc de l’encodage/décodage base64 !

Différences entre les fonctions fournies :

Les fonctions n’ont pas le même nom pour éviter toute ambiguïté :

Dans SYSTOOLS : BASE64ENCODE et BASE64DECODE

Dans QSYS2 : BASE64_ENCODE et BASE64_DECODE

L’implémentation des nouvelles fonctions (QSYS2) est basée sur Axis (en C natif), contrairement aux fonctions historiques de SYSTOOLS en Java. L’empreinte mémoire est donc bien meilleure avec les fonctions de QSYS2.

Surtout, les paramètres diffèrent : dans la version SYSTOOLS, la taille des paramètres est très limitée, et nous sommes donc sur du VARCHAR jusqu’à 4Ko maximum encodé. Les nouvelles versions utilisent des CLOB et BLOB jusqu’à 2Go !

Usages

Données caractères

On utilise régulièrement l’encodage base64 pour transmettre une authentification par profil/mot de passe, par exemple une authentification http basic.

Les deux fonctions renvoient bien sur le même résultat :

Si vous utilisez un convertisseur en ligne, vous n’obtenez pas le même résultat :

Par exemple sur https://simplycalc.com/base64-encode.php :

La raison est simple : l’encodage base64 a pour objectif d’exprimer sous forme de caractères une donnée binaire. Le paramètre en entrée des fonctions QSYS2.BASE64_ENCODE et SYSTOOLS.BASE64ENCODE sont donc un BLOB (Binary Large Object) ou un VARCHAR avec CCSID 65535 (signifie pas de conversion).

La chaine de caractères ‘toto’ est donc transmise ici en EBCDIC et c’est la valeur binaire correspondante qui est encodée en base64.

Pour être conforme au standard : convertissez les chaines de caractères en UTF-8 :

Pour décoder des données, on utilise SYSTOOLS.BASE64DECODE et QSYS2.BASE64_DECODE :

Le résultat affiché diffère.

La aussi c’est un effet de bord du changement de type de paramètre, ET de la configuration de ACS :

La fonction de SYSTOOLS étant en VARCHAR, elle est interprétée dans le CCSID du travail. La fonction de QSYS2 renvoyant un BLOB, il n’y a pas de conversion directe possible en caractères.

La valeur binaire renvoyée est bien la même. Si l’on teste en passant par un fichier :

Données binaires

L’objectif premier est tout de même de pouvoir travailler sur des valeurs binaires.

On utilise une image sur l’IFS en tant que donnée binaire à encoder. L’image fait 158Ko, une valeur très raisonnable.

Pour faciliter la démonstration, on travaille étape par étape avec des variables SQL.

Pour lire le fichier image en binaire :

Script de test :

Les résultats semblent concordants :

Mais :

C’est le problème de la longueur des paramètres des fonctions de SYSTOOLS !

Dans l’historique :

On a un SqlCode à 0 mais un SqlState en classe ‘01’ !

On décode notre image :

Les fichiers d’origine et le fichier encodé/décodé sont bien identiques !

Les nouvelles fonctions, au-delà de l’implémentation en C, nous apportent la possibilité d’encoder et décoder des « documents » (image, pdf …à) en base64. Très utile pour faire transiter des informations binaires dans nos web services par exemple !

Et la limite à 2Go semble raisonnable.

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

, ACS sous Chromebook

Vous nous avez demandé plusieurs fois, si on pouvait installer et faire fonctionner ACS sur un Chromebook.

Donc nous avons fait une RFE chez IBM qui a été refusée .

Nous avons donc décider de faire un test par nous même :

Prérequis avoir un Chromebook à jour avec un processeur x86 en 64 bits

Installer Linux, vous pouvez laisser tout les paramètres par défaut
Après l’installation, lancer l’explorateur de fichier
Aller dans l’onglet ‘Linux fichiers’
Vous devez y extraire le fichier ZIP d’ACS
Vous devez maintenant installer Java
Par exemple ‘sudo apt install openjdk-11-jre’
Aller dans Linux_Application (‘cd Linux_Application’)
Exécuter la commande : ‘./install_acs_64’
Suivre le processus classique de setup (sélectionner les options nécessaires)
Une fois l’installation terminée, quitter le terminal
Chercher IBM dans les applications
Si il est présent, tout est bon
Sinon redémarrer le ChromeBook

Ca peux paraitre compliqué comme ca, mais c’est relativement simple en réalité et ça prend moins d’une heure.

Nous avons donc testé pendant une demi-journée le travail sur ce terminal.

Voici ce qu’on a constaté


Le lancement est un peu long
Pas de touche Fx sur le clavier vous devrez les mettre en incrusté dans votre session
Pas de clic droit
Des comportements d’affichage assez particuliers en cas de perte de focus.


Ma ca reste tout à fait utilisable.

Conclusion :


Ca fonctionne et sur un poste pour une utilisation occasionnelle c’est tout à fait acceptable

Merci à Clément pour ces tests.

, , Débogage de grandes variables avec RDi

Le débogage avec RDi apporte confort et souplesse, mais il y a un point sur lequel il faut certainement faire un rappel : le débogage de grandes chaines de caractères.

Notre exemple

Simplissime :

Débogage avec RDi

Les variables et leur valeur apparaissent dans la vue dédiée « Variable »

Par contre, « seuls » 10.000 caractères sont affichés, impossible de voir la suite de la variable. De plus, impossible de modifier la variable :

La vue Moniteurs

Cette vue, qui sert déjà pour les variables des programmes CL, va également nous aider pour les variables RPG en permettant plus d’options. Il est possible d’utiliser dans cette vue toutes les syntaxes usuelles de STRDBG avec la commande EV (ou EVAL) qui supporte des compléments, des fonctions intégrées etc …

Vous pouvez ajouter une expression monitorée en faisant un click droit sur une variable puis « Contrôler une expression »

Vous pouvez également saisir manuellement des expressions (vous reconnaîtrez les syntaxes du STRDBG) :

Vous pouvez alors utiliser %SUBSTR, DIGITS etc … Pour vous permettre de cibler une sous-chaîne spécifique par exemple.

Mais impossible de modifier une sous-chaîne par ce moyen :

Modification de variables

Vous devez utiliser cette syntaxe :

Attention : les chaines de caractères sont passées en majuscule ! Sauf à travailler en hexadécimal (est-ce réellement pratique ?)

Extension via APAR SE71579

L’APAR https://www.ibm.com/support/pages/apar/SE71579 permet d’augmenter les limites. Désormais :

Extend the string length limits to bigger values for            
fixed-length and variable-length string values in RDi debug.    
Maximum editable limit is now 4K (4096). Maximum display limit  
is now 30K (30720). The limits are 1K (1024) in the current    
driver.

Vous devez installer les PTF SI71302 (7.3) ou SI71314 (7.4). Après application on peut voir jusqu’à 30720 caractères dans notre cas :

La modification reste limitée à 4Ko.

, Client FTPS avec la nouvelle interface DCM

Pas encore habitué à la nouvelle interface de DCM ? Les options sont rangées différemment, voici donc un guide pour activer le FTPS client !

Informations nécessaires

Lorsque vous avez besoin d’initier une connexion FTP vers un serveur sécurisé par un certificat SSL, vous n’avez pas besoin d’importer le certificat serveur, mais de vous assurer de disposer des autorités de certification (CA) correspondantes.

Par exemple, pour le serveur jupiter.gaia.fr, voici le certificat lié au service FTP :

Ce certificat a été émis par une autorité Let’s Encrypt Authority X3, elle-même issue d’une autorité DST Root CA X3. Ce sont ces deux autorités de certification dont il faut disposer.

Connexion à DCM

La nouvelle interface est disponible ici : http://monIBMi:2006/dcm

Connectez-vous avec un profil fort :

Ouvrez le magasin *SYSTEM :

L’ensemble des certificats vous est proposé, nous allons filtrer pour n’afficher que les autorités de certifications :

Seuls les CA sont affichées désormais. En naviguant / cherchant, on retrouve nos 2 certificats racines :

Les options de recherches / tri :

Importation d’une autorité

Si un ou plusieurs CA racine ne sont pas trouvés, vous devez les importer. Pour cela, transférer le certificat sur l’IFS (via FTP, NetServer etc …).

Définir les CA pour FTPS

Il ne reste maintenant plus qu’à indiquer au client FTP la ou les autorités de certification auxquelles faire confiance : tous les certificats serveurs issus de ces autorités seront autorisés.

Allez sur l’option « Manage Application Definition » :

Filtrer puis sélectionner FTP Client :

Par défaut, si aucun CA n’est indiqué, FTP fait confiance à l’ensemble des CA connu dans le magasin *SYSTEM. Sinon, uniquement aux CA indiqués :

Sélectionner les CA nécessaires puis Define :

Test

Renseigner profil et mot de passe lorsque demandé : la connexion est sécurisée, vos données et les commandes FTP seront cryptées lors de l’échange.