Coding dojo Flex Mobile : Presentation Model

Le deuxième coding dojo sur Flex Mobile a eu lieu hier soir dans les locaux d’Objet Direct Grenoble.

Contexte fonctionnel :

  • Flickr via son API avec des scénarios utilisateurs de recherche par mots clés et d’affichage de résultats.

Objectifs :

  • Utiliser le SDK Flex 4.6 sorti récemment en release candidate
  • Définir une architecture logicielle telle qu’on pourrait en avoir besoin sur des applications plus conséquentes. En l’occurrence, nous sommes partis sur une architecture reposant sur le presentation model, de l’injection de dépendances avec le framework Swiz
  • Refactorer le code du dojo précédent en suivant l’architecture précédemment définie (nous nous étions arrêter à la green phase)
  • Profiler l’application dans cette architecture

Les conditions du dojo :

  • 4 développeurs
  • un écrivain qui tourne toutes les 10 minutes
  • durée : 4 heures, incluant une pause repas

Rétrospective :

  • Les plus de la soirée :
    • Des objectifs remplis 🙂
    • Découverte de nouveau framework pour certain
    • Partage sur les bonnes pratiques (injection de dépendances vs évènement)
    • Plus efficace qu’au premier dojo : objectifs clairement établis avant la soirée, rythme imposé par le roulement de l’écrivain
    • Une bonne machine de développement (merci la DSI)
  • Les points à améliorer :
    • Une rotation de 10 minutes c’est un peu court pour l’écrivain, particulièrement quand il y a des échanges / débats
    • Pour l’instant, l’application tourne seulement sur un émulateur.

Les prochains évènements :

  • un prochain dojo dans 3 semaines
  • une présentation technique de ce qui a été réalisé lors de ces dojos
  • la mise à disposition des sources dans Codendi

ASP.NET MVC : comment fournir les donnees depuis le controleur

Voici une question qui revient régulièrement lorsque j’interviens sur des projets.

En avant-propos, vous trouverez ici l’article de la msdn qui présente partiellement le problème. Ce qu’il faut retenir :

  • besoin d’afficher une vue liée à une classe du modèle ? une vue fortement typée vous apportera de la productivité via la complétion. La compilation des vues, si vous l’activez, vous apportera de la sérénité dans le refactoring. Les étapes :
    • définir une action du contrôleur qui récupère une instance de la classe du modèle cible et qui transfère cette instance à la vue. On peut utiliser par exemple la méthode View(object). L’objet passé en paramètre correspond à l’instance du modèle.
    • définir une vue fortement typée. Généralement, on utilise la directive  @model dans la vue Razor pour définir le type du modèle qui sera utilisé. Cette instruction permet d’utiliser la propriété WebViewPage.Model et d’avoir la complétion (WebViewPage<T> est un générique).
  • besoin d’afficher une vue générique, non liée à une classe du modèle ? une vue faiblement typée apportera simplicité (moins de classe) et/ou dynamicité (possibilité de fournir à la vue des données issues d’une introspection). Les options :
    • utilisation du dictionnaire de données WebViewPage.ViewData. Il s’agit d’un dictionnaire dans lequel les données sont identifiées par une clé de type « magic string ».
    • utilisation du type dynamic avec la propriété WebViewPage.ViewBag. Ce principe a pour conséquence d’alléger la syntaxe  du dictionnaire.

Techniquement il est possible de mixer les approches (vue fortement typée + vue faiblement typée), mais n’est-ce pas le reflet d’un problème de conception ?

http://msdn.microsoft.com/fr-fr/library/dd394711%28v=VS.98%29.aspx

Lancement du coding dojo sur Flex mobile

Dernièrement, Objet Direct a démarré une série de coding dojos sur le thème Flex et la mobilité.

Les objectifs :

  • prendre en main l’outillage
  • monter en compétence sur cette nouvelle technologie
  • évaluer les capacités de la plateforme
  • partager / apprendre collaborativement

Les conditions choisies :

  • une équipe de 4 personnes
  • un écran, un clavier, un vidéo projecteur
  • un objectif de séance partagé par tous

Rétrospective sur l’organisation :

  • Les plus de la soirée
    • Une application qui fonctionne ! C’est toujours bon pour le moral
    • Une bonne cohésion dans le groupe
    • Une bonne ambiance
  • Quelques améliorations à apporter
    • Définir un objectif en amont de la soirée afin de gagner en efficacité
    • Alterner plus fréquemment d’écrivain
    • Inciter l’écrivain à mieux décrire ce qu’il fait

