JIRA outil de gestion de la demande

Lors d’une vie professionelle précédente j’avais personnalisé Trac afin d’en faire un outil de gestion de la demande pour une population d’utilisateurs non informaticiens. En plus de le rendre plus agréable en l’épurant il a fallut répondre aux besoins en utilisant des extensions bien choisies et voire en créant de nouvelles en python. Lire la suite sur mon blog caché:

//awsyja6cjl2qmy7m.onion/blog/?p=1217

Si vous ne pouvez pas utiliser Tor ou que votre anonymat n’a pas d’importance, vous pouvez utiliser un proxy Tor en cliquant sur le lien suivant mais dans ce cas votre identité (adresse IP) n’est plus secrète:

//awsyja6cjl2qmy7m.tor2web.org/blog/?p=1217

Jointure sur des bases de données différentes avec WebDev 16: encore une déception !

Dans la cas d’une application multibase, on peut être amené à aggréger des données en provenance de bases différentes. La sélection peut s’opérer en 2 étapes: rapatrier les données de chaques bases puis les aggréger en mémoires. Si l’aggrégation consiste à faire une jointure on préfèrerait que cela se fasse dans la “base”.

En J2EE, le développeur ferait appel à des EJB puis avec un EQL ferait la sélection interbase. Il s’appuirait ainsi sur des mécanismes de chargement paresseux afin limiter l’occupation mémoire en évitant de charger la base en mémoire! Comment webdev adresse-t-il se problème ?

Prenons un cas concrêt de 2 requêtes paramêtrées, chacune mettant en jeu des tables sur des bases de données différentes. Le test SQL de chacune de ces 2 requêtes dans l’IDE se fait sans encombre puisque aucune ne fait pas intervenir l’autre. Créons une 3e requêtes qui fait une produit cartésien sur les 2 premières. Cette 3e requête est elle-même paramêtrée afin d’assurer la jointure. Et bien le test SQL de la 3e requête dans l’IDE se passe parfaitement !

Cela donne l’illusion au développeur de pouvoir utiliser la 3e requêtes comme source pour un tableau. Que nenni ! On a droit à une belle explosion, webdev se plaigant que le fichier (table) correspondant à la 3e requête n’existe pas. Dommage que l’IDE laisse au développeur espérer une opération magique qui n’existe pas !

La solution consiste à remplir le tableau manuellement avec le résultat de l’appel à des requêtes SQL manuelles. Il faut déclarer une source de données pour chacune des requêtes et executer le SQL associé sur chacune d’elle (HExecuteEquêteSQL). Ensuite il faut faire de même avec une nouvelle source de données et un requête SQL faisant un produit cartésien sur les 2 premières sources de données.

Finalement on arrive a nos fin mais au prix d’un effort de programmation non négligeable et une rupture dans les concepts: le médecin doit abandonner le confort de la manipulation d’objet dans l’IDE (requêtes) pour écrire du SQL dans une chaine de caratères non validée par l’IDE. Quel dommage !

Webdev 16 de déception en déception

Voulant partager du code entre plusieurs projet, l’idée naturelle est de mettre ce code dans des bibliothèques dont va dépendre les projets. En java cette dépendance peut être définie par Maven qui gère le cycle de build. Avec Windev on est loin d’une solution industrielle….

Tout d’abord le simple partage de code via le centre de réutilisabilité revient ni plus ni moins à partager les sources sur un disque réseau sans versionnage aucun des pseudo-bibliothèque obtenue. Chaque projet doit alors faire un copier-coller des sources. C’est vraiment pauvre !

Il existe néanmoins un notion plus intéressante en WebDev qui gère le versionnage: le composant. Avec des composants, les projets sont mis à jour automatiquement quand une nouvelle version est disponible pour peu que le composant indique sa compatibilité. Cela se rapproche de la gestion des dépendances de Maven et de son système de dépôt, grâce à la mise en ligne du composant dans le Gestionnaire De Sources (GDS) de WebDev (son SCM propriétaire).

