17 mai 2012

Equilibrage de charge entre un Apache et deux HRaSpace v7 sous Tomcat



L'objectif est de faire en sorte que Apache répartisse les utilisateurs sur deux serveur Tomcat . Ceci peut être utile pour répartir la charge (load balancing) et sécuriser l'exploitation (crash d'un des serveurs). En revanche, il faudra livrer les mises à jour de l'arborescence du client riche sur chacun des serveurs. Cette configuration n'est donc adaptée qu'aux environnements sans publication par HRStudio.

La configuration initiale du site est la suivante :
  • un Apache en frontal,
  • un Tomcat avec son application HRaSpace v7,
  • une base JetSpeed déportée sur l'instance DB2 de HR Design.
A noter :
  • si un des Tomcat "tombe", HRAccess n'assure pas la persistance de la session des utilisateurs. Ceux initialement affectés au Tomcat défaillant seront basculés sur le rescapé où ils devront se ré-authentifier (ce n'est pas une configuration de "cluster" avec réplication de session).
  • Apache a été compilé avec le module proxy_balancer (présence du fichier /hraxxx/apache/modules/mod_proxy_balancer.so et dans httpd.conf : LoadModule proxy_balancer_module modules/mod_proxy_balancer.so)

  • L'expérience montre qu'un schema JetSpeed unique est suffisant.

Coté Tomcat


Mise en place d'un second tomcat et son fichier de configuration :
  • fermeture et copie de l'arbo tomcat /hraxxx/hraspace dans /hraxxx/hraspace.balancer, 
  • dans le server.xml du nouveau Tomcat, les ports 5208* sont modifiés en 5209* (pour mon test les Tomcat sont "côte à côte" sur le même serveur. Installés sur deux machines distinctes, cette modification serait inutile).
  •  Définition des Routes dans les fichiers "server.xml" de chaque Tomcat :
    <!-- Define the top level container in our container hierarchy
    <Engine name="Catalina" defaultHost="localhost">
    -->


    <Engine name="Catalina" defaultHost="localhost"
    jvmRoute="route1" debug="0">

(et route2 pour le second Tomcat)

Coté Apache


Fermer Apache, puis dans le extra/httpd_hraccess.conf de mon Apache (mon httpd.conf inclue cet extra) :

  • Mise en commentaire du routage initial (Tomcat unique) :
