WebDev 16 vs J2EE : connexion aux sources de données par programmation

On a vu précédemment que la gestion des sources de données se devait d’être faite manuellement dans un contexte d’entreprise. En effet l’utilisation de telle ou telle base de donnée doit être configurée dans l’environnement, sur site, et non pas dans l’AGL. Cette article résume la marche à suive pour rendre une application Webdev 16 réellement professionnelle.

En premier lieu, puisque l’AGL ne le propose pas, on créera un mini-socle technique. Ce sera un projet webdev de type “composant”. Il pourra contenir des pages, des bibliothèques de procédures, des classes etc.

Le socle technique devra tout d’abord rechercher le fichier de configuration qui permettra de paramétrer l’application. On créera donc dans le projet socle, une bibliothèque de procédures que l’on nommera Initialisations. Dans cette bibliothèques on créera une procédure que l’on appellera ChercheFichierInit dont le rôle sera de trouver le fichier de configuration afin que le reste de l’initialisation puisse se faire.


PROCEDURE ChercheFichierInit(LOCAL sNomFichierConfig est une chane = "config.ini", LOCAL sNomRepConfig est une chane = "config")

// recherche du fichier de configuration

// recherche dans le rpertoire de config du rpertoire donnes de l’application
gsRepertoireConf = fRepDonnes()
//Info(“Rep de donne”, gsRepertoireConf)
gsFichierConf = ComplteRep(ComplteRep(gsRepertoireConf) + sNomRepConfig) + sNomFichierConfig
//Info(“Recherche fichier conf “, gsFichierConf)
SI fFichierExiste(gsFichierConf) = Faux ALORS

// on monte 2 fois car le composant est install dans un sous rpertoire le rpertoire web de l’application utilisatrice
gsRepertoireConf = fRepParent(fRepParent(fRepWeb()))
// Info(“Rep du site”, gsRepertoireConf)
// fichier de config spcifique l’environnement (ex: production)
gsFichierConf = ComplteRep(ComplteRep(gsRepertoireConf) + sNomRepConfig) + sNomFichierConfig
// Info(“Recherche fichier conf “, gsFichierConf)
SI fFichierExiste(gsFichierConf) = Faux ALORS
// fichier de config par dfaut (ex: en developpement)
gsFichierConf = ComplteRep(gsRepertoireConf) + sNomFichierConfig
// Info(“Recherche fichier conf “, gsFichierConf)
FIN

FIN

RENVOYER gsFichierConf

Une fois que le fichier de configuration a été déterminé on peut s’occuper de connecter les tables (appelées Fichier dans la terminologie WLangage) de l’analyse à la bonne base de données.


PROCEDURE InitConfigurationBase(sListeFichierAnalyse est une chane)
logInfo("Chargement de la configuration des connexions aux bases de donnes...")
SI fFichierExiste(gsFichierConf) ALORS

logInfo(“Lecture des paramtre d’initialisation de la base de l’application”)
gsUtilisateur_app = INILit(gsCFG_SECTION_BD_APPLI,gsCFG_SECTION_BD_APPLI_KEY_USER,””,gsFichierConf)
gsMotdepasse_app = INILit(gsCFG_SECTION_BD_APPLI,gsCFG_SECTION_BD_APPLI_KEY_MDP,””,gsFichierConf)
gsSource_app = INILit(gsCFG_SECTION_BD_APPLI,gsCFG_SECTION_BD_APPLI_KEY_SOURCE,””,gsFichierConf)
gsServeur_app= INILit(gsCFG_SECTION_BD_APPLI,gsCFG_SECTION_BD_APPLI_KEY_SERVEUR,””,gsFichierConf)
logInfo(“source serveur : ” + gsServeur_app + CRLF + “source base: ” + gsSource_app + CRLF + “utilisateur: ” + gsUtilisateur_app + CRLF + “mot de passe : ******”)

// changer les connexions des FICHIER de la base de l’application
// Description de la connexion

gConnexionManuelleAppli..Utilisateur = gsUtilisateur_app
gConnexionManuelleAppli..MotDePasse = gsMotdepasse_app
gConnexionManuelleAppli..Serveur = gsServeur_app
gConnexionManuelleAppli..BaseDeDonnes = gsSource_app
gConnexionManuelleAppli..Provider = hAccsHFClientServeur
gConnexionManuelleAppli..Accs = hOLectureEcriture

gbCOnnexionManuelleAppliOuverte = False
logInfo(“Ouverture de la connexion la base de l’application…”)
SI HOuvreConnexion(gConnexionManuelleAppli) ALORS
logInfo(“OK Connexion ouverte ! “)
gbCOnnexionManuelleAppliOuverte = True