Malheueusement la notion de composant impose des limites. Un composant doit être vu comme un boîte offrant un service de bout en bout à l’application utilisatrice. Il peut fournir des procédures, des pages etc mais le composant ne peut accéder aux objets de l’application utilisatrice. Le terme objet est volontairement flou car c’est là que les ennuis commencent. Le WLangage ne pousse pas à faire de l’objet et toutes les fonctions du WLangage sont globales (ex: HChangeConnexion). Malheureusement ce paragdigme est vraiment insuffisant pour expliquer clairement la magie qui s’opère à l’execution. Ainsi selon que la fonction WLangage est appelée dans le composant ou pas, son résultat est différent. Par exemple un composant ne peut être utilisé pour effectuer un changement des connexions de l’application utilisatrice, car HChangeConnexion echoue silencieusement (comble de l’horreur…là où Java léverait une exception) si appelée depuis le composant.

Du coup il est impossible d’initialiser les connexions de l’application comme indiqué dans ce billet et il faudra mettre le code dans l’application même. Dommage, cela calme les ardeurs du concepteur qui cherche à faire du code réutilisable et classe définitivement WebDev hors-jeu pour le développement professionnel.

Squelette de projet python pour Maemo5

Le projet Pyjama est aujourd’hui dans un état presque utilisable. Pyjama est un outil écrit en python pour générer un squelette de projet python pour Maemo5. Il s’agit d’un “bootstrapper” à la manière du plugin archetype de maven.

Le principal objectif de Pyjama est atteint puisque la version disponible sous forme de source permet de générer un embryon d’application exécutable. Les sources générés comprennent des outils afin de gérer le messages d’informations, la remontée de bug via googlecode et les tâches asynchrones.

Le prochaine étape est la création d’une interface de saisie des paramètres du projet ainsi que d’une IHM pour Maemo5. Ainsi on pourra créer le squelette sur PC ou bien directement sur le terminal.

Ouverture de ligne Free Mobile : Erreur de clé rib

Common rock pigeon (Columba livia)
Image via Wikipedia

Le pigeon n’aime pas le Javascript c’est de notoriété publique. En effet tout site web se basant sur du javascript s’expose à ne pas fonctionner car il s’appuie sur un composant client non maîtrisé. Je dois être un peu vieux jeu même si je n’ai pas encore 36 ans… Enfin pour quelques semaines me séparent encore de l’horizon des 36 ans: l’âge limite des informaticiens selon cadreonline….

Une fois de plus, mon aversion du JavaScript se justifie. En essayant de libérer mon pigeon je suis tombé sur une erreur de clé RIB lors de la toute dernière étape:

Erreur clé rib

Cette erreur est vraiment incongrue puisque j’ai laissé le RIB qui est déjà utilisé pour mon compte Freebox. Je compare le RIB avec celui que me donne ma banque: c’est bien le bon. Je modifie le RIB en ressaisissant le même mais rien n’y fait. Le pigeon se sent alors floué car son collègue dans le même pigeonnier vient lui de réussir à se libérer.

C’est alors que mon désamour du JavaScript se réveille. Ce contrôle de surface (vérification de la clé de Luhn) doit être fait côté client. Mon navigateur doit avoir un problème… Je prend alors mon N900 et via la connexion internet de mon opérateur actuel, que je vais quitter pour Free, je réussi enfin à m’inscrire ! hourra le N900 à sauvé le soldat piegon et ironie de l’histoire, mon opérateur m’a permis de le quitter !

Free Mobile, j'arrive

Prototype d’application python pour Maemo 5

Often called "albino", this amelanis...
Image via Wikipedia

La mise en place d’un nouveau projet python pour Maemo5 est consitituée de plusieurs étapes:

  1. création du référentiel de sources: ex: subversion chez google code
  2. création du projet sous ESBox
  3. ajout des fichiers pour setuptool
  4. ajout de l’arborescence initiale du projet (architecture)
  5. import des sources dans le référentiel
  6. enregistrement du projet sur PYPI
  7. création du site du projet: ex: blog chez blogspot
  8. création du groupe de discussion: ex: google group

