NHibernate en Medium Trust

2009-11-02
Tags:
Posté dans Programmation
Aucun commentaire »

Faire fonctionner NHibernate en Medium Trust n’a pas été facile mais j’ai finalement réussi à faire fonctionner une application relativement simple. Quand je dis simple c’est vraiment très simple : il n’y a qu’une seule classe dans mon Domain Model…

Après m’être battu avec Castle ActiveRecord, j’ai du laisser tomber et retourner à du NHibernate pur. L’avantage majeur de ActiveRecord est qu’il n’est pas nécessaire de produire des fichiers de mapping xml  pour chaque classe du domaine. Cela facilite beaucoup le démarrage d’un projet où le Domain Model est susceptible d’évoluer beaucoup. Heureusement, ActiveRecord est capable de générer ces fichiers de mapping pour nous (en mode Debug), ce qui a facilité le passage à NHibernate une fois que j’ai décidé d’arrêter de me battre avec les problèmes de ActiveRecord en Medium Trust.

Il existe un guide assez complet pour démarrer avec NHibernate : http://nhforge.org/wikis/howtonh/your-first-nhibernate-based-application.aspx

Il existe également un guide express pour faire rouler NHibernate en Medium Trust : http://nhforge.org/wikis/howtonh/run-in-medium-trust.aspx

Cependant il y a deux points auxquels il faut faire attention :

- All referenced assemblies must be marked with AllowPartiallyTrustedCallers

- Reflection optimization must be disabled
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<reflection-optimizer use="false" />

</hibernate-configuration>

Dans la version de NHibernate que j’utilise (2.1.0 GA) les assemblies étaient déjà marquées avec l’attribut AllowPartiallyTrustedCallers, donc pas besoin de modifier le code source.

Cependant, ajouter <reflection-optimizer use="false" /> à la configuration de NHibernate ne fonctionne pas. La directive ne semble pas être prise en compte. Il faut à la place ajouter la ligne suivante avant l’initialisation de NH :

NHibernate.Cfg.Environment.UseReflectionOptimizer = false;

Une fois que j’ai résolu ce dernier problème, mon application était fonctionnelle en Medium Trust. Ça fonctionne même chez mon hébergeur, Go Daddy. Ouf, j’ai pas fait ça pour rien…

Copier une table de SQL Server vers MySQL

2009-08-02
Tags: ,
Posté dans Programmation
Aucun commentaire »

Vendredi j’ai du migrer une table contenant les code postaux du Canada de SQL Server à MySQL. La table comporte plus de 800 000 enregistrements et je voulais quelque chose de moins lourd que de scripter le tout en SQL.

MySQL possède un outils qui permet d’importer des données au format TSV, c’est à dire avec des tabulations comme séparateur de colonnes. Il faut donc d’abord exporter les données dans ce format. Voici la requète utilisée :

SELECT [PostalCode] + '	' +
    [StateCode] + '	' +
    [Latitude] + '	' +
    [Longitude] + '	' +
    [CityName]
FROM [dbo].[PostalCode]

SQL Server Management Studio permet d’exécuter la requète et d’enregistrer le résultat dans un fichier. Pour cela sélectionner Query –> Results To –> Results to File dans le menu. Le nom du fichier doit correspondre au nom de la table dans MySQL. L’extension du fichier est sans importance.

Voici un extrait du résultat. Le fichier comporte également deux lignes d’en-tête qu’il faudra ignorer à l’importation.

A0A 1A0	NL	47.007347	-52.958921	AQUAFORTE
A0A 1B0	NL	47.362280	-53.293993	AVONDALE

Ensuite il faut utiliser mysqlimport.exe (sous Windows) pour importer les données dans MySQL. La table doit avoir été créée au préalable.

mysqlimport.exe --user=user_name
	--columns=postalcode,statecode,latitude,longitude,cityname
	--ignore-lines=2 databaseName pathToFile