# Single local Tomcat
# ProxyPass /  ajp://localhost:52085/
# ProxyPassReverse /  ajp://localhost:52085/


  • Mise en place du "répartiteur" avec Proxy balancer,
  • Redirection de chacune des application HRaSpace (merci Stéphane pour le tuyau) sur le cluster  par ProxyPass,
  • Avec stickysession (pour que les requêtes de l'utilisateurs "restent" dirigées sur le serveur qui lui a été attribué lors de sa première transaction),
  • Correction avec ProxyPassReverse des messages retournés pour rétablir l'entête initial :

# Load balancing two local Tomcats

<Proxy balancer://HRaCluster>
   BalancerMember ajp://localhost:52085/ loadfactor=1 route=route1
   BalancerMember ajp://localhost:52095/ loadfactor=1 route=route2
   # byrequests / bytraffic / bybusyness
   # ProxySet lbmethod=bytraffic
</Proxy>

ProxyPass        /hra-space balancer://HRaCluster/hra-space stickysession=JSESSIONID|jsessionid nofailover=On
ProxyPassReverse /hra-space balancer//localhost:52085/hra-space
ProxyPassReverse /hra-space balancer//localhost:52095/hra-space
ProxyPass        /hr-dms    balancer://HRaCluster:52083/hr-dms stickysession=JSESSIONID|jsessionid nofailover=On
ProxyPassReverse /hr-dms    balancer//localhost:52085/hr-dms
ProxyPassReverse /hr-dms    balancer//localhost:52095/hr-dms
ProxyPass        /hr-rich-client balancer://HRaCluster:52083/hr-rich-client stickysession=JSESSIONID|jsessionid nofailover=On
ProxyPassReverse /hr-rich-client balancer//localhost:52085/hr-rich-client
ProxyPassReverse /hr-rich-client balancer//localhost:52095/hr-rich-client
ProxyPass        /hr-portlets    balancer://HRaCluster:52083/hr-portlets stickysession=JSESSIONID|jsessionid nofailover=On
ProxyPassReverse /hr-portlets    balancer//localhost:52085/hr-portlets
ProxyPassReverse /hr-portlets    balancer//localhost:52095/hr-portlets
ProxyPass        /hr-self-service balancer://HRaCluster:52083/hr-self-service stickysession=JSESSIONID|jsessionid nofailover=OnProxyPassReverse /hr-self-service balancer//localhost:52085/hr-self-service
ProxyPassReverse /hr-self-service balancer//localhost:52095/hr-self-service
ProxyPass        /hr-configuration-tool-web balancer://HRaCluster:52083/hr-configuration-tool-web stickysession=JSESSIONID|jsessionid nofailover=On
ProxyPassReverse /hr-configuration-tool-web balancer//localhost:52085/hr-configuration-tool-web
ProxyPassReverse /hr-configuration-tool-web balancer//localhost:52095/hr-configuration-tool-web
ProxyPass        /hr-admin-console balancer://HRaCluster:52083/hr-admin-console stickysession=JSESSIONID|jsessionid nofailover=On
ProxyPassReverse /hr-admin-console balancer//localhost:52085/hr-admin-console
ProxyPassReverse /hr-admin-console balancer//localhost:52095/hr-admin-console
ProxyPass        /hr-online-query  balancer://HRaCluster:52083/hr-online-query stickysession=JSESSIONID|jsessionid nofailover=On
ProxyPassReverse /hr-online-query  balancer//localhost:52085/hr-online-query
ProxyPassReverse /hr-online-query  balancer//localhost:52095/hr-online-query

ProxyTimeout 300

Coté Objet Site HRS

Créer une seconde fonction "Serveur Web" pour pouvoir accéder au second Tomcat sur la console d'administration Web de HRaSpace (je vois que l'on peut créer des "Cluster" de serveur Web mais je n'en connais pas les implications ... A tester).



Pour finir


  • Noter que le "balancer" Apache a sa propre console : http://mon.serveur.apache:52000/balancer-manager


     
  • Vous pouvez tester la répartition en altérant le loadfactor puis en contrôlant avec la console ou par consultation des logs sur quel Tomcat vous êtes redirigé.

3 mai 2012

Corriger par update SQL les ZX00.NUGEST déphasés

Si vous chargez des dossiers ZY et ZX par NOZ sur un environnement possédant déjà des dossiers, il y a de fortes chances que les NUDOSS ZY d'origine soient re-numérotés.Du coup, les NUGEST ZX ne seront plus en phase avec les NUDOSS des dossiers ZY concernés.

Pour faire un constat, exécutez :
select
ZX00.NUDOSS, ZX00.NUGEST, ZX00.SOCCLE, ZX00.MATRIC, ZY00.SOCCLE, ZY00.MATCLE
from ZX00 LEFT OUTER JOIN ZY00 on ZX00.NUGEST=ZY00.NUDOSS
where (
    (ZX00.SOCCLE<>ZY00.SOCCLE or ZY00.SOCCLE is null)
    or
    (ZX00.MATRIC<>ZY00.MATCLE or ZY00.MATCLE is null))

Ci joint un exemple d'update pour corriger ZX00.NUGEST.

Pour Oracle
update ZX00 set ZX00.NUGEST = (
  select coalesce( 
    (select ZY00.NUDOSS from ZY00 where ZX00.SOCCLE=ZY00.SOCCLE and ZX00.MATRIC=ZY00.MATCLE)
    ,0)
    from DUAL);

Pour DB2 remplacez DUAL par SYSIBM.SYSDUMMY1

A noter : Avec cet ordre SQL, les dossier ZX sans correspondance avec des matricules ZY auront un NUGEST nul.

 SQL> select nugest from zx00;
       181
 SQL> select soccle,matric,nugest from zx00;
 SOC MATRIC           NUGEST
 - - - - - - - - - - - - - - - - - -
 FRR FRP1047             181

 SQL> select nudoss,soccle,matcle from zy00 where nudoss = 181;
 no rows selected

 SQL> update ZX00 set ZX00.NUGEST = (select coalesce((select ZY00.NUDOSS from ZY00 where ZX00.SOCCLE=ZY00.SOCCLE and ZX00.MATRIC=ZY00.MATCLE),0) from DUAL);
 1 row updated.

 SQL> select soccle,matric,nugest from zx00;
 SOC MATRIC           NUGEST
 - - - - - - - - - - - - - - - - - -
 FRR FRP1047               0

2 mai 2012

grep et message "Fichier binaire ... concorde"

Vous utilisez la commande "grep" sur un fichier texte et celle ci répond "Fichier binaire ... concorde" au lieu de vous afficher les lignes concernées. Ceci est du au fait que la commande a estimé que le fichier était de type "binaire", donc non affichable.  

Forcez le type du fichier en utilisant une des options suivantes :

grep -a
grep --text
grep --binary-files=text.

25 avril 2012

Putty Connection Manager : pour tabuler entre les sessions telnet

Vous connaissez certainement Putty : cet utilitaire est un client telnet/ssh qui permet d'ouvrir des session en mode ligne de commande sur les machines de type Unix.

Un des reproches que l'on peut faire à putty est qu'il ne sait pas gérer l'affichage de multiples sessions dans des tabulations (comme le font maintenant les navigateurs). PuttyCM pallie à ce manque.


18 avril 2012

BLS-BBAD0015-ERREUR D'ACCES ... : TD12/9N/FJ/FETCH/000000000001002

Si vous rencontrez l'erreur suivante lors d'une NOY
 XXXXXBLS-BBAD0015-ERREUR D'ACCES (TABLE RELATIONNELLE) : TD12/9N/FJ/FETCH/000000000001002

C'est que vous avez sans doute des dossiers vérolés (leur TD12 ne reflète pas la réalité du contenu de la table).
Le programme BLS ne gère pas l'erreur correctement ...

Exécutez une ROL sur les dossiers concernés par l'export (pour corriger la TD12) puis relancez la NOY.

Pour information le message d'erreur Oracle associé :
01002, 00000, "fetch out of sequence"
*Cause: This error means that a fetch has been attempted from a cursor
         which is no longer valid.  Note that a PL/SQL cursor loop
         implicitly does fetches, and thus may also cause this error.
         There are a number of possible causes for this error, including:
         1) Fetching from a cursor after the last row has been retrieved
            and the ORA-1403 error returned.
         2) If the cursor has been opened with the FOR UPDATE clause,
            fetching after a COMMIT has been issued will return the error.
         3) Rebinding any placeholders in the SQL statement, then issuing
            a fetch before reexecuting the statement.