logInfo(“Modification des connexion des tables propres l’application”)
ListeFichierAnalyse = sListeFichierAnalyse
ChangeConnexionApplication(ListeFichierAnalyse)

logInfo(“Fin du traitements des tables applicatives”)
SINON
logFatal(“Erreur lors de l’ouverture de la connexion à la base applicative” + CRLF + HErreurInfo())
Erreur(“Erreur lors de l’ouverture de la connexion à la base applicative”,HErreurInfo())
FIN
SINON
logFatal(“Le fichier de configuration ” + gsFichierConf + ” est introuvable”)
Erreur(“Impossible d’initialiser la configuration de base de donnes, Le fichier de configuration ” + gsFichierConf + ” est introuvable”)
FIN

 

La liste des fichiers de l’analyse de l’application utilisatrice de notre composant ne peut être déterminé par le composant lui-même. En effet la fonction HListeFichier() appelée depuis le composant, retourne les fichiers de l’analyse du composant. C’est donc à l’application d’appeler cette fonction et de passer la liste des fichiers dont il faut changer la connexion. Voici la procédure qui change la connexion:


PROCEDURE PRIVE ChangeConnexionApplication(ListeFichierAnalyse)

POUR TOUT CHAINE fichier_analyse DE ListeFichierAnalyse SEPAREE PAR RC

HChangeConnexion (fichier_analyse,gConnexionManuelleAppli)
SI ErreurDtecte ALORS
Erreur(“Erreur lors de l’attachement de la table : ” + fichier_analyse,HErreurInfo())
SINON
logInfo(fichier_analyse + ” attache ” + gsSource_app + ” sur ” + gsServeur_app)
FIN

FIN

 

Dans le code de l’initialisation serveur du projet de l’application cliente il suffit de mettre ces lignes:


Intialisations.ChercheFichierInit()
Initialisations.InitConfigurationBase(HListeFichier())

NB: Le lecture corrigera de lui même les références à des variables nom déclarées telles que les constantes des clés utilisées dans le fichier d’initialisation.

NB: les fonctions LogInfo(), LogFatal() utilisées dans le code sont des fonctions personnelles afin de palier le manque de niveau de log dans WebDev, et feront éventuellement l’objet d’un billet ultérieur.

Comparaison WebDev 16 et J2EE : session web

En J2EE le mécanisme des Servlets est entièrement documenté. Une servlet est instanciée pour servir les requêtes des clients. Chaque execution (traitement) peut obtenir la session à laquelle il appartient en invoquant peu ou prou un getSession sur la requête courante. Cet objet de session peut servir à accueillir des objets que l’on souhaite rattacher à la session courante comme, par exemple, des informations à passer de page en page.

Le modèle de programmation de WebDev est de son côté peu documenté mais de façon empirique on arrive à la conclusion suivante: dans les pages dynamiques webdev, les objets globaux au projet sont en fait des objets de sessions.. Du moins en développement car une particularité troublante est que la gestion des sessions est différente dans l’AGL de sa gestion dans le vrai serveur WebDev. Cela est regrettable car un code qui fonctionne sur le poste du développeur risque de ne pas fonctionner en intégration… D’autant plus que la gestion des sessions peut devenir critique mais utilise-t-on WebDev pour des applications critiques ?

Webdev 16 vs J2EE : log applicative

Les applications écrites en Java adressent des problématiques techniques complexes notement en terme d’architecture et les développeurs (terme noble) de monde Java se sont attachés à répondre au besoin d’outillage suscité par ces développements. Ce besoin n’est pas spécifique à Java mais il est présent dès lors que les applications le nécessitent.

Parmi les outils, l’un des plus triviaux est un mécanisme de log. Ainsi avant le JDK1.4, les librairies tierces telles que Log4j ont permi aux applications de disposer d’une fonction de log modulaire par composants (domaine métier, domaine technique etc) et par niveau de sévérité (log d’information, de debug ou d’erreur etc). Cette solution , pour ne citer qu’elle, est bien sûr libre (et gratuite).

Que nous propose Webdev de son côté ? Il existe une fonction de trace (Trace) qui affiche des log dans une popup… Surtout pratique en développement et s’apparente plus à un vulgaire System.out.println qui est le niveau zéro de la log puisque non paramétrable et ni débrayable tel quel en production.

Une recherche rapide sur google dans le monde Java donne tout de suite une réponse aux problématiques de log en Java alors que la même recherche pour WebDev n’amène aucune réponse du même niveau. Comme d’habitude (cf la gestion des sources de donnéées) il faudra se créer des fonctions qui géreront le niveau de log et l’écriture de la trace dans un fichier. la fonction Trace sait écrire dans un fichier mais il nous faudra ajouter l’horodatage nous même…

Comparaison WebDev et J2EE : langage et gestion des sources de données

