« Pre-upgrade Verification tool » plus connu sous le nom de PRUV est maintenant en téléchargement pour tous.

Il va vous permettre d’effectuer vos contrôles avant de lancer une mise à jour de version OS.

 

Pour le télécharger rendez vous à l’adresse

https://www-01.ibm.com/support/docview.wss?uid=nas8N1014074

après une explication le chargement ce passe ici

https://www-01.ibm.com/marketing/iwm/iwm/web/dispatcher.do?source=ipvt

Vous avez besoin de vos identifiants IBM pour télécharger

Vous pouvez télécharger soit avec Download director ou par HTTP

Vous allez récupérer un zip exécutable  exemple : pruv_.4.0.nnnnnn.exe

après dezippage,  vous obtenez un fichier run_pruv.bat que vous allez lancer.

Vous devez accepter la clé puis vous identifier.

Choisir votre version cible , ensuite , next

Vous obtenez un rapport très facile à lire, avec les interventions à faire

Vous pouvez facilement l’exporter au format HTML

Conclusion :

Un petit outil bien sympathique qui permet de valider des choses avant votre migration !

Attention, il ne remplace pas  la « Préparation de l’installation » (go licpgm puis Option 5)  que vous devrez quand même l’utiliser.

par exemple:

Pour augmenter les tailles LIC ou pré accepter les licences, mais PRUV vous l’aura indiqué …

 

Nouveauté sur le SBMJOB en V7R4

La V7r4 apporte une nouveauté pour la commande SBMJOB, vous pouvez désormais définir un programme d’exit pour cette commande (QIBM_QWT_SBMJOB).

Le programme d’exit prend la main avant de placer l’exécution de la commande demandée dans la jobq.

Ce point d’exit, peut être mis sur une jobq ou sur toutes, *ANY

2 paramètres

Le premier contiendra plein d’informations nécessaires, Utilisateurs, jobq, jobd etc…

Le second contient la taille dans un binaire de 4

Vous pouvez donc facilement loguer une demande sensible, réorienter un travail en fonction d’un utilisateur ou d’un contexte, voir le cas échéant interdire la demande de ce travail.

Extrait d’un exemple

Pour que les jobs de l’utilisateur exploit parte dans une file de travail en *NOMAX

DCL &SBMJOB *CHAR 1000
….
DCL &USER *char 10

chgvar &user %sst(&sbmjob 14 10)

if cond(&user = ‘EXPLOIT’) then(do)

enddo

Conclusion :
Ça peut être indispensable si vous avez des ERPs de type boite noire, et que vous avez du mal à paramétrer certaines taches .

Remarque :
Vous avez également un nouveau point d’exit sur la commande CHGJOB (QIBM_QWT_CHGJOB)

Mise à jour du firmware sur une machine sans console HMC.

 

Quand on audite chez nos clients souvent les dernières mises à jour du firmware sont très vieilles, vous pouvez voir ces informations par la commande DSPFMWSTS,  c’est surtout vrai dans les sociétés qui n’ont pas de console HMC.

Attention, même si vous n’avez qu’une seule partition et donc pas de HMC Vous pouvez avoir des problèmes de compatibilité entre votre partition et votre firmware.

Ces plantages interviennent suite à l’application de PTFs, souvent microcodes et se matérialisent par un IPL très long voir qui n’aboutit pas. Si c’est le cas vous devrez arrêter électriquement votre machine, pour pouvoir vider le cache et la relancer, et ensuite démarrer votre partition.

C’est donc la partition qui doit pousser les mises à jour au Firmware vous le savez en voyant *OPSYS dans la commande DSPFMWSTS, l’autre valeur est *HMC qui indique que c’est votre HMC qui fait ces mise à jour.

Vous pouvez également avoir ces infos depuis la version 7.3 en utilisant la vue SYSTOOLS.FIRMWARE_CURRENCY
exemple pour la date de mise à jour en cours :

SELECT FW_RELEASE_DATE, FW_MACHINE_TYPE_MODEL FROM
SYSTOOLS.FIRMWARE_CURRENCY
vous avez également le niveau recommandé zone FW_RECOMMENDED_UPDATE
Cette vue pour fonctionner doit avoir accès à la page :
https://www14.software.ibm.com/support/customercare/flrt/liteTable?prodKey=fw&format=json