La création des fichiers initiaux est une tâche rébarbative mais nécessaire pour d’une part industrialiser la production (build, déploiement et d’autre part assurer la qualité du code (architecture en couche, réutilisation…). D’un projet à l’autre ces étapes ne diffèrent que par les caractéristiques du projet:

  • Nom du projet
  • Nom de l’auteur
  • Licence du projet
  • Date de création
  • Nom de certaines classes etc.

En somme la phase d’initialisation du projet doit pouvoir s’automatiser. Un peu à la manière des archétypes maven, il serait intéressant de pouvoir générer à l’aide d’une commande (et d’un assistant) le squelette d’un nouveau projet qui compile et s’exécute !

Le projet Pyjama est sans doute le dernier que je crée par copier/coller d’un projet précédent. Pyjama doit en effet permettre la création de projet via une simple commande.

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 ?

Google Data API 2.0.15 et Maemo5 en python

.AVI en el N900Maegen, une application de généalogie pour Maemo5/N900 utilise le service googlecode de google pour la soumission de bug. Pour cela Maegen se base sur la librairie gdata fournie par google. Le code de rapport de bug a été écrit il y a plus d’un an et suppose que la version de gdata soit la 2.0.9 alors que la version courante est la 2.0.15

Ayant testé Maegen sur des machines différentes sur lesquelles des versions récentes de gdata étaient installées, je pensais qu’une dépendance de type au moins la 2.0.9 était une solution valable. Cela donne dans le fichier setup.py

setup(... install_requires=["gdata>=2.0.9"], ...)

Tout semblait marcher correctement puisque à la fois sur le terminal et les machines de développement (Virtual Appliance Maemo SDK), Maegen s’executait correctement, jusqu’à ce que je décide de passer sur une machine vierge (Virtual Appliance Maemo SDK) où jamais gdata n’avait été installé. Et là ce fut le drame, Maegen ne fonctionnait plus. La faute à gdata introuvable.

Une première solution est provoquer l’installation des dépendances. Pour cela se mettre sous l’environnement de compilation croisée

scratchbox

puis se placer dans le répertoire du projet

cd workspace/maegen

et enfin lancer une installation

python2.5 setup.py install

Lorsque les lignes cabalistiques ont fini de défiler, on remarque que gdata 2.0.15 a été installé. Le lancement de Maegen echoue cette fois sur l’absence du paquet json !

D’où vient le problème ? En regardant la version de gdata sur les machine où Maegen fonctionne, je remarque alors une différence: c’est la 2.0.14. Je désinstalle donc gdata 2.0.15 et installe la 2.0.14 à partir des sources dans scratchbox et là le miracle se produit: Maegen reprend vie !

En comparant le module gdata.gauth.py entre la 2.0.14 et la 2.0.15, on constate que des tentatives d’imports de json sont effectués à partir de la ligne 64 et finalement suppose que python 2.6 est utlisé en essyant un ultime import json, ce qui malheureusement échouera lamentablement sur le N900 qui ne dispose que de python 2.5 !

Voilà, le mystère est résolu, à moins de rajouter une dépendance vers json, je doit me résoudre à ne pas utliser la dernière version de gdata. Pour cela la directive de dépendance dans le fichier setup.py devient:

install_requires=["gdata>=2.0.9, <=2.0.14"]

En conclusion, les dépendances externes doivent être utiliser avec parcimonie et on doit éviter les dépendances ouvertes en leur préférant une dépendance exacte si possible. En effet moins il y a de dépendance, plus l’application est autonome et légère avec des risque de conflit de version en moins. De plus les dépendances ouvertes ouvrent la porte à une régression apportée par une nouvelle version.

WebDev pour un développement rapide mais pour qui ?

L’outil WebDev édité par PCSOFT est un atelier de développement pour la création de site web dynamique. S’inspirant du principe RAD il permet de faire des pages web de façon visuelle et de partir de la base de données pour créer automatiquement ou presque les pages en accès CRUD. Le langage propriétaire, WLangage, est en français et facile d’accès car d’abord procédural et objet optionnellement.

La prise en main de l’outil est vraiment aisée. La facilité et la rapidité des créations d’un site en CRUD avec le RAD est bluffante. Toutefois toute belle fille ne peut donner plus qu’elle n’a. Si Webdev permet de baisser drastiquement la barrière de compétence pour développer, quelles sont les limites informatiques dans l’architecture du SI quand on mise ses développements sur Webdev ou tout outil équivalent ?

En premier lieu le choix de Webdev est judicieux pour permettre une population ancienne technologie d’accéder, sans montée en compétence, à des technologies nouvelles. La terminologie utilisée par Webdev sent bon l’ancien temps avec la notion de fichier ou de rubrique pour les tables et les colonnes. Le langage possède même une instruction GOTO ! En même temps l’outil propose sur simple clic d’accéder à des techniques dans l’air du temps: Ajax, Webservice… Cette dualité ouvre la porte au plus grand nombre aux dernières innovations sexy de l’informatique et cela dès la lecture d’une publicité commerciale ou du manuel utilisateur de Webdev…

Malheureusement la forme n’est pas tout et les organisations ont des besoins différents. Webdev est-il le graal ? La réponse est évidement non. Un raisonnement par l’absurde suffit à nous convaincre. L’échec des projets de développement informatique ne se conjurent pas par l’utilisation des AGL et le succès des projets utilisant des technologies non RAD dans les secteurs concurrentiels (banque, e-commerce…) montre la pertinence de ces choix technologiques.

Les secteurs où la technique relève d’un critère concurrentiel ne peuvent se permettre d’attendre la prochaine version de l’AGL pour offrir la dernière technologie à la mode à ces clients. L’accélération du monde fait que le “time to market” est parfois vital. Une bonne idée ce n’est pas suffisant, il faut la mettre en œuvre avant les autres.

Le modèle des appliccations WebDev promeut un développement CRAD (mélange de RAD et de CRUD). En effet la rapidité de développement pousse à la paresse conceptuelle. La conception consiste à modéliser (et faire apparaître) des objets artificiels qui ne sont ni issus du métier ni même technologiques (je n’utilise pas le terme technique pour bien préciser ma pensée). Cette tâche de conception nécessite de vrai compétence informatique que le public visé par Webdev n’a pas. L’approche RAD se focalise sur l’analyse qui n’est n’y plus ni moins qu’un modèle meurisien orienté données. La tentation est alors grande de se laisser enfermer dans l’outil et de ne pas passer par la case conception logicielle. La préjudice ne se voit pas si la logique métier est peu présente dans l’application;.. Mais on fait alors l’impasse sur l’évolutivité, la scalabilité et donc la pérénité de l’application.

Les organisations ayant une SI de grande ampleur où l’interconnexion des systèmes occupe une place importante ne peut se contenter du modèle applicatif proposer par WedDev. En effet la notion de réutilisation semble re dans WebDev qu’un partage de bibliothèques qui nécessiteront un “redéploiement” (livraison) de toutes les applications qui les utilisent. Pourtant des technologies datant de la fin des années 90 adressent ces problématiques comme les EJB ou plus anciennement les ORB Corba.

Si on replace dans l’utilisation de l’outil, la présentation du code est bien pensée en regroupant sur un écran les codes de différentes natures qui concourent au fonctionnement d’une page ou d’un bouton. Dommage que des bugs mineurs tels que le crash de l’IDE quand l’assistant de saisie présente les paramètres de la procédure Milieu() utilisée dans le premier exemple de l’auto-formation (Ce bug est répétable sur plusieurs machines de mon organisation, peut-être un problème de master spécifique). Ce n’est toutefois pas très gênant.

Pour conclure ce billet auquel d’autres succéderont au fil de mon utilisation de WebDev, je dirais qu’il faut prendre cet AGL pour ce qu’il est: un moyen de développer rapidement sans prétention. Il faut donc savoir faire le deuil de toute agilité du SI et pour cela bien analyser la typologie de son SI.