Les prochains évènements :

  • Une deuxième soirée courant novembre
  • Une série d’articles techniques présentant les investigations menées

Execution d’un test de charge dans le Cloud

Montée en charge

Lors d’un développement d’une application Web grand public, un problème récurrent apparait : combien d’utilisateurs l’application pourra-t-elle supporter ?

La solution parait simple : planifier un test de charge ! Oui, mais …

  • la bande passante de mon réseau locale sera-t-elle suffisante ?
  • la machine exécutant les tests sera-t-elle assez puissante ?
  • est-ce que le test utilisera un accès réseau équivalent à celui des internautes ou utilisera-t-il une liaison spécialisée ?

Une solution : CloudNetCare

CloudNetCare répond à cela en proposant un service de test de charge dans le Cloud. La mise en place s’avère assez simple :

  1. création d’un scénario de test avec Selenium IDE, un plugin Firefox permettant d’enregistrer les actions de navigation réalisées par un utilisateur
  2. création d’un scénario de test avec CloudNetCare en fournissant simplement le script enregistré par Selenium IDE
  3. validation du scénario, en le jouant par un unique utilisateur simulé par CloudNetCare
  4. paramétrage du test, par exemple le nombre d’utilisateurs simulés ou  bien le navigateur utilisé
  5. exécution du test

Résultats :

Temps de réponses
Temps de réponses
Requetes par secondes
Requêtes par secondes
Bande passante
Bande passante

Un service à quel prix ?

La première offre est tout simplement gratuite, avec un nombre d’utilisateurs limité à 25. Voici le détail de l’offre : http://www.cloudnetcare.com/fr/tarifs

Interroger SAP depuis une application .NET

L’intégration d’applications spécifiques avec des ERP fait partie du quotidien d’Objet Direct depuis l’intégration avec Viseo.

Dans son article, Ioan nous avait montré comment récupérer des données stockées dans un ERP Dynamics AX depuis une application .NET avec le Business Connector. A mon tour de présenter l’approche proposée par SAP avec son connecteur 3.0, diffusé en début d’année.

Les fondements du connecteur SAP : Remote Function Call

Que ce soit en version 3.0, diffusée en début d’année, ou en version précédente, le connecteur repose sur une approche RFC, Remote Function Call. Des fonctions métier sont implémentées en ABAP et déployées sur un serveur SAP. Les applications distantes utilisent ces fonctions en leur fournissant des paramètres en entrée et en récupérant des résultats. Les aspects techniques tels que les connexions, la sérialisation sont pris en charge par le connecteur, simplifiant ainsi le code des applications distantes.

Contrairement à la version précédente où l’outil générait à partir des fonctions ABAP des classes C# statiques de type proxy, la version 3.0 adopte un modèle plus dynamique qui permet notamment d’accéder à la description des fonctions. Comme nous allons le voir, ce modèle repose essentiellement sur des magic string (API faiblement couplé, noms de fonctions/paramètres résolus par des chaines de caractères).

Plusieurs patterns de messaging sont supportés par le connecteur. Dans cet article, nous détaillerons le pattern request-reply synchrone : l’application .NET invoque une fonction ABAP et attend le résultat.

Dans notre application, un seul serveur SAP est ciblé. Une destination, une instance de RfcDestination permet d’identifier un serveur SAP.  Cette instance est configurée au démarrage de l’application et elle est fournie à notre code applicatif. Je détaillerai dans un autre article les éléments de configuration.

Passons au code :

Nous souhaitons invoqué une méthode ZZ_ECHO dont la description est la suivante

* »———————————————————————-
* »* »Local Interface:
* »  IMPORTING
* »     VALUE(INPUT) TYPE  CHAR1
* »  EXPORTING
* »     VALUE(OUTPUT) TYPE  CHAR2
* »     VALUE(S_OUTPUT) TYPE  ZZOUTPUT
* »  TABLES
* »      T_OUTPUT STRUCTURE  ZZOUTPUT
* »———————————————————————-

Et voici le code C# correspondant :

// récupération d’une Repository qui contient la définition des fonctions
var rfcRepository = RfcDestination.Repository;

// récupération d’un descripteur de fonction correspondant à la fonction ZZ_ECHO disponible sur le serveur SAP
IRfcFunction echoFunction = rfcRepository.CreateFunction(« ZZ_ECHO »);

// la fonction prend en entrée un paramètre de type chaine de caractères nommé « INPUT »
echoFunction.SetValue(« INPUT », « A »);