Les PTF, FSP code commence par MH, vous ne les avez pas si vous êtes en application à partir de la console HMC.

Vous devrez rapidement récupérer le dernier niveau de MH correspondant à votre configuration, vous avez l’information ici :
https://www-01.ibm.com/support/docview.wss?uid=nas8N1021194

 

Vous devrez alors télécharger le groupe PTF sur fix central et l’appliquer par un IPL de type *FULL , attention le temps de l’IPL peut être doublé … D’après les documentations IBM, un IPL de type système peut suffire en effet s’il y a une PTF firmware, il l’applique mais …

Malheureusement ces groupes ne sont pas téléchargeables en automatique, le conseil est donc de le faire une ou 2 fois par an l’opération et à chaque montée d’OS.

Elle  s’applique comme une autre cumulative

Pour contrôler l’application des PTFs, utilisez la commande DSPPTFAPYI

Il est possible que vous ayez des messages CPF6602 dans la log sur d’autres PTF, si vous n’avez pas suivi régulièrement l’application de celles ci.

Pour corriger, la première possibilité est de passer la commande UPDPTFINF pour mettre à jours les informations PTF.

Si cela ne suffit pas, par exemple si vous avez des PTF de versions précédentes, vous devrez supprimer les fichiers QAPZPTF* de la bibliothèque QUSRSYS et faire un IPL qui les recréera avec les informations à jour à partir des modèles dans QSYS.
Vous ne pouvez pas lire les informations de ce fichier, mais vous pouvez y accéder indirectement par les vues de qsys2, PTF_INFO.
exemple :
Voir les PTFs chargées, mais pas encore appliquées
SELECT PTF_IDENTIFIER, PTF_IPL_REQUIRED, A.*
FROM QSYS2.PTF_INFO A
WHERE PTF_LOADED_STATUS = ‘LOADED’
ORDER BY PTF_PRODUCT_ID

Pour rappel, il vaut mieux effacer les savfs de PTF qui sont dans qgpl, en utilisant la commande DLTPTF

Exemple DLTPTF PTF(*PRMAPY) effacera les savfs des PTFs appliquées de manières permanentes.

Conclusions :

Vous êtes le garant d’un écosystème et il faut bien mettre les correctifs sur :
La partition
Le firmware
La HMC si vous en avez une

Sans être un expert base de données, on peut être amené à faire un minimum de gestion. Voici comment gérer vos index.

Index advisor est un logiciel, intégré à SQL, qui analyse tous les index inexistants dont le système à besoin et qui  choisit de les créer.

il collecte des informations sur le nombre de fois dont il en a eu besoin, la dernière utilisation etc…

On estime aujourd’hui l’impact de vos index à 70 % de la performance totale de votre SGBD.

Il est donc important de savoir bien gérer ces index.

Pour matérialiser index advisor, Vous pouvez voir des informations à plusieurs endroits :

Dans ACS Shémas/Tables/ clique droit / utilisation index , ou directement dans le table système interrogeable par un simple select sur la table QSYS2.SYSIXADV,
ou un select sur la vue fournie sur cette table QSYS2/CONDENSEDINDEXADVICE nom sql et CONDIDXA nom système.

Nous allons voir comment être efficace en utilisant ces informations.

1) Périmètre

Il faut déterminer le périmètre que vous voulez analyser.
C’est une liste de bibliothèques contenants vos pf ou un schéma contenant vos tables.

2) Réinitialisation des statistiques

Il va vous falloir réinitialiser régulièrement les statistiques
des index sur votre périmètre, souvent à la semaine ou au mois.
Il existe une procédure sql qui permet de réaliser cette tache,
RESET_TABLE_INDEX_STATISTICS nom sql et RESET_STAT nom système.
Exemple :
CALL QSYS2.RESET_TABLE_INDEX_STATISTICS(‘Votre_Bib’,’%’, ‘*YES’);

-% indique pour toutes les tables de votre bibliothèque.
-la valeur *YES indique que la ligne sera supprimée de la table QSYS2.SYSIXADV.

3) Analyse