Après l’importation,  il a fallu supprimer les deux derniers enregistrements de la table car la fin du fichier contenait des lignes inutiles qui ont quand même été insérées.

En tout cela prend environ 10 secondes à exporter les donnés dans le fichier, puis 10 secondes pour les importer dans MySQL, ce qui plutôt rapide. En comparaison, le script SQL que j’avais testé au départ faisait un timeout au bout de quelques minutes…

Voir également cette solution sur StackOverflow : Migrate table from MS SQL Server to MySQL

Les bienfaits de SCRUM – L’outil le plus simple

2009-07-26
Tags:
Posté dans Boulot
Aucun commentaire »

Ici on parle du fameux Post-It™. Avant la mise en place de SCRUM dans la compagnie, le petit carré de papier jaune se faisait discret. Un pense-bête dans le coin d’un moniteur ou bien une simple note apposée sur un document important étaient les seules utilisation dont je puisse me souvenir.

Quelques mois plus tard, c’est la révolution du Post-It dans la compagnie : les notes autocollantes de toutes les tailles et de toutes les couleurs recouvrent des pans de murs entiers, au point que certains s’inquiètent de l’impact néfaste de SCRUM sur l’environnement !

Mais ce succès n’est pas anodin. Le Post-It est certes un outil très simple mais aussi très puissant : autocollant, transportable et déplaçable à volonté (enfin presque), facilement mis à jour avec un simple crayon… Et en le retournant, il est même réutilisable une deuxième fois ! À condition qu’il colle encore bien sûr.

Les Post-It servent entre autre à identifier les Stories planifiées pour le Sprint ainsi que les tâches qui en découlent. Rassemblés sur un support vertical, ils forment le tableau de bord du projet.

L’avantage d’utiliser un support physique plutôt qu’un outil électronique est qu’il est beaucoup plus simple de suivre le travail en cours. Il suffit de suivre la transhumance des morceaux de papier le long du mur pendant le déroulement du Sprint pour avoir un aperçu rapide de l’avancement des tâches. Le tableau de bord du Sprint est consultable par tous à tout moment et chacun peut le mettre à jour au besoin. Simple outil de planification et de suivi au départ, le tableau de bord devient même un lieu de rencontre, de discussion et d’échange car il est beaucoup plus efficace de parler du projet quand on l’a sous les yeux.

Évidemment SCRUM ne se résume pas à coller des bouts de papier sur un mur, mais disons que c’est sa manifestation la plus visible au début. Une fois que tout le monde sera à l’aise avec la mécanique de SCRUM, on les remplacera surement par un outil électronique (tout sauf Excel, merci) mais en attendant, c’est l’outil le plus simple et le plus efficace.

Ce billet fait partie de la série “Les bienfaits de SCRUM

Les bienfaits de SCRUM – Les réunions qui commencent et terminent à l’heure

2009-07-22
Tags:
Posté dans Boulot
Aucun commentaire »

Je déteste les réunions.

Pour être plus précis, je déteste les réunions où je perds mon temps. Je déteste les réunions de 30 minutes qui durent 1 heure, les réunions qui empiètent sur l’heure du lunch, les réunions ou je suis assis à écouter des débats stériles qui n’aboutissent à rien, les réunions qui terminent par “On va réfléchir à ça et on refait une réunion pour voir ce qu’on décide.” Je sais pas pour vous mais moi j’ai du travail qui m’attends…

Avec un peu de “gros bon sens”, voici ce qu’on peut faire pour améliorer les choses :

Une réunion commence à l’heure et termine à l’heure. Si les gens sont en retard, on commence sans eux, ils ne seront pas vexés. Quand le temps est écoulé, tout le monde est libéré. Si les choses dérapent, le Scrum Master peut invoquer la toute puissance de la boite de temps pour mettre un terme à la rencontre et mettre tout le monde dehors.

Une fois que tout le monde a intégré la règle, on peut commencer à travailler.

Update : Justement voici un article de Paul Graham qui explique pourquoi les programmeurs détestent tant les réunions.

