[2 novembre 2007: je viens de faire une mise à jour des chiffres de ce post (publié originellement le 19 octobre 2007)]
Je vous faisais part dans ce billet du fait que j'étais en charge cette année de développer le système de gestion du plus gros événement de Microsoft France, à savoir les TechDays 2008.
Pour se fixer les idées, les TechDays 2007 représentaient 232 sessions et ont impliqué 153 personnes pour les préparer/présenter (et je ne parle même pas de tous les autres qui ont travaillé dans l'ombre pour organiser ça).
Je vais partager dans ce billet le backstage de ce projet. Voici le schéma général de l'infrastructure :
Nous allons voir maintenant dans le détail les point suivants :
Je dispose d'un portable HP Compaq NC6120 équipé de 2 Go de RAM et d'un disque de 60Go partagé en deux partitions : 30 Go pour la partition Système (C:) et 30 Go pour la partition DATA (D:)
J'ai installé dessus
Pour contrôler le source code de mon application, j'utiliser bien-entendu Visual Studio 2005 Team Foundation Server qui est installé dans une image Virtual PC de 25 Go et se trouvant sur un disque dur externe. Je n'ai pas cette VPC allumée en permanence. Je ne l'allume que lorsque je souhaite faire un Check-In / Check-Out, ce que je fais à intervalles réguliers. Actuellement, l'ensemble du projet représente 2 038 fichiers dans 199 répertoires, soit près de 700MB.
Le serveur hébergeant les services est exposé sur Internet via l'hébergeur ASPSERVEUR (localisé à Marseille, et oui on ne se refait pas :-)). Il s'agit d'un DELL PIV DC 2.8 Ghz avec 4 Go de RAM et deux disques dur SATA de 160Go chacun. Ce serveur dispose d'un transit IP 1 Mbps dédié et garanti. Sur cette machine, j'ai installé la même chose que sur mon poste de développement (Microsoft Virtual PC 2007 en moins) :
Oui je sais, installer Visual Studio 2005 sur un serveur peut vous paraître surprenant mais c'est comme ça ! On en reparlera dans ma session :-)
C'est donc sur ce serveur que sont exposées, grâce à Windows Communication Foundation (WCF), actuellement l'ensemble des 425 services (voir un peu plus bas dans ce post).
Côté client, l'application nécessite l'utilisation du .NET Framework 3.0 et rien d'autre. Le déploiement de cette application est réalisé à l'aide de la technologie ClickOnce. Du coup, tout ce que j'ai à faire, c'est de transmettre une URL aux utilisateurs de l'application et le tour est joué !
Dans le cadre de ce projet, j'ai utilisé les expériences passées de toutes les personnes concernées l'année dernière par la gestion des TechDays.
Après plusieurs allers-retours, j'ai finalement créé le schéma quasi-final de la base de données SQL Server 2005 que j'ai exposé en réunion (vous pouvez vivre ce moment en différé en visionnant le webcast shooté par notre Marine nationale et disponible sur le blog officiel des TechDays !). J'ai ensuite faire quelques modifications pour tenir compte de l'intégration des données avec notre système de gestion des inscriptions (Galilee) et notre système de visionnage des WebCasts (Vision).
Finalement, cela donne ceci :
Nombre de tables
53
Nombre de colonnes dans ces tables
228
Nombre de procédures stockées T-SQL générées
629
Nombre de procédures stockées T-SQL écrites
357
Nombre de procédures stockées .NET (SQLCLR)
3
Nombre de scalar functions T-SQL
29
Nombre de scalar functions .NET (SQLCLR)
1
Nombre de lignes de code T-SQL
34 132 dont 8 381 écrites à la main
Comme vous pouvez le voir, j'ai écrit quelques procédures stockées en C# mais je vous en dévoilerai la raison lors de ma session :-)
Le principe que j'ai adopté est assez simple. Chaque service WCF exposé n'est rien d'autre qu'un wrapper qui effectue l'appel de la procédure stockée correspondante.
Le code ADO .NET faisait appel à la procédure stockée ainsi que le code WCF faisant appel au code précédent est entièrement généré par OlyMars. Pour cela, j'ai à la fois utilisé le modèle "DotNet Framework Data classes" fourni en standard pour la partie ADO .NET et un tout nouveau modèle que j'ai écrit et que je compte rendre disponible très vite pour la partie services WCF.
A l'heure actuelle, 425 fonctions sont exposées. Le binding actuellement utilisé est wsHttpBinding.
Il est évident qu'il vaut mieux que les services décrits précédemment soient sécurisés !
Pour cela, j'ai implémenté mon propre mécanisme de sécurité et je l'ai déclaré au niveau de la couche WCF. La base des comptes utilisateurs est donc stockée dans ma base de données. Ceci étant dit, cela n'était pas suffisant. Il fallait ensuite définir les notions d'autorisation. En gros, voici comment je m'y suis pris.
WCF fournit en standard une sécurité basée sur les rôles. En décorant via un attribut spécifique les méthodes exposées, on peut indiquer que seuls les membres de tel ou tel rôle sont autorisés. Ceci n'est pas suffisant car pour certains services, le scénario la plupart du temps est un tout petit peu plus compliqué. Généralement, tout le monde a le droit d'appeler certains services mais pas forcément avec les mêmes valeurs de paramètres.
Un exemple : la fonction de mise à jour, en tant qu'utilisateur, de ses propres informations comme l'adresse de messagerie par exemple. Tout le monde a le droit d'appeler cette fonction mais seulement pour mettre à jour les infos le concernant, pas celles des autres. Le seul moyen d'implémenter ce genre de choses, consiste à savoir quels sont les paramètres qui sont passés lors de l'appel AVANT que l'appel ne soit vraiment effectué. C'est toute la magie de l'interface IParameterInspector. Avant tout appel à un service, je suis notifié dans l'interface précédente de l'appel en cours. J'ai la possibilité d'avoir accès aux paramètres qui ont été fournis pour l'appel du service. Je fais alors appel à une procédure stockée spéciale et qui a également été généré automatiquement par OlyMars à l'aide d'un modèle spécifique que j'ai écrit pour l'occasion. Je passe à cette procédure stockée non seulement les paramètres qui ont été passés par l'appelant mais surtout l'identité de l'appelant. Il ne me reste plus alors qu'à coder dans cette procédure stockée la logique de sécurité que je souhaite pour l'appel de ce service. Rassurez-vous la session que je vais animer va vous permettre de bien comprendre comment je m'y suis pris si tout ceci vous parait confus :-).
Pour finir, l'ensemble de ces services représentent :
Nombre de fichiers dans le projet
913 fichiers
Lignes de code* dans le projet
365 067 lignes de code (total=955 925)
Ces 365 067 lignes de code correspondent à 85% de toutes les lignes de code qui ont été générées par OlyMars.
Dans cette partie là de l'application, je n'ai écrit qu'une centaine de lignes de code manuellement. Tout le reste a été généré. Bon d'accord, j'ai quand même beaucoup investi dans le modèle OlyMars. Mais il me permet désormais d'ajouter un nouveau service simplement en écrivant la procédure stockée correspondante, rien de plus.
Concernant l'application de gestion elle-même, il s'agit d'une application Windows Forms se "contentant" d'appeler les services précédents. Et bien même dans cette partie, OlyMars m'a été utile puisqu'il m'a permis de générer les formulaires d'un grand nombre de tables. J'ai également écrit un modèle OlyMars spécifique pour cela. Voici quelques chiffres :
134 fichiers
23 176 lignes de code (total=53 636)
Lignes de code* écrites manuellement
9 658
Nombre de formulaires générés
32
Nombre de formulaires développés manuellement
12
J'ai souhaité partager avec vous le backstage de cette première application liée aux TechDays 2008. Mon souhait, quand elle sera finalisée, est de pouvoir m'attaquer à une application offline, basée sur Windows Presentation Foundation (WPF), et qui vous serait destinée. Elle vous permettrait de faire toutes les recherches possibles sur les sessions des TechDays. Le stockage local des données sera effectué avec SQL Server Compact Edition. Si vous avez des idées sur ce que vous souhaiteriez voir dans cette application, c'est le moment de vous exprimer !
Voilà c'est tout pour le moment. Encore une fois la session que j'animerai aux TechDays 2008 vous donnera plus de détails sur tout ça !
* : je parle ici du nombre de véritables lignes de code, pas des lignes blanches ni des lignes de commentaires