Vous allez pouvoir analyser les index qui ont été nécessaire depuis votre précédente réinitialisation !

Voici un exemple de requête sur une bibliothèque de votre périmètre :

SELECT
substr(TABLE_NAME, 1, 10) as TABLE_NAME,
LAST_ADVISED,
TIMES_ADVISED,
substr(KEY_COLUMNS_ADVISED, 1 , 100)
FROM QSYS2/SYSIXADV WHERE TABLE_SCHEMA = ‘Votre_Bib’
ORDER BY TIMES_ADVISED desc ;

4) Création

Vous allez pouvoir envisager des actions pour les index manquants que vous analysez comme pertinent.

Exemple ceux qui ont été demandés 500 fois au moins
SELECT
substr(TABLE_NAME, 1, 10) as TABLE_NAME,
LAST_ADVISED,
TIMES_ADVISED,
substr(KEY_COLUMNS_ADVISED, 1 , 100)
FROM QSYS2/SYSIXADV WHERE TABLE_SCHEMA = ‘Votre_Bib’
and TIMES_ADVISED > 500
ORDER BY TIMES_ADVISED desc

Il y a 2 types d’actions possibles

A) Les index nécessaires

Il faudra les construire.

B) Les index demandés :

A cause d’une requête mal écrite.
On trouve très souvent le défaut dans la clause WHERE d’un select

Exemple :

Vous avez une liste d’objets avec un index sur le nom d’objet et le Type

Si vous écrivez :

select * from votre_table where …

order by objet , type
Vous allez utiliser l’index existant.

Si vous écrivez
select * from votre_table where …

order by type, objet

Le système va construire un nouvel index, ordonné par type puis par nom d’objet, mais il ne sert à rien…
Si vous avez la main sur l’applicatif, corrigez la requête …

5) Génération de scripts

Il existe des procédures dans la bibliothèque SYSTOOLS pour vous
aidez dans votre gestion.

La première procédure va permettre de créer des index automatiquement sur une table en fonction de critères statistiques :
ACT_ON_INDEX_ADVICE(‘Votre_bib’ , ‘Votre_table’, Nb_fois,
nb_maint, tps_estim)

Exemple (plus de 5OO utilisations) :
CALL SYSTOOLS.ACT_ON_INDEX_ADVICE(‘Votre_bib’,’votre_table’, NULL,
500, NULL )

La valeur à utiliser est à déterminer après avoir fait une analyse.

Cette méthode est plus destinée à un applicatif avec un ERP dont vous n’avez pas les sources et par conséquent dont où vous ne pouvez pas intervenir directement dans l’applicatif.

 

La deuxième procédure va vous permettre de générer les scripts SQL en fonction de critères statistiques , qui vous aiderons à créer vos
index suggérés.
Vous devez créer un fichier source assez long, par exemple qsqlsrc.
Exemple
CRTSRCPF FILE(VOTRE_BIB/QSQLSRC)
RCDLEN(512)
TEXT(‘SOURCE pour génération index’)
voici la procédure
HARVEST_INDEX_ADVICE(‘Votre_bib’ , ‘Votre_table’, Nb_fois, nb_maint,
tps_estim, ‘Bib_src’, ‘Fic_src’)

Exemple:

CALL SYSTOOLS.HARVEST_INDEX_ADVICE(‘Votre_bib’,’votre_table’, 1, 500,
0, ‘Votre_bib’, ‘QSQLSRC’)

Pour exécuter vos scripts vous pouvez ensuite le faire par la
commande système RUNSQLSTM.

RUNSQLSTM SRCFILE(Votre_bib/QSQLSRC) SRCMBR(Votre_Table)
COMMIT(*NONE) NAMING(*SQL) ERRLVL(30) MARGINS(512)

MARGINS étant la longueur de votre fichier source.

Cette méthode permet de vérifier les index proposés avant de les générer. Toujours privilégier une correction de requête dans l’applicatifs que la génération d’un index pour palier des légèretés de programmation…

6) Suppression des index générés

Il est possible d’utiliser une procédure cataloguée REMOVE_INDEXES,
pour supprimer les index générés, ne supprime pas les autres index.