// invocation de la fonction distante en mode synchrone en fournissant les coordonnées du serveur via l’objet destination
echoFunction.Invoke(RfcDestination);

// récupération du résultat : cette fonction renvoie un paramètre nommé « S_OUTPUT » qui est une structure
IRfcStructure param = echoFunction.GetStructure(« S_OUTPUT »);

// l’un des champs de cette structure est nommé « OUTPUT », c’est une chaine de caractères
var result = param.GetString(« OUTPUT »);

Quelques remarques complémentaires :

  1. Plusieurs types de données peuvent être utilisés :
    • types primitifs : chaines de caractères, décimaux, ….
    • type structure : types complexes permettant d’agréger des champs, chaque champ ayant un nom et un type
    • type table : structure permettant de stocker une liste d’éléments, tout comme une table d’une base de données
  2. Contrat de fonction documenté : le contrat fourni par les fonctions ABAP doit être clairement détaillé, et notamment le nom et le type des paramètres, les structures et les tables utilisées. En cas de doute, le plus simple est de lancer l’application en mode DEBUG et de positionner un point d’arrêt lorsqu’une instance de IRfcFunction est récupérée. On peut alors visualiser dynamiquement les méta données de la fonction. Mais cela reste moins pratique qu’une description textuelle partagée par toute l’équipe.
  3. La repository joue également un rôle de cache : lorsque l’on demande la définition d’une fonction qui est déjà enregistrée dans la repository, aucun appel n’est réalisé sur le serveur SAP

Conclusion :

Ce cas d’école montre comment invoquer une méthode distante déployée sur un serveur SAP. On constate notamment que le code nécessaire reste relativement simple.

Entity Framework Model First

J’ai eu l’occasion d’intervenir sur un projet utilisant Entity Framework 4.1 avec une approche Model First. Je profite de ce billet pour faire part de mes premiers retours.

Contexte technique du projet

  • une trentaine d’entités, dont une dizaine stéréotypées référentiel
  • des règles métier
  • un workflow de validation
  • une approche domain driven

Rappels sur les principes de l’approche Model First

Je ne vais pas détailler ces rappels car il existe de nombreux articles sur le sujet. Je vous propose celui-ci qui me parait intéressant.

Dans les grandes lignes, le processus de développement consiste en deux étapes :

  1. définition d’un modèle du domaine, appelé modèle conceptuel dans Entity Framework. Cette définition est généralement réalisée à partir d’un designer graphique, outil permettant de créer visuellement un pseudo diagramme de classes. Pour les plus courageux (ou quand l’outil a atteint ses limites), il est également possible de modifier le fichier XML sous-jacent. Mais soyons clairs : le fichier de mapping XML de NHibernate est peu complexe par rapport au fichier EDMX proposé par EF !
  2. transformations de modèles. A partir du modèle conceptuel, EF nous propose des outils permettant de générer les modèles relationnels et objets ainsi qu’une partie de la couche d’accès aux données. Ces transformations reposent sur les T4 Text Templates, outil simple et efficace de génération de code.

Quelques principes adoptés sur le projet

  • Domain driven : un modèle du domaine riche, contraint, contenant notamment les règles métier.
  • L’IHM, réalisée avec ASP.NET Web forms et jQuery n’a alors en théorie plus qu’à venir se greffer sur le modèle
  • patterns context-per-request et conversation utilisée dans seam
  • utilisation partielle du scaffolding pour les entités de référence

Avantages

  • Outillage productif intégré dans Visual Studio
  • Adaptation de la génération avec les T4Templates. Voici un exemple d’adaptation : partant du principe qu’une contrainte sur le domaine apporte de la richesse et évite des erreurs d’incohérence, j’insiste sur le fait de marquer les contraintes. Si une entité Livre a nécessairement un titre, le constructeur de Livre devrait avoir un paramètre non optionnel « titre » et la visibilité du setter de la propriété « Titre » devrait être réduite. Quelques lignes dans le T4Template et cette règle est généralisée à l’ensemble du domaine !

    Relation ManyToOne requise
    Relation ManyToOne requise
  • Refactor facilité : Approche agile, permettant de refactorer pour améliorer la sémantique du domaine et donc sa compréhension. Le travail à réaliser est opéré sur le modèle conceptuel. Domaine, repository, schéma de BD sont générés : ça ne coute donc presque rien. Un peu de rework est parfois nécessaire dans les couches supérieures, en fonction du refactor apporté.