*Action: 1) Do not issue a fetch statement after the last row has been
             retrieved - there are no more rows to fetch.
          2) Do not issue a COMMIT inside a fetch loop for a cursor
             that has been opened FOR UPDATE.
          3) Reexecute the statement after rebinding, then attempt to
             fetch again.

5 avril 2012

java.security.AccessControlException: access denied

Information obtenue de la HotLine : depuis la version 1.6.0_22 de la JVM Sun/Oracle, un "fix" peut provoquer des erreurs sur le démarrage d'une applet dans des configurations réseaux particulière.

Exemple d'erreur :
[ERROR] applt - APPLT???? Error when testing web application's status <java.security.AccessControlException: access denied (java.net.SocketPermission 10.9.8.7:6543 connect,resolve)>
 java.security.AccessControlException: access denied (java.net.SocketPermission 10.9.8.7:6543 connect,resolve)

Voir la release note Oracle : (chapitre CVE-2010-3560).

Il est donc nécessaire, afin que les applets puissent fonctionner avec ces versions de Java , qu'il y ait bijection entre une adresse IP et un nom d'hôte. Dans la pratique, il faut que le "reverse lookup" sur une adresse IP redonne le même nom qu'un "direct lookup" sur le serveur DNS. Cela est résolu en ayant deux entrées dans le DNS de l'entreprise :
  • Première entrée classique "Direct lookup" : résolution d'un nom -> IP
 host    aaa.bbb.ccc.ddd
  • Deuxième entrée "Reverse lookup" : résolution IP -> nom
 aaa.bbb.ccc.ddd    host.auth.ddd.ccc.bbb.aaa.in-addr.arpa