Vous pouvez la planifier une fois par an :

Exemple :

CALL SYSTOOLS.REMOVE_INDEXES(NULL, 1, ’12 MONTHS’)

Attention si vous voulez supprimer des index applicatifs,
il faut analyser ceux qui n’ont pas été utilisés et surtout penser à
supprimer les objets dépendants.

Conclusion :

Vous allez de en plus utiliser SQL et les index sont un facteur important de la gestion de votre base de données.
Il est donc intéressant de mettre en place une politique adaptée à la gestion de ceux ci.

, Premiers tests services web REST SQL

Une des fonctionnalités attendues disponible avec la 7.4 / 7.3 TR6 (SF99722 niveau 19) est la possibilité de déployer des services web (REST uniquement) basés sur des instructions SQL au lieu de programmes ILE.

 

Voici nos premiers tests, effectués « à vue » la documentation IBM n’étant pas encore disponible …

 

Services REST SQL

En bref, vous avez désormais les possibilités suivantes :

  • effectuer des SELECT, UPDATE, INSERT
  • appeler des fonctions SQL utilisateur (UDF), des fonctions tables (UDTF)
  • appeler des procédures stockées (procédures cataloguées)
  • utiliser directement la syntaxe VALUES …
  • retourner des données BINAIRES (images, pdf, …)

De plus, IWS vous propose également un format de sortie HTML, en plus de JSON et XML déjà en place. De quoi faciliter l’intégration de vos données dans des pages web !

 

Comment fait-on ?

Déployer un nouveau service : vos avez maintenant la possibilité de choisir SQL

Comme d’habitude pour les services REST, vous indiquez nom de service et nom de ressource

Maintenant, vous avez des paramètres spécifiques à un service basé sur SQL vous permettant de régler les conventions de nommage et la résolution des objets non qualifiés dans vos requêtes. Le fonctionnement est habituel en SQL. Pour simplifier : basé sur la *LIBL en convention *SYS, sur un schéma par défaut en *SQL

Vous pouvez indiquer plusieurs « procédures » dans un service REST SQL, c’est à dire plusieurs opérations disponibles au travers de votre service, et identifiées (plus tard) par des URL et/ou des méthodes HTTP différentes

Pour commencer simplement :

Bien sûr, vous pouvez utiliser des paramètres dans vos requêtes SQL, identifiés par « ? » :

L’outil est plutôt bien fait de ce côté-là : il est capable de détecter le type des données correspondant à vos paramètres en analysant le fichier :

Vous devez ensuite régler le comportement attendu de votre traitement :

la suite des écrans est classique et ne présente pas de particularité dû au SQL, en dehors du type de sortie *HTML proposé.

Quelques exemples de résultats fournis par les appels de différents services (renvoyant une ligne ou plusieurs lignes, en JSON, en XML, en HTML …) :

 

L’outil vous permet également d’obtenir des informations sur l’exécution et les erreurs SQL :

 

Données binaires

Maintenant, passons à la possibilité qui ouvre d’autres perspectives !

Avec les services basés sur des programmes ILE RPG/COBOL, nous n’arrivons pas à retourner des images ou documents binaires : toutes les données sont converties en UTF-8 (par défaut) pour sortir sur le flux HTTP. Nos données binaires ne supportent pas bien … seule solution jusqu’ici : encoder en base64 (c’est à dire en caractères) ! Mais cela complexifie, nécessite du temps machine et augmente la taille de la sortie.

Lors du déploiement, sélectionner le type « Media resource »

Vous devez indiquer le type de ressource (seule la première valeur est prise en compte) :

Dès lors, vos services web peuvent retourner des documents (au sens large), par exemple un pdf accessible depuis un navigateur :

Ou une image (vous devriez reconnaître) :

 

Adaptation des scripts shell

Un nouveau script shell a fait son apparition dans /qibm/proddata/os/webservices/bin : getConfigurationFile.sh

 

Les informations disponibles actuellement : https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/dW%20IBM%20Integrated%20Web%20Services%20for%20i/page/Script%20to%20generate%20property%20file%20for%20a%20service

Ce dernier génère deux fichiers pour un service :

  • un fichier .properties
  • un fichier .xml