Le monde J2EE est souvent jugé complexe mais cette complexité apparente n’est que la réponse nécessaire aux problématiques réelles des SI. De son côté WebDev propose une solution aguicheuse pour le développement mais tient-il la comparaison ?

Dans un billet précédents je déclarais que la cible de WebDev n’était pas la même que J2EE. WebDev semble s’adresser à une population d’informatiien et surtout de non informaticien pour développer des applications de gestion CRAD (portemanteau de CDRUD et de RAD). Après quelques semaines passé à manipuler WebDev voici mes conclusions.

Du point de vue du développeur (rôle développeur en J2EE), le langage WLangage n’est pas Objet. On est trop souvent amené à appeler des fonctions qui ne sont pas des méthodes d’objet ni de classe. Ce sont bel et bien des fonctions. Le paradigme de programmation du WLangage (langage propriétaire utilisé par WebDev) est donc bancal. Se voulant objet, puisque l’on peu faire des objets, il n’impose malheusement pas ce modèle. Si le lecteur doute de la pertinence de l’objet en matière de génie logiciel, je ne peux que lui conseiller de mettre à jour ses connaissances.

Certaines fonctions sont elles-mêmes bancales dans leur signature. Ainsi le fonction qui test si une chaine commence par une autre est bien nommée ChaîneCommencePar mais ne retourne pas un booléen mais un entier…. Donc le développeur passe d’un niveau d’abstration fonctionnel avec des fonction dont le nom est significatif à un autre, celui d’un test en langage C….

Une fois l’application développé vient le temps du déploiement. Comme on veut comparer WebDev et J2EE, nous sommes dans le contexte d’un SI d’entreprise voire d’un éditeur, avec des environnements de test, de preé-production et de production. Là où J2EE permet de découpler le code de l’application des paramètres de l’environnement comme les sources de données qui sont du ressort de l’administrateur (rôle déployeur en J2EE). Ainsi le mème livrable pourra être déployé en test ou en production, le code étant totalement agnostique de l’environnement, Quelle solution propose WebDev ?

La notion de connexion nommée est interne à l’IDE qui confond allègrement nom de connexion et nom de variable dans le but de simplification à outrance. Ainsi une connexion définie dans l’IDE est référencé par son nom en tant que variable et nom pas en temps que chaine. Les connexions semblent devoir être définies lors du développement. WebDev inscite donc à repasser par l’AGL et déclarer les connexions spécifiques à l’environnement cibles puis recompiler et redéployer l’application. Une fois dployée l’application est alors scotchée à sa source de donnée…. WebDev ne fait donc pas de découplage entre application et source de données!

Néanmoins on peut par programmation construire une connexion et l’affecter aux tables (appelées Fichiers) du programme. Cette méthode est celle préconisée par le support pour rendre l’application multi-cible. Finalement c’est un développeur si il a un minimum de compétence en génie logiciel, de prévoir ce qui est du ressort de la technique et donc contraire à la cible première de WebDev. Par ailleur le support propose une solution hasardeuse de détecter l’environnement en fonction de l’IP du serveur… sous-entendant que le code doit tester si il est en test ou en prod. WebDev est donc a proscrire pour les éditeurs qui devraient connaitre l’IP de tous les serveurs de ses clients!

Une première solution pourtant existe et aurait dû être proposée par le support. Lors du déploiement l’AGL propose d’inclure des fichiers supplémentaires. Il suffit d’ajouter un fichier de type INI qui contient la définition de la connexion pour l’instance en train d’être déployée. Par programmation, l’application lors de son initialisation va lire ce fichier et créer la connexion puis surcharger la connexion de l’analyse. Cependant, cette méthode oblige toute modification des sources de données de se faire soit en redéployant soit en allant modifier le fichier INI sur le serveur. On peut aller plus loin en incluant un fichier (Table) d’initialisation qui contiendrait les valeurs de connexions aux tables métiers et un module d’administration pour modifier la table de paramétrage… Dommage que WebDev ne propose pas cela dans son modèle, ce qui lui aurait permis de soutenir la comparaison avec J2EE.

Derrière un marketing singulier dans le monde des éditeurs, WebDev est un AGL qui ressemble plus à une boîte à outils pour assembler rapidement des applications focalisées sur l’apparence. Certes, on développe vite des IHM mais le modèle applicatif n’est pas celui attendu par des SI d’entrepise et encore moins celui de professionnelles de l’informatique comme les éditeurs. Définitivement, a moins de s’adjoindre les services d’un spécialiste en architecture ou génie logiciel, l’utilisation de WebDev n’est pas adaptée à un SI d’entreprise avec des contraintes autres que celles du médecin qui veut développer un IHM sur son fichier de patients.