Ces consignes ne sont plus nécessaire à partir de la JVM 1.6.0_25 qualifiée avec la release cliente 7.20.60.

26 mars 2012

Nettoyer le volume d'archivage de HRQuery

Depuis HRv5 le serveur HRQuery permet d'archiver des états dans le "Volume d'Archivage". Ces documents sont accessibles par l'utilisateur final via l'interface du client Web (les URL sont stockées dans la table ZO3Q des dossiers de travaux).
Pour nettoyer le volume d'archivage des fichiers "orphelins" (sans lien avec une occurrence de ZO3Q), l'éditeur met à disposition un outil : ${SIGACS}/query/bin/admin_query.sh. Notez que cet outil ne purge QUE le volume d'archivage, et pas les listings de $LIS.
 
syntaxe : admin_query.sh {audit/clean} [archive_volume]

  • l'option "audit" liste les fichiers orphelins
  • l'option "clean" détruit les fichiers orphelins 
  • archive_volume est le nom du volume d'archivage concerné (utile si plusieurs sont définis)
Exemple : nettoyer les listings des mises à jour batch archivés de plus de 7 jours

Avant HRv7 (sous Oracle)
SQL> delete from ZO00 where CDPHAS='NRB' and TISOUM > '0001-01-01' and TISOUM < SYSDATE - 7 ;
122 rows deleted.
SQL> commit;

A partir de HRv7
SQL> delete from ZO00 where CDPHAS='NRB' and FLGJOB='1' and TISOUM < SYSDATE - 7 ;
122 rows deleted.
SQL> commit;

Puis

cd $SIGACS/query/bin
sh admin_query.sh clean

L'outil indique :

Cleaning archive volumes referenced by query server QRYSRV ...
Archive volume: ARCHIV
Deleted files count: 792 (Cumulative size: 747 454 710 bytes)
 
List of deleted files:
/nrb/bbbm/10076/01_txt_00.txt - 99 092 338 bytes
/nrb/bbbm/10096/01_txt_00.txt - 177 459 328 bytes
/nrb/bbbm/10116/01_txt_00.txt - 257 323 092 bytes
/nrb/bbbm/10136/01_txt_00.txt - 99 092 338 bytes
/nrb/bbbv/10076/01_txt_00.txt - 1 510 bytes
...
OK

PS : ce script prends aussi les options :
  • {start/stop} pour lancer le démarrage ou l'arrêt du serveur de Query

20 mars 2012

Transférer des fichiers par "tar|gzip" à travers un lien "ssh"

Ci joint un exemple de commande pour transférer un grand nombre (ou un gros volume) de fichiers sans créer de ".tar.gz" intermédiaire (ici on transfère le $FILE de deux environnements nommés hraqua et situés sur deux machines distantes) :