Le fichier properties contient les attributs du service, des procédures/méthodes, du connecteur jdbc.

Le fichier xml est en réalité un fichier pcml contenant des balises spécifiques utilisées pour le déploiement d’un service.

Ces formats de fichiers permettront également le déploiement par script shell (avec installWebService.sh) des services REST SQL.

 

 

En conclusion

L’outil poursuit sa belle évolution, avec toujours plus de fonctionnalités et de possibilités ! Nous compléterons prochainement avec des tests plus approfondis.

D’ici là, bonnes vacances à tous, et rendez-vous à la rentrée, reposé et bronzé !

 

L’arrivée de la function table joblog_info qui permet de voir la log d’un travail ouvre de nouvelles manières de travailler.

En voici une qui va vous permettre de savoir si vous avez des données erronées dans vos fichiers PF.

Quand vous faites une requête avec un select sur un pf qui a des données en erreur, en fonction de votre interface vous obtenez des ++++ ou autres qui vous indique que vos données sont en erreur !

Mais surtout ça génère un message CPF5035 dans votre log qui vous indique la ligne et la zone en erreur

Exemple :

select substr(MESSA00007, 1, 10) as fichier ,
substr(MESSA00007, 21, 10) as biblio,
substr(MESSA00009, 55, 71) as texte
from table(qsys2.joblog_info(‘*’)) a
where MESSAGE_ID = ‘CPF5035’

Qui vous donnera

CLIENTS GAIA la zone CLIENTS_1.CAANC, numéro d’enreg 213, format *FIRST, membre
CLIENTS GAIA la zone CLIENTS_1.CAAN1, numéro d’enreg 213, format *FIRST, membre
CLIENTS GAIA la zone CLIENTS_1.CAAN2, numéro d’enreg 213, format *FIRST, membre

Ici on voit que sur l’enregistrement 213 (rang relatif) a des zones CAANC, CAAN1 et CAAN2  qui ont des données en erreur

Vous pouvez corriger facilement en faisant

update gaia.clients a set caanc = 0 where rrn(a) = 213

Voici un petit script CLLE qui vous permettra de savoir si un PF à des données en erreur

pgm parm(&table &lib)
dcl &table *char 10
dcl &lib *char 10
chkobj &lib/&table *file
RUNSQL SQL(‘drop table qtemp/wtest’) COMMIT(*NONE)
monmsg SQL9010
RUNSQL SQL(‘create table qtemp/wtest as (select * +
from’ *BCAT &LIB *TCAT ‘/’ *TCAT &TABLE +
*bcat ‘)with data’) COMMIT(*NONE)
monmsg SQL9010 exec(do)

/* ici votre traitement pour récupérer les erreurs CPF5035 */
/* select substr(MESSA00009, 55, 71) as texte */
/* from table(qsys2.joblog_info(‘*’)) a */
/* where MESSAGE_ID = ‘CPF5035’ */
/* vous devrez par exemple écrire ces données dans une table */

endpgm

Ce script est a améliorer en effet il ne donne que le premier enregistrement corrompu , sql interrompant le traitement à la première erreur.

L’opération SQL JSON_TABLE sert à extraire les données d’un flux JSON pour les intégrer en base de données.

Pour rappel, les services web REST renvoient  la plupart du temps des réponses en JSON.
L’opération fonctionne bien si le premier niveau hiérarchique du flux est un objet JSON,  pouvant lui-même contenir un tableau.
Prenons par exemple un flux JSON contenant l’objet « qteage » étant lui-même un tableau :

{
« qteage »: [
{
« agence »: « LY »,
« qte »: 567
},
{
« agence »: « PA »,
« qte »: 879
}
],
« code »: « OK »,
« message »: «  »
}

Nous pouvons récupérer les éléments du tableau sans problème par la requête :

select u.* from json_table( ‘{
« qteage »: [
{
« agence »: « LY »,
« qte »: 567
},
{
« agence »: « PA »,
« qte »: 879
}
],
« code »: « OK »,
« message »: «  »
}’, ‘strict $.qteage[*]’
COLUMNS( « CodAge » varchar(50) PATH ‘strict $.agence’ ,
« Quantite » decimal   PATH ‘strict $.qte’
)  ) AS U;