Limites rencontrées

  • Mécanisme de Facets non extensible. Les Facets permettent d’apporter des précisions sur les propriétés des entités : par exemple si la propriété est Nullable, sa longueur maximale… Certaines facets sont manquantes, typiquement la facet unique. Certes, les équipes de Microsoft travaille dessus, mais je doute qu’ils puissent couvrir tous les cas de figures. Ce qui je pense pourrait être intéressant, serait introduire un point d’extension permettant aux développeurs de définir de nouvelles Facets. Les développeurs pourraient alors exploiter ces Facets dans les templates.
  • Méta données des entités non extensibles. Certaines entités jouent des rôles particuliers, nécessitant une implémentation qui leur est propre. C’est par exemple le cas des entités de référence (les unité de mesure, les catégories de produits, …). Ces entités ont une particularité : les interfaces d’administration sont des interfaces de type CRUD. Le scaffolding est une bonne option pour ce type d’interface. Pour l’activer, il faut tagguer les classes C#. Je trouve dommage qu’on ne puisse pas tagguer ces entités directement dans le modèle avec une annotation custom. Dans l’exemple, l’annotation aurait été Referential. Dans la transformation de modèle, on aurait alors pu rajouter une règle : toutes les entités stéréotypées Referential supportent le scaffolding. A défaut, nous avons utiliser le mécanisme des classes partielles pour apporter cette information. 
  • Stratégie d’héritage globale : il existe plusieurs stratégies pour mapper un héritage objet dans un modèle relationnel (table par type, table par classe concrète, table par hiérarchie). Le choix d’une stratégie doit être traitée au cas par cas : dois-je privilégier la performance sur une requête polymorphe ? dois-je promouvoir le faible couplage ? Malheureusement dans l’outil, le choix est unique pour tout le modèle :(. La encore, un mécanisme d’extension de type stéréotype aurait été le bienvenu.
  • Namespace globale. Actuellement avec l’outil, on ne peut définir qu’un seul Namespace pour un modèle EDMX.

Ma conclusion

Je trouve cette approche productive pour des projets nécessitant peu de spécificités (comprendre sortir du cadre prévu par Microsoft) et dont la complexité du modèle du domaine reste raisonnable. Comme toutes les approches Model Driven, la modification des templates n’est intéressante que si le nombre d’entités est significatif . La limite majeure pour des projets plus conséquents, c’est le manque de points d’extension. Je terminerai par un dernier constat qui est également vrai pour les outils de ce type : ne pas se laisser berner par la facilité apparente !

Coding Dojo sur Entity Framework

Voici un rapide retour sur le coding dojo organisé le 16 juin 2011 à Objet Direct sur le thème « Entity framework code first ».

L’approche code first présentée ici a bien évolué avec la version 4.1, et notamment la partie convention over configuration qui permet de gagner en productivité et en clarté.

Pour changer du format classique des formations en soirée, nous sommes partis d’une base de coding dojo randori kata. Le programme était le suivant :

  • présentation générale d’entity framework
  • présentation du mode code first
  • mise en œuvre du coding dojo avec les règles suivantes
    • 1 machine, 1 projecteur
    • un nombre de participants inférieur à 7 personnes
    • un challenge
    • des périodes de 5 minutes, dans lesquelles un pilote et un copilote avancent sur le challenge
    • à la fin de la période, le copilote devient pilote et un autre participant devient le copilote
  • TDD

Difficultés rencontrées et constat :

  • 4, 5 personnes c’est vraiment bien
  • la période de 5 minutes n’est pas suffisante. 7 minutes c’est mieux

Les plus par rapport à un format plus classique :

  • dynamique et vivant
  • hétérogénéité des participants plus facile à gérer
  • moins de préparation
  • plus ouvert, très enrichissant : les participants peuvent introduire de nouvelles notions
  • dense, informations très condensées, rythme soutenu
  • favorise les échanges
  • objectifs plus facilement atteignables

Packaging et déploiement d’une application Web avec Visual Studio 2010

Industrialiser, faciliter le développement d’une application Web en utilisant un outillage adapté au projet est appréciable. De manière générale, limiter les tâches à faible à valeur ajoutée, par exemple en les outillant, est une bonne pratique reprise dans les méthodes dites « agiles », telles que Scrum, ou bien XP.

Dans le cycle de vie d’une application Web, le packaging et le déploiement sont de bons candidats à l’automatisation. C’est d’autant plus vrai si l’équipe travaille par itération, en livrant une version régulièrement (sur nos projets, c’est généralement 3 semaines).

Visual Studio 2010 va nous aider à faciliter ces déploiements. En réalité, Visual Studio fournit une interface permettant de configurer une brique disponible sur iis.net : le web deploy. L’objectif de cette brique est de packager une application Web, en fournissant des scripts d’installation, en permettant d’inclure par exemple des scripts SQL de création de table ou d’insertion de données. L’ensemble des livrables est rassemblé dans un répertoire. Pour déployer sur une machine distante, il faut copier ce répertoire sur la machine cible et lancer le script. Pré-requis sur la machine cible : web deploy doit être installé.

Détaillons le travail à réaliser dans Visual Studio.

Première étape : configurer le packaging d’un projet de type application Web.

Lancement de la configuration du packaging d'un projet de type application Web
Lancement de la configuration du packaging d'un projet de type application Web

Deuxième étape : configurer le packaging

Ecran de configuration du packaging
Configuration du packaging

Cet écran de configuration permet notamment d’indiquer :

  • la configuration du build. Généralement, on lance l’application en mode Debug lors du développement, ce qui permet d’avoir entre autres choses des traces d’exécution. En revanche, le déploiement sur l’environnement de production est réalisé en mode release. Web deploy permet de définir des paramètres différents selon la configuration souhaitée. L’exemple type, c’est la connexion à la base de données dont les paramètres sont différents en mode développement ou en mode production.
  • l’URL cible d’accès à l’application Web. Dans notre exemple, si le site par défaut IIS est un serveur localhost, l’application cible sera disponible sous  http://localhost/ProtoGraphique_deploy
  • les fichiers SQL à exécuter sur le serveur de base de données avant de lancer l’application : création du schéma de base de données, insertion des données de référence, …
  • le chemin où notre livrable sera disponible. Parmi les livrables, figurera un script à exécuter en ligne de commande sur le serveur. Ce script peut être lancé avec l’option /T qui simulera le déploiement. Pour réellement jouer le déploiement, il faut exécuter le script avec /Y. Il est également possible de jouer le déploiement directement à partir de IIS manager, avec la commande « Import »

Une fois la configuration terminée, il reste à sélectionner la configuration de build souhaitée dans l’IDE et d’exécuter la commande « Build Deployment Package », disponible dans le menu présenté ci-dessus.

Derrière cette interface, plusieurs fichiers texte sont générés. Ils peuvent d’ailleurs être édités manuellement comme le décrit cet article. Je vous rassure, ce n’est pas le cas d’usage. En revanche, le fait que tout ce mécanisme soit décrit dans des fichiers texte offre deux avantages :

  1. les fichiers peuvent être stockés dans le gestionnaire de sources et partager par toute l’équipe
  2. si vous avez un mécanisme d’intégration continue, que ce soit avec Team Foundation Server ou avec une usine logicielle libre telle que Jenkins, la génération du packaging peut être automatisée !

Tracer une communication Flex

Je développe une application Flex avec mon environnement de développement : tout va bien. En cas de problèmes, je peux poser des points d’arrêt, débugger dans mon IDE préféré.

Vient ensuite le temps du déploiement sur un serveur : premier réflexe, je teste l’application depuis mon navigateur. L’application se charge : l’écran d’accueil, un écran de login, est affiché. Tout va bien.

Je tente de me loguer, avec un premier échange de données entre le client Flex et le serveur. Et là, c’est le drame : rien ne se passe, néant, nada …

Une première piste est de trouver un moyen d’identifier les échanges avec le serveur. Des outils tels que Fiddler ou Ethereal vont permettre de monitorer ce qui se passe (ou ce qui ne se passe pas). Quelques données à vérifier :

  • l’URL  de requête envoyée : correspond-elle à l’URL configurée sur mon serveur back-end ?
  • contenu de la requête
  • code et contenu de la réponse retournée par le serveur

J’apprécie particulièrement Fiddler qui est bien intégré dans FireFox par l’ajout de l’addon FiddlerHook.

NuGet en ligne de commandes

J’avais présenté succinctement NuGet dans ce billet, en montrant comment importer une librairie externe par un simple click droit.

Il est également possible de travailler en ligne de commandes, en ouvrant le Package Manager Console (Tools > Library Package Manager). Le premier point d’entrée : « get-help NuGet », qui permet de connaitre l’ensemble des commandes disponibles. En voici quelques-unes:

  • Install-Package
  • Uninstall-Package
  • Get-Package, avec notamment le paramètre -Remote permettant de lister les packages disponibles en ligne
  • Update-Package

Vous pouvez retrouver le détail de ces commandes ici.