tar cvf - /hraqua/file | gzip -c | ssh hraqua@1.2.3.4 "cd /;gunzip -c | tar -xvf -"

  • A exécuter sur la machine / environnement source
  • Derrière le "ssh" mettre le user et le nom (ou l'IP) de la machine / environnement cible
  • En fin de ligne entre quotes se trouve la commande exécutée sur la machine/ environnement cible
NB : le tar gnu des linux a une option de compression "-z" qui permet de se passer du " | gzip -c"

Exemple :
hraqua@old_srvhr:/hraqua> tar cvf - /hraqua/dir |gzip -c |ssh hraqua@new_srvhr "cd /hraqua; gunzip -c |tar -xvf -"
 a /hraqua/dir
 a /hraqua/dir/dir1
 a /hraqua/dir/dir1/dummy1.txt 1 blocks
 a /hraqua/dir/dir2
 a /hraqua/dir/dir2/dummy2.txt 1 blocks
 The authenticity of host 'new_srvhr (1.2.3.4)' can't be established.
 RSA key fingerprint is f1:c1:04:73:64:f9:a5:19:16:8b:06:21:9f:86:06:65.
 Are you sure you want to continue connecting (yes/no)? yes
 Warning: Permanently added '1.2.3.4' (RSA) to the list of known hosts.
 hraqua@new_srvhr's password:
 Warning: untrusted X11 forwarding setup failed: xauth key data not generated
 Warning: No xauth data; using fake authentication data for X11 forwarding.
 x /hraqua/dir
 x /hraqua/dir/dir1
 x /hraqua/dir/dir1/dummy1.txt, 39 bytes, 1 tape blocks
 x /hraqua/dir/dir2
 x /hraqua/dir/dir2/dummy2.txt, 37 bytes, 1 tape blocks

PS : Pour exécuter cette commande en batch (avec un "at now" ou un crontab) vous aurez besoin de paramétrer le ssh pour qu'il réalise une connexion sans authentification (fichier clef + .ssh/authorised_keys).

19 mars 2012

16 mars 2012

*ST01BU2-BBAC0052-Le noeud AT221000 n'est pas referencé dans son arbre, il est supprimé

Sous HRv7, lors de l'import d'un nœud, le programme BU2 réalise un contrôle de rattachement :

Ce qui signifie que l'on ne peut livrer un nouveau noeud QUE par livraison de l'arbre fonctionnel complet.

En effet le message BBAC0052 se déclenche si le noeud en question n'est pas DEJA référencé comme rattaché à l'arbre fonctionnel. Il est alors supprimé.


 296000*CURSEUR SUR LES NOEUDS ORPHELINS                                 7SQ070
 296100*--------------------------------                                 7SQ080
 296200*                                                                 7SQ090
 000001                  EXEC SQL DECLARE CWT20 CURSOR FOR SELECT        DCWT20
 000002                           CDTREE,                                DCWT20
 000003                           CDNODE,                                DCWT20
 000004                           NUVERS,                                DCWT20
 000005                           TIMODI,                                DCWT20
 000006                           TEVERR,                                DCWT20
  ...
 000021                       FROM %1.WT20                               DCWT20
 296400               WHERE  CDTREE||CDNODE NOT IN                       7SQ150
 296500             ( SELECT B.CDENRF                                    7SQ160
 296700               FROM   %1.RC50 B                                   7SQ170
 296800               WHERE  B.TYENRF = "NN"                             7SQ180
 296900               AND    B.TYENTI = "AN"                             7SQ190
 297000               AND    B.NATREF = "I"  )                           7SQ200
 000001                      ORDER BY                                    ORWT20
 000002                           CDTREE                                 ORWT20
 000003                          , CDNODE                                ORWT20
 000004                                                       END-EXEC.  ORWT20
et
 544500*N204X.    NOTE *TRAITEMENT DU NOEUD                *.            P005
 544600 F204X.                                                           P005
 544700*Display BBAC0052 noeud orphelin.                                 P010
 544800     MOVE        "BBAC0052" TO S-CDDISP.                          P020
 544900     MOVE        H-WT20-CDTREE TO S-ZOSUB1.                       P030
 545000     MOVE        H-WT20-CDNODE TO S-ZOSUB2.                       P040
 545100     PERFORM     F97 THRU F97-FN.                                 P050
 545200     MOVE        "04" TO W-WP00-CDRET.                            P060
 545300*Suppression du noeud.                                            P070
 545400     MOVE        H-WT20-CDTREE TO W-WP01-CDTREE.                  P080
 545500     MOVE        H-WT20-CDNODE TO W-WP01-CDNODE.                  P090
 545600     MOVE        "NN" TO W-WP01-TYENTI.                           P100
 545700     MOVE        W-WP01-CDENTI TO XF10-CDENTI.                    P110
 545800     MOVE        "NN" TO XF10-TYENTI.                             P120
 545900     MOVE        "WT20" TO XF10-IDTABL.                           P130
 546000     PERFORM     F9D THRU F9D-FN.                                 P140
 546100     PERFORM     F9GGA THRU F9GGA-FN.                             P150
 546200     PERFORM     F9GCH THRU F9GCH-FN.                             P160
 546300*Effacement table de chgt obj NN.                                 P170
 546400     PERFORM     F8MDE THRU F8MDE-FN.                             P180

15 mars 2012

Editeur de fichier MF Cobol : dfed

MicroFocus met a disposition un utilitaire permettant sous Unix d'éditer les fichiers Record Sequential : dfed.

Avant de le déclencher, positionnez la "taille de la fenêtre" :
export LINES=25
export COLUMNS=80

Puis ouvrez le fichier à éditer
dfed monfichier

NB : L'interface peut devoir demander le type du fichier et la longueur des enregistrements.
Pour les archives de paie YS, le type de fichier et "Sequential" (valider en tapant "espace") et la longueur des enregistrements est de 3000 (validez en tapant <CR>).



Ci dessous des correspondances de touches clavier utiles :
  • F1 ... F9 F10 F11 F12 accessibles par les touches /1 ... /9 /0 /- /=
  • menu Alt (open, save) = /a
  • menu Ctrl (search) = /c

Déplacer vous avec les flèches.

Faites Esc deux fois pour sortir sans enregistrer


Syntaxe :
  dfed \[filename] \[{-A|-E}] \[{-B|-b}]
  • -A : ASCII (par défaut) / -E : EBCDIC
  • -B : backup du fichier si édition (par défaut) / -b : pas de backup


A voir :
supportline.microfocus.com editeur
supportline.microfocus.com keys

13 mars 2012

Formater sous DB2 un nombre avec signe et zero non significatifs

Ci joint un exemple d'ordre SQL pour formater sous DB2 un nombre avec signe et zéros non significatifs (par exemple pour les bordereaux NRB)
  •  "CASE" pour l'affichage systématique du signe
  •  "CHAR" pour les zeros non significatifs et le séparateur des décimales
  •  "DECIMAL" pour spécifier le nombre de chiffres dont le nombre de décimales

select CASE WHEN a.BASCT > 0 THEN '+' ELSE '-' END|| CHAR(DECIMAL(a.BASCT,15,2),',') from  HR.ZYVL a, HR.ZY00 b, HR.ZYES c
where a.nudoss=b.nudoss and a.nudoss=c.nudoss
and a.dteffe between c.datent and c.datsor and a.datfin not between c.datent and c.datsor
and b.matcle='A123456'
------------------
+0000000123400,00

12 mars 2012

Objets de conception de l'arborescence HRaSpace v7

Ci joint une (superbe) illustration faite par un collègue, dans l'objectif d'éclairer sur les liens entre objets de conception de l'arborescence ...
et permettant de mettre en correspondance un libellé aperçu en naviguant avec celui d'un libellé d'objet sous HR Studio.

Merci à lui.


Préparer un import d'objets RB4 avec HRD Studio


C'est par hasard que j'ai trouvé sous HRv7.17.5 cette fonctionnalité : un clic droit sur l’item « Groupe de Traitements » ou « Traitements » donne accès à « Préparer un import ».



Il faut alors sélectionner un fichier (de format PSBBC101 ou PSBRG0OB).

Tous les objets sont cochés d’office (ils seront chargés en l’état). Seuls les objets traitements permettent un choix particulier. La colonne « Existe » indique que le traitement à charger existe déjà. Cocher le traitement signifie que l’on souhaite l’importer sans personnalisation.

9 mars 2012

Obtenir les sources Cobol incluant le code des Clause Copy (fichier .lst)

Sur Unix, lorsque l'on compile les processus, il n'y a plus nécessairement de création des fichiers .lst (les seuls dans lesquels on ait le contenu des clauses COPY).

Pour les avoir, il faut ajouter l'option -P à la commande de compilation
  • dans le fichier "config" de ${SIGACS}/adm/cfg
Ajouter -P en fin de la ligne COBFLAGS

# Directives for Cobol compiler
COBFLAGS=-C ASSIGN=EXTERNAL -C SEQUENTIAL=LINE ... -P

  • ou dans le fichier "Makefile" $SIGACS/adm/cfg (pour chacun des types d’exécutable à générer)

@$(COB_VAR) cd `dirname $(*)`; $(COB) -vzP $(COBFLAGS) $(*).cbl

Les chaines de génération placeront désormais les ".lst" dans $LIS.
Attention : ces fichiers sont volumineux. Pensez à les purger.