Par contre si le flux JSON renvoie directement un tableau, l’opération JSON_TABLE n’arrive plus à extraire les données :

Prenons par exemple, le flux suivant, qui est reconnu par les outils de validation en ligne :

Lorsque nous essayons de travailler avec ce flux, l’opération JSON_TABLE, ne fonctionne plus :

select u.* from json_table( ‘[
{
« agence »: « LY »,
« qte »: 567
},
{
« agence »: « PA »,
« qte »: 879
}
]’, ‘strict $.[*]’
COLUMNS( « CodAge » varchar(50) PATH ‘strict $.agence’ ,
« Quantite » decimal   PATH ‘strict $.qte’
)  ) AS U;

L’instruction est bien traitée, mais le résultat est vide :

IBM confirme que l’instruction attend un objet JSON et non un tableau sur le premier niveau hiérarchique.

Si vous êtes confronté à ce problème, vous n’aurez pas d’autre solution que de modifier le JSON reçu, pour ajouter un niveau hiérarchique qui englobera votre flux initial.

Par exemple par l’ajout de l’objet « data ». Votre flux deviendra :

{ « data » : 

[
{
« agence »: « LY »,
« qte »: 567
},
{
« agence »: « PA »,
« qte »: 879
}
] }

Vous pouvez le faire, entre autre, par SQL  :

SET :donnees = ‘{« data » : ‘ || trim(:donnees) || ‘}’ ;

Attention toutefois à l’encodage de votre résultat, le flux JSON d’origine est encodé en UTF8. Si le CCSID de votre machine est 65535, vous  devrez modifier le CCSID de travail pour que l’instruction SQL s’exécute sans erreur, soit au niveau du job, de l’utilisateur, de variables de travail…. Mais là c’est une autre histoire ! 

 

 

La version 7.4 arrive, et une des grandes annonces est l’abandon de *ANYNET.

(*ANYNET est une solution qui permet d’encapsuler SNA dans de l’IP)

C’est l’occasion de faire le point sur SNA.
Pour les plus jeunes SNA est une implémentation réseau un peu comme TCP/IP ou ISO avec les quels il a de grandes similitudes.
C’est une solution propriétaire (IBM) qui existait avant TCP/IP qui tend à le remplacer.
Souvent les gens pensent ne plus utiliser SNA mais réalité ils l’utilisent encore.

Voici trois traces persistantes qu’on retrouvent chez nos clients

  • 1) La commande SNDDST pour envoyer des mail
    2) l’utilisation des fichiers stockés dans QFLR (plus connu sous le nom de dossier partagés)
    3) l’utilisation des commandes SAVRST* qui permettent de distribuer des objets d’une machine à une autres.

Si vous utilisez une des 3 fonctions ne chercher pas vous êtes concernés.

Certes SNA ne semble pas être le sens de l’histoire, mais comment faire ?

  • Première Solution

  • Abandonner SNA purement et simplement
  • Attention à bien analyser l’impact beaucoup de sources recèlent des trésors cachés (SNDDST, SNDNETF, SBMNETJOB, SAVRSTLIB, etc …)
    il peut y avoir beaucoup de travail, par exemple OBJECT CONNECT n’a pas d’équivalent IP.
  • Quels gains peut on attendre ?
    Plus besoin de faire un SAVDLO dans votre sauvegarde globale
    Plus besoin de gérer la directory SNA
    Faire des envois de mail avec des historiques et de vraies pièces jointes.

 

  • Deuxième Solution

  • Faire durer SNA encore une peu.
  • Si vous avez plusieurs machines, vous allez être obliger de migrer vos connexion en Oject extended.
  • Ne perdez pas de temps, vous pouvez faire cette opération dès à présent ce qui simplifiera votre migration.
  • Cette deuxième solution ne vous dispense pas de petit à petit basculer des fonctions de SNA vers IP , on n’est pas sur que SNA sera Pérennisé dans le temps par IBM

Conclusion

  • Dans tous les cas, il faut penser à remplacer  petit à petit SNA
  • Par contre l’arrêt de *ANYNET sera brutal , alors anticipez !

Principales correspondances SNA / IP