Ce billet fait partie de la série “Les bienfaits de SCRUM

Installer un serveur LAMP sur Ubuntu Jaunty (9.04)

2009-06-17
Tags:
Posté dans Aventures ordi-naires
Aucun commentaire »

Aujourd’ hui j’ai du configurer un serveur LAMP sur une machine Ubuntu Desktop 9.04 fraichement installée. Je m’attendais déjà à ce que ce soit assez simple avec toute la littérature disponible sur les Internets… Mais je ne m’imaginais pas que ce serait aussi trivial !

En fait il suffit d’une seule ligne de commande pour avoir Apache, MySQL et PHP prêts à l’emploi : sudo apt-get install lamp-server^

Il suffit juste de fournir un mot de passe pour l’usager root de MySQL, et voilà !

La magie vient du ^ à la fin de la commande, qui désigne en fait une tâche à exécuter. On peut aussi afficher toutes les tâches disponibles en exécutant : sudo tasksel

Tasksel est un installeur qui nous vient de Debian.

Tasksel is an installation system that is an integral part of the Debian installer; it is also included in Ubuntu. Tasksel groups software packages by tasks and offers an easy way to install all the packages needed for that task. It provides the same functionality as using conventional meta-packages.

Un fois l’installation terminée, on peut tout de suite tester Apache en allant sur http://localhost/ qui affiche le message suivant :

It Works!

Terminé ! (mais on peut aussi installer phpMyAdmin pour compléter le tout)

Les bienfaits de SCRUM – L’esprit d’équipe

2009-06-15
Tags:
Posté dans Boulot
Aucun commentaire »

La  notion d’équipe est centrale à SCRUM.

L’équipe est  composée d’équipiers. C’est tout. Pas de chef d’équipe ou de Lead QuelqueChose… Juste des équipiers. Certes différents métiers et différents niveaux d’expertise sont représentés, mais globalement il n’y a pas de hiérarchie au sein de l’équipe et tout le monde est impliqué dans l’ensemble des activités décrites par SCRUM.

Voici un exemple des activités au cours d’un Sprint :

  • Planification de Sprint
    • Estimation des User Stories
    • Négociation avec le directeur de produit des User Stories à inclure dans le Sprint
    • Découpage des User Stories en tâches et estimation.
  • Daily Scrum
    • Compte rendu quotidien de l’avancement du Sprint
    • Distribution des tâches
  • Revue de Sprint
    • Démonstration au client
    • Rétrospective

Faire participer tous les membres de l’équipe à toutes ces activités comporte de nombreux avantages : L’information circule infiniment mieux, tout le monde à la même vision d’ensemble du projet et chacun participe au processus de décision. L’implication de chacun s’en trouve renforcée.

C’est ainsi que le “groupe de personne travaillant sur le même projet” devient progressivement une véritable équipe.

Ce billet fait partie de la série “Les bienfaits de SCRUM

Les bienfaits de SCRUM

2009-06-09
Tags:
Posté dans Boulot
1 Commentaire »

Depuis le jour ou j’ai commencé à m’intéresser au mouvement Agile et plus particulièrement à SCRUM, je voyais ces principes comme la solution miracle pour régler les divers dysfonctionnement rencontrés dans mon quotidien de programmeur, au sein d’une petite équipe de développement interne.

Les problèmes rencontrés étaient plus organisationnels que techniques : conflits, retards de développement, objectifs mal définis,  perte d’informations, mauvaise circulation des connaissances… En réalité, la situation n’était pas si mauvaise mais disons simplement qu’il y avait place à l’amélioration.

Depuis maintenant quelques mois, SCRUM est progressivement mis en place au sein de ma compagnie les premiers effets se font sentir. Après maintenant quelques sprints je dirais que mes attentes n’ont pas été déçues. Certes aucun miracle ne s’est produit mes les améliorations sont visibles et les progrès de l’équipe sont encourageant !

Dans cette série de billets à venir, je décrirais les effets positifs que la mise en place de SCRUM a apporté. Il s’agit bien sur d’un point de vue totalement personnel, s’inscrivant dans le contexte spécifique de ma compagnie. De plus, certaines de ces observations ne sont pas forcément une conséquence de SCRUM, mais peut-être tout simplement dues au simple fait de se remettre en cause et de chercher à s’améliorer.

  1. L’esprit d’équipe
  2. Les réunions qui commencent et terminent à l’heure
  3. L’outil le plus simple

Signer une Assembly déjà compilée

2009-05-11
Tags:
Posté dans Programmation
Aucun commentaire »

Voici une astuce m’a déjà servi plusieurs fois alors je la publie ici.

Il peut arriver qu’on ait besoin de signer une Assembly après la compilation. Par exemple, il se peut qu’ une tierce partie fournisse un .dll non signé et dont on ne possède pas le code source pour le recompiler. Voici comment procéder :

  1. Lancer l’invite de commande de Visual Studio
    Démarrer –> Microsoft Visual Studio 2008 -> Visual Studio Tools -> Visual Studio 2008 Command Prompt
  2. Générer une clé
    sn -k maCle.snk
  3. Désassembler le .dll
    ildasm monAssembly.dll /OUT=monAssembly.il
  4. Assembler le .il avec la clé
    ilasm monAssembly.il /DLL /KEY=maCle.snk /OUTPUT=monAsembly.dll

Si le .dll contient des ressources incorporées, elle seront désassemblées puis assemblées également.

Gestion d’erreurs centralisée avec Elmah – Partie 2

2009-05-07
Tags: ,
Posté dans Programmation
Aucun commentaire »

Gestion d’erreurs centralisée avec Elmah – Partie 1

Dans un premier temps, il faut que les applications puissent envoyer leurs erreurs à un serveur central. La méthode qui combine le mieux simplicité et souplesse est d’utiliser HTTP pour transmettre les erreurs en POST.

Elmah ne comporte pas de HttpErrorLog, on doit donc créer notre propre implémentation. Facile ! Il suffit d’hériter de la classe abstraite ErrorLog.

using System;

namespace Elmah
{
    public class HttpErrorLog : ErrorLog
    {
        public override ErrorLogEntry GetError(string id)
        {
            throw new NotImplementedException();
        }

        public override int GetErrors(int pageIndex, int pageSize, System.Collections.IList errorEntryList)
        {
            throw new NotImplementedException();
        }

        public override string Log(Error error)
        {
            throw new NotImplementedException();
        }
    }
}

Il y a seulement 3 méthodes à redéfinir : GetError, GetErrors et LogError. Les deux premières sont utilisées pour la consultations des erreurs et la troisième pour la journalisation des erreurs.

Comme on veut pouvoir consulter les erreurs localement, le HttpErrorLog encapsulera un MemoryErrorLog qui stocke les erreurs en mémoire pour consultation locale.

Elmah possède un mécanisme pour encoder une erreur en Xml. C’est ce que nous utiliserons pour transmettre en HTTP les informations relatives à l’erreur.

L’url à laquelle sont transmises les erreurs est définie dans le web.config. Il est également important de définir l’attribut applicationName pour distinguer les erreurs d’applications différentes.

Enfin, Elmah est compatible avec les versions 1.1 à 3.5 du framework .NET donc il faut faire attention à ce que le code compile sur toutes ces versions.

Voici la classe résultante :

using System;
using System.Web;
using System.Text;
using System.IO;
using System.Net;
using System.Globalization;
using System.Collections;
using System.Collections.Specialized;

namespace Elmah
{
    public class HttpErrorLog : ErrorLog
    {
        private MemoryErrorLog _innerMemoryErrorLog;
        private string _loggingUrl;
        public HttpErrorLog(IDictionary config)
        {
            _innerMemoryErrorLog = new MemoryErrorLog(config);
            _loggingUrl = (string)config["url"];
            string appName = (string)config["applicationName"];
            ApplicationName = appName == null
                ? string.Empty
                : appName;

        }
        public override ErrorLogEntry GetError(string id)
        {
            return _innerMemoryErrorLog.GetError(id);
        }

        public override int GetErrors(int pageIndex, int pageSize, System.Collections.IList errorEntryList)
        {
            return _innerMemoryErrorLog.GetErrors(pageIndex, pageSize, errorEntryList);
        }

        public override string Log(Error error)
        {
            error.ApplicationName = ApplicationName;
            Guid id = new Guid(_innerMemoryErrorLog.Log(error));

            NameValueCollection nameValuePairs = new NameValueCollection();
            nameValuePairs.Add("errorId", id.ToString());
            nameValuePairs.Add("allXml", ErrorXml.EncodeString(error));

            StringBuilder queryString = new StringBuilder();
            foreach (string key in nameValuePairs.AllKeys)
            {
                queryString.Append(key + "=" + HttpUtility.UrlEncode(nameValuePairs[key]) + "&");
            }

            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(_loggingUrl);
            request.Method = WebRequestMethods.Http.Post;
            request.ContentType = "application/x-www-form-urlencoded";

            byte[] byteData = Encoding.ASCII.GetBytes(queryString.ToString());
            request.ContentLength = byteData.Length;
            using (Stream postStream = request.GetRequestStream())
            {
                postStream.Write(byteData, 0, byteData.Length);
                postStream.Close();
            }
            return id.ToString();

        }
    }
}

Dans la méthode Log on utilise la classe HttpWebRequest pour envoyer les données Xml dans une requète HTTP. On envoie aussi l’Id que nous a retourné le MemoryErrorLog. Ce sont les seules informations dont nous avons besoin.

Comme Elmah est un projet libre, on peut ajouter directement cette classe à la source du projet et le recompiler selon nos besoins.

Voici comment l’utiliser dans le web.config de l’application à surveiller :

<elmah>
    <errorlog applicationname="MyApplication" type="Elmah.HttpErrorLog, Elmah" url="http://logurl/LogError.axd" />
        <errorfilter>
            <test>
                <equal type="Int32" value="404" binding="HttpStatusCode" />
            </test>
        </errorfilter>
</elmah>

Ici on a rajouté un filtre pour ne pas envoyer les erreurs 404. Pour un exemple de configuration complète d’Elmah, voir cet article.

Dans la troisième partie nous verrons comment récupérer ces erreurs et les enregistrer dans la base de données centralisée.

Gestion d’erreurs centralisée avec Elmah – Partie 1

2009-05-02
Tags: ,
Posté dans Programmation
1 Commentaire »

Elmah est une bibliothèque .NET pour la journalisation (logging) des erreurs d’une application ASP.NET. Elle est très simple d’emploi et il existe pas mal de littérature sur le Web quant à sa configuration et son utilisation.

La plupart des exemples cependant concernent la surveillance d’une seule application. Mais comment faire pour gérer les erreurs de plusieurs dizaines, voire centaines de sites Web de manière efficace ?

L’envoi de courriels est la solution la plus élémentaire. Cela fonctionne bien pour quelques sites, voire quelques dizaines. Mais quand la liste des sites à surveiller s’allonge, cette solution s’avère peu pratique et une solution plus efficace est nécessaire.

Voici la liste des contraintes à considérer :

  • Les sites Web à surveiller utilisent des versions différentes de .NET, de 1.1 à 3.5
  • Le déploiement doit être le plus simple possible, sans avoir à recompiler les sites Web
  • Les sites Web sont installés chez différent hébergeurs
  • Une application doit permettre la consultation des erreurs de manière centralisée

L’utilisation de Elmah permet déjà de résoudre les points 1 et 2. En effet Elmah est compatible avec toutes les versions de .NET depuis la 1.1 et son activation nécessite seulement l’ajout de quelques lignes dans le web.config. Pfiou… c’était dur.

Il reste maintenant à développer un module pour envoyer les erreurs et une interface de consultation.