Archive pour la catégorie ‘informatique’

Ch’ti JUG : Lili et Cassandra

Jeudi 15 décembre 2011

Le 12 décembre s’est tenu dans les locaux de l’IUT A de Lille une session du Ch’ti JUG sur Lili et Cassandra deux outils autour des bases de données NoSql. La présentation de Lili a été faite par Stevens Noel et celle sur Cassandra par Jérémy Sevellec.

Ayant déjà écrit un post sur la session sur le NoSQL, je ne reparlerais pas de Cassandra (bien que la présentation fut plus complète et fort intéréssante), vous pouvez retrouver mon post sur le NoSQL ici :  Ch’ti JUG : NoSQL

La présentation de Lili par Stevens Noel commença tout d’abord par un rappel de ce qu’est le NoSQL, du pourquoi de l’utilisation du NoSQL et de la notion de BigData. Il explique pourquoi on a eu besoin des bases de données NoSQL par la problématique du BigData : le problème du BigData c’est :

  • Quand un serveur BDD relationnel ne suffit plus à hébergé une base de donnée
  • Quand les performances en écritures ne sont plus suffisante
  • Quand les indexes poses des problèmes car ils représentent une optimisation figé (on ne peut changer un index dynamiquement)
  • Quand on a besoin de possibilité de scaling horizontal (plusieurs serveur)

Quand on est dans une ou plusieurs de ces problématique, alors les BDD relationnels standard ne suffisent plus, c’est la problématique du BigData donc les bases de données NoSQL apportent une solution.

Lili est une solution complète basée sur un ensemble de composants open source tournant autour des problématiques NoSQl, vous trouverez des informations détaillée de la solution sur son site : http://www.lilyproject.org/lily/index.html. Les différents composants peuvent tous être utilisé de sur plusieurs nœud (tout l’interêt du NoSQL est d’utiliser plusieurs serveur au lieu d’un unique) Lili se chargeant de l’orchestration.

Le principe de Lili est de fournir un ensemble de composant pour résoudre toutes les problématiques d’accès a des données de type BigData :

  • Un DataStore
  • Un système d’entrepôt de donnée (DWH)
  • Une partie Analitics

Ceci via un ensemble de briques OpenSource mise bout à bout et communiquant ensemble via ZooKeeper :

  • HBase : base de données NoSQL basée sur Hadoop (Utilisation de la distribution Cloudera de HBase)
  • MapReduce : calcul distribué sur les données NoSQL
  • Solr : indexage et requêtage des données NoSQL

Grâce à ça, Lili permet le stockage, l’indexation et la recherche des données en NoSQL de manière scalable et en temps réel!

Quelques explications sur les principales briques utilisés :

  • Hadoop : disque virtuel distribué, fiable et tolérant aux panes : l’Hadoop Distributed File System (HDFS)
  • MapReduce : calculs distribués sur plusieurs serveurs des données stocké dans l’HDFS. Tolérant aux panes (si un noeud tombe, le calculs est repris par un autre). Le calcul est localisé sur le serveur contenant la donnée. Attention MapReduce n’est pas interactif, le calcul est de type batch.
  • HBase : BDD NoSQL interactive au dessus de l’HDFS. On peut simplifier en la présentant en tant que RAM au dessus du Disque Dur qu’est Hadoop.

Lili intègre tout ça et offre par là un système complet et simple d’utilisation :

  • DataModel : les données NoSQL de HBase ne sont que des tableaux de byte, Lili intègre un système de modèle de données haut-niveau typé et permettant de réaliser des liens entre les données (relation sans contrainte, la validité des liens n’étant pas vérifié automatiquement par la BDD)
  • Version : les objets dans Lili peuvent être versionné (avec différente stratégie au niveau du stockage ou non des différentes versions des objets)
  • API : deux API existent, une Java : AVRO et une via REST
  • Indexation : via Solr, un projet lui-même basé sur Apache. Les index doivent être configuré manuellement puis ils sont créé à chaud et mis à jour à chaud à chaque insertion/suppression/mise à jour des données. On peut utiliser plusieurs indexes de manière concurrentiel. Les index sont partitionné automatiquement sur les différents nœuds.
  • Recherche : via Solr
  • Consistence
  • Pas de Master : les nœud se découvrent automatiquement, l’accès à un nœud par l’API Java fait découvrir les autres à l’API.

Une démo fort intéressante a terminé la présentation, la distribution de Lili contient des scripts permettant de lancer toutes les briques nécessaires sur une machine de développement et plein d’exemple simple pour commencer à l’utiliser.

Maintenant, il ne vous reste plus qu’à télécharger la distribution et à vous amuser avec ;)

Ch’ti JUG : NoSQL

Lundi 20 décembre 2010

Le 2 décembre s’est tenu dans les locaux de l’IUT A de Lille une session du Ch’ti JUG sur les technologie NoSQL animé par Olivier Mallassi.

L’intervenant a commencé la conférence par un bref historique de la manière dont les données on été stockées dans le monde de l’informatique:

  • Au commencement été les fichiers plats
  • Puis vinrent les fichiers plats indexé (gain de performance grâce à l’index) encore couramment utilisés (et surtout en COBOL).
  • Ensuite apparurent les base de données relationnelle (les SGBDR – Système de Gestion de Base de Données Relationnel) et le langage SQL, nous étions dans les année 1970!

Pendant prêt de 40 ans, les SGBDR régnèrent en maître sur les technologies de stockage de données … puis au détour des années 2000 un outsider est apparut, poussé par les besoins spécifique des géants du web.

En effet, de par l’accroissement de la fréquentation du web, certaines société telle que Google ou Amazon ont eu a traiter un nombre de données tellement important avec une nécessité de sécurisation des données tellement grande (leur business model étant basé dessus) que les SGBDR montrèrent leur limite et ces société commencèrent à développer des bases de données non relationnelle : le NoSQL été né.

Revenons sur les contraintes de ces géants du web:

  • Performance malgré tout (même en cas où une partie des serveurs tombe)
  • Disponibilité > 99,99%
  • Résilience (capacité à supporter les pannes)
  • Scallabilité horizontale

Pour pallier à ces contraintes, chaque société développa ses technologies. Aujourd’hui on peut les ranger en 4 catégories distinctes.

Les bases de données orientées colonne

Références : BigTable (Google), HBase (Apache) et Cassandra (Facebook)

Principales fonctionnalités:

  • Stockage des données en colonne et non en lignes
  • 1 ligne = une HashMap et 1 valeur = une HashMap, on manipule donc des HashMap de HashMap via l’API.
  • Données stockée en tableau de byte : donnée non structurée
  • Implémentation de l’algorithme MapReduce au plus proche des données (Job directement dans la base de données) pour le requêtage de données
  • Existence de DSL (Domain Specific Language) au dessus de MapReduce pour en simplifier l’utilisation telle que Hive et Pig permettant l’utilisation de JDBC et d’une sémantique plus proche du SQL.

Les bases de données Key/Value

Référence : Dynamo (Amazon) et Project Voldemor (LinkedIn)

Principales fonctionnalités:

  • Données stockée sous forme de key/value dans des HashMap : on manipule donc directement des HashMap via l’API
  • But : accepter une demande quelle que soit l’état de la base
  • Modèle distribué, élastique, ajout d’un serveur dans l’infrastructure à la demande
  • Modèle clé/valeur distribué sur l’ensemble des serveurs : clé = localisation
  • Scalabilité horizontale
  • Tolérance à la panne grâce à une synchronisation asynchrone et synchrone des différents serveurs : mode Master/Master et mise à jour concurrente (transaction non ACID)
    • gossip protocol : les serveurs se parlent entre eux au sujet de leur disponibilité
    • hinted handoff : capacité à servir la requête d’un autre serveur si celui-ci ne répond pas
  • Read Repair : modèle “eventually concistent“, ce qui veut dire consistant à la fin : plusieurs versions différentes sur les différent serveur selon leur degré de synchronisation, mais la réponse est toujours consistante.

Les bases de données orientées document

Référence: MongoDB

Principales fonctionnalités:

  • Modèle de donnée en Key/Valeur dont la valeur est une donnée structurée et indexable
  • Requêtage possible à l’intérieur de la valeur (dans sa structure)

Les bases de données Graph

Référence: neo4j

Principales fonctionnalités:

  • Données représentée en graphe
  • Implémentation d’un algorithme de parcours de graphe pour le requêtage
  • Principales notions : node, relation, property

Autres types de bases de données NoSQL

Base de données XML, Base de données Objet, Base de données géographique, …

Force et faiblesse du NoSQL

Attention, dans certain cas les forces et faiblesses peuvent être vue comme des faiblesse ou des forces. En effet par exemple le fait que la modélisation soi faible est un avantage quand on ne veut pas s’embarrasser d’une modélisation complexe.

Ces forces et faiblesses s’appliquent principalement aux base de type orientée colonnes, orientée document ou Key/Value.

Forces Faiblesses
Performance
Stockage de gros volume
Disponibilité et tolérance aux pannes
Élasticité du stockage
Souplesse de modélisation : pas de structure, on stocke ce que l’on veut.
Transaction non ACID
Faible modélisation
Pas de contrainte d’intégrité
Changement d’outillage d’administration (le plus souvent, bases de données en Java => JMX)
Peu de contraintes d’accès (GRANT)
Pas de standard
Difficile d’intégrer à un Système d’Information existant

Pour autant, il ne faut pas perdre à l’esprit que les bases de données NoSQL ne veulent pas remplacer les bases de données relationnelle mais bien offrir une alternative permettant de répondre à des besoins que n’adressent pas les SGBDR classique. C’est une réelle innovation qui nous oblige à penser différemment la notion de stockage de base de données et vient bouleverser 40 années de SGBDR.

Ch’ti Jug: GIT et Mockito

Mercredi 26 mai 2010

Mardi 20 avril s’est déroulé une session du Ch’ti JUG sur GIT et Mockito sponsorisé par ProxiAD : GIT et Mockito avec ProxiAD

Pour ceux qui ne savent pas ce qu’est le Ch’ti Jug ou ce qu’est un Jug, voir l’introduction de mon article sur la première session à laquelle j’ai participé:  Ch’ti Jug: les technologies Google.

Cette session été animée par David Gageot directeur technique chez Algodeal.

GIT

Les principaux atouts de GIT:

  • Rapide : il fonctionne en locale.
  • Déconnecté : commit local, repository local intégrale, possibilité de synchroniser un repository local avec un repository  distant
  • Ouvert
  • Flexible
  • Robuste
  • Simple : utilisation simple par des lignes de commandes
  • Complet et Complet : possibilité étendue.
  • Grande communauté d’utilisateur : github

De nombreux outils sont compris dans GIT qui permettent de faciliter grandement sont utilisation et qui peuvent faire gagner énormément de temps. Le présentateur nous a fait une démonstration de l’outil git-bisect qui a lui-seul suffit à vouloir utiliser GIT.

Imaginez que vous ayez fait une centaines de commit dans votre repository et que vous découvrez ensuite que les sources ne compilent plus! Comment faire pour trouver l’erreur ? git-bisect vous permet de facilement retrouver le commit à partir duquel vos sources ne compilent plus. Son principe: il utilise un algorithme de type dichotomie pour tester un a un l’état de votre repository. Pour cela vous lui donnez la version de départ et une commande à exécuter (par exemple “mvn compile” si vous utilisez Maven), il va ensuite lancer la commande sur les versions de votre repository et vous donner la première version dont la commande est en erreur. Comme il utilise un algorithme de dichotomie cela prend beaucoup moins de temps que de tester toutes les version … et en plus c’est automatisé!

Comment marche git au jour le jour. N’importe quel répertoire peut être définie comme un repository git (le présentateur nous a même expliqué qu’avant toute mise à jour d’Eclipse il transformer le répertoire d’Eclipse en repository git pour pouvoir revenir en arrière si nécessaire!). Ensuite ils suffit d’ajouter des fichiers (git add) et de faire des commits des fichiers (git commit -m “message”). Tout se passe alors en locale, sans connexion a aucun serveur.

Vous me direz, oui mais, et le travail en équipe?

Pour cela il y a de nombreuses manière de faire.
Par définition, on doit utiliser les commandes suivantes:

  • git clone : clone un repository (depuis une machine distante, un disque réseaux, une clé USB, un autre répertoire, …).
  • git push : envoit les modification de votre repository vers un autre.
  • git pull : recupère les modification d’un autre repository.

Classiquement, on utilise deux architecture différentes:

  • Server centralisé : on défini un serveur qui sera le repository centralisé sur lequel toute l’équipe fera ses push et depuis lequel elle fera ses pull.
  • Cercle de confiance : architecture utilisé dans les projets open source (et notamment dans le développement du noyeau linux). Il y aura alors une hiérarchie de commiteur, les plus “petit” feront un push vers une personne de plus grande confiance qui lorsqu’elle aura tester les changement fera un push vers une personne de plus grande confiance et cela jusqu’au repository de référence. Ensuite tout le monde fera des pull en cascade. Intérêt: pas d’administration, idéale pour les grande équipe, vérification limité grâce aux cercles de confiance, pas de serveur centralisé: peut marcher s’il y a défaillance d’une partie des repository.

GIT est réputé aussi pour son merge “omniscient” : GIT peut merger tout seul énormément de situation qui sous d’autre gestionnaire de source nécessite une action manuelle et permet donc des refactoring lourd sans code freeze. Il réussit à faire un merge d’un fichier ayant été déplacé et renommé alors qu’une autre personne le modifié!

Pour tout ceux qui voudrait essayer, il existe un outils permettant de migrer un repository SVN existant en gardant l’historiquel : git-svn.

Il existe de nombreuses autres fonctionnalités, si vous êtes intéressé, n’hésitez pas à creuser le sujet.

MOKITO

Mockito est un framework de mock facilitant grandement l’écriture de test unitaire par la possibilité de créer différents objets de test tel que :

  • Dummy object : Mockito.mock(Class c) : mock une classe concrète ou une interface : créé une instance “bidon” de cette classe.
  • Fake object : MaClass fake = Mockito.mock(MaClass.class); when(fake.getTime()).thenReturn(1,2,3) : crée une instance “bidon” de la classe retournant des valeurs prédéfinie (1,2,3) lors d’appel successifs d’une des méthode de cette classe.
  • Stub : MaClass stub = Mockito.mock(MaClass.class); verify(stub).send(Email.class) : crée une instance “bidon” de la classe. On peut ensuite l’utiliser (par exemple appeler une méthode send avec comme paramètre un Email). Puis dans notre testcase on va vérifier que notre stub a bien été appelé : on vérifie que la méthode send a été appelé avec un email en paramètre.
  • Mock : sur le même principe un mock permet de valider les exceptions, l’appel des méthodes avec le contenu des paramètre, les appels multiples, les réponses multiples, …

Mockito peut s’interfacer facilement avec JUnit4 grâce à l’annotation RunWith qui permet ensuite d’utiliser l’annotation Mock pour mocker un objet.

Mockito contient de nombreuses fonctionnalités avancées toujours aussi facilement utilisable (mock partiel, deep-stub, syntaxe BDD, …), pour plus d’information allez faire un tour sur le site officiel: http://code.google.com/p/mockito/

Ch’ti Jug: GlassFish ESB

Lundi 1 mars 2010

Jeudi 21 janvier s’est tenu une session du Ch’ti Jug sponsorisée par  Cap Gemini sur GlassFish ESB : GlassFish ESB avec CAPGEMINI.

Pour ceux qui ne savent pas ce qu’est le Ch’ti Jug ou ce qu’est un Jug, voir l’introduction de mon article sur la première session à laquelle j’ai participé:  Ch’ti Jug: les technologies Google

Cette session été animée par Didier Burkhalter, Architecte chez Sun.

Utilisant GlassFish ESB depuis quelques temps déjà, je connaissais le sujet. La présentation été normalement sur un cas d’utilisation, une “Success Story” mais il faut avouer que le cas d’utilisation n’a que très peut évoqué alors que ce qui intéressé mon équipe été plus un retour sur expérience. Mais je pense que ceux qui ne connaissait pas GlassFish ESB on été plus intéréssé par la conférence que moi car une bonne partie de la conférence a servi a en présenter les principes de bases.

Présentation rapide de GlassFish ESB:

  • Implémentation de référence de la spécification JSR208 :  Java Business Integration (JBI)
  • JBI est une spécification qui ne fait pas partie de J2EE mais vient répondre à des problématique intégration de services en utilisant un serveur d’application comme conteneur uniquement (sans l’utilisation de la couche J2EE). GlassFish ESB est donc un GlassFish auquel on a ajouter un conteneur JBI.
  • JBI répond donc à des besoin autre que des besoin client/serveur. Aux besoin d’ESB: Enterprise Service Bus.
  • JBI est décomposé en trois couches:
    • Binding Composant: couche basse permettant la communication avec les éléments externe à l’ESB. Les principaux Bindng Composant sont: JMS, HTTP (Soap), Scheduler, FTP, Email, …
    • NMR (Normalized Service Bus): c’est le coeur de l’ESB, il permet la communication de manière normalisé enter toutes les partie de l’ESB
    • Service Engine: moteurs permettant de faire fonctionner les composants déployé dans l’ESB (les différents jar et autres artefact). Les principaux services engine sont: J2EE (pour les EJB), Bpel, Xslt, Pojo, …
  • GlassFish ESB est livré avec un ensemble de binding component et de service engine, de nombreux autres peuvent être trouvé dans le projet open ESB (issue de la communauté open source), dans le projet CAPS (livré par Sun mais payant) ou par des société tierces.
  • Netbeans est l’IDE permettant de développer et de déployer facilement pour GlassFish ESB. Il contient entre autre un designer BPEL de très bonne qualité.

Quand on veut développé pour GlassfishESB, on développe les composants suivant:

  • Des Webservices, EJB ou Pogo à intégrer pour les parties métier
  • Des XSLT pour les transformation
  • Des BPEL pour le mapping de donné et l’orchestration des services. La version de BPEL est la 2.0.
  • Une CASA (Composite Application): artefact final de déploiement sur le serveur. Elle permet de lier entre eux les différents composants de l’application et de gérer la couche de binding (qui peut être séparé des composants) et la partie QoS (Quality Of Service)

De nombreuses autres fonctionnalités existent:

  • Gestion des alertes et des évènement
  • Monitoring via JMX et scripts: GlassFish ESB est livré avec des bean JMX et des scripts permettant de monitorer les application et les instances de BPEL mais est livré sans réelle console de monitoring et de supervision. C’est du ressort du développeur de créer ses propres consoles.
  • CEP: Complex Event Processing si on achète la version CAPS de l’ESB
  • De nombreux autres fonctionnalités sont disponibles, certaines gratuites d’autres payants. Voire les sites web des produits.

Quelques mots sur les différentes version, qui toutes regroupe une version de GlassFish intégrant le conteneur JBI et une version de Netbeans comprenant les éditeurs BPEL et CASA. J’ai utilisé ici principalement le terme de GlassFish ESB mais pour être exacte il faut séparé:

  • OpenESB: version open source avec appuie de la communauté. Aucun support possible. Près de 40 composants disponible dont de nombreux en version bêta.
  • GlassFish ESB: version gratuite mais permettant une support de Sun. Sous ensemble stable d’Open ESB comprenant environ 15 composants.
  • CAPS: version payante fournie par Sun, apportant de nombreux composants et fonctionnalités supplémentaire. Généralement basé sur une version antérieur de OpenESB et Netbeans.

Pour terminer, quelques mots du cas d’usage présenté. Il s’agit de la création d’environ 40 composants pour une société de télécommunication pour gérer les demandes de création de lignes ADSL pour les entreprises. Le nombres de commandes été de l’ordre de quelques centaines à un millier maximum par jour. Le développement a été réalisé dans un temps court (grâce à la plateforme qui offre une architecture standardisé opérationnelle et aux facilité offertes par Netbeans) par une équipe de 4-5 personnes en mode Agile. Et le résultat a été, pour le client, une surprise car très rapidement fonctionnel et performant.

Pour terminer, quelques liens pour aller plus loin:

Ch’ti Jug: Drools v5 et Drools Planner

Samedi 13 février 2010

Jeudi 21 janvier s’est tenu dans les locaux de l’Université de Lille 1 une session du Ch’ti Jug sponsorisée par Cylande sur Drools:  Drools, avec Cylande et l’Université Lille 1

Pour ceux qui ne savent pas ce qu’est le Ch’ti Jug ou ce qu’est un Jug, voir l’introduction de mon article sur la première session à laquelle j’ai participé:  Ch’ti Jug: les technologies Google

Cette session été animée par Mark Proctor, Project Leader de Drools et Geoffrey De Smet créateur de Drools Planner.

Le première partie nous as donc parlé de Drools version 5, en commençant par une explication de ce qu’est un moteur de règle et des spécificité de Drools. La conférence été d’un niveau technique très élevé, je ne vais pas ici tout vous rapporter. Si vous désirez savoir ce qu’est un moteur de règle et comment marche Drools je vous conseil de lire l’excellent article du blog de Xebia: Drools et les moteurs de règles

Pour ne pas parait trop paresseux, je vais quand même vous donner, pêle-mêle, quelques informations glané lors de la conférences:

  • Intégration avec Hibernate: on peut accéder directement à la session depuis un pattern via $hbm, par exemple $hbm.getNamesQuery(“myQuery”);
  • Timers: permet de mettre des contraintes de temps sur une règle. Utilisation d’expression de type crontab possible.
  • Calendars: permet d’exécuter une règles à une date données uniquement.
  • logicalInsert: permet d’enlever automatiquement un objet quand la règle devient fausse. Par exemple, une règle ajoute un permis de novice quand on a moins de deux ans de permis, le permis de novice est ajouté avec un logicalInsert, dès qu’on a plus de deux ans de permis, le permis de novice est automatiquement enlevé.
  • CEP: Complex Event Processing: système d’évènement proche de CEP avec la possibilité de gérer des évènement changeant dans le temps.
  • DSL: possibilité de définir son propre langage (DSL: Domain Specific Language)
  • self-monitoring, adaptive, capacité de debug, …

La deuxième partie de la conférence été dédiée à Drools Planner: un outils de planification basé sur le moteur de règle Drools. L’intervenant a commencé par nous expliquer ce qu’est la planification en partant d’exemple simple (faire rentrer 5 cartons de tailles différentes dans un box) en arrivant à l’exemple type: faire la planification de session d’examen.

Pourquoi un logiciel de planification? Calculons tout d’abord le nombre de possibilité qu’il existe pour la planification de 80 examen dans 40 salles avec 1000 élève on en arrive à … 1000 exp (80 * 40), ce qui donne plus de possibilité que le nombre d’atomes de l’univers … et il faudrait à un super calculateur plusieurs milliers d’années pour arriver à tous les tester! Pour résoudre ce type de problématique la solution naïve de tester toutes les combinaisons possible (aussi appeler brute force) n’est donc pas possible. Arrive alors les algorithme qui permettent de trouver une solution “acceptable” qui ne sera bien sur pas la meilleur (qui ne peut être trouvée que en testant toutes les combinaison) mais une solution quand même! Dans ces problème, une solution n’est même pas assuré!

Tout d’abord, on doit définir les contraintes que l’on sépare en deux catégories:

  1. Les contraintes dure (hard): que l’on ne peut enfreindre
  2. les contrainte légère (soft): que l’on peut enfreindre

Puis on pondère les contrainte. L’algorithme essayera ensuite de trouver une solution avec le score le moins élevé … donc qui viole le moins de contraintes possible (et si possible aucune contrainte dure).

Pour cela, Drools Planner utilise un ensemble d’algorithme déterministique (pour baisser le nombre de solution à tester) puis heuristique (pour trouver la meilleur … ou la moins pire) basé sur l’algorithme de RETE. Le résultat est une planification qui n’est pas parfaite mais qui est optimisé à un point qu’un humain aurais été incapable de faire (même si l’algorithme du “bon sens” n’existant pas, l’être humain peut parfois simplement optimiser encore le résultat obtenu …) . Pour éviter de dire trop de bétise (j’espère ne pas avoir fait d’erreur jusqu’ici), je ne vais pas m’étaler plus.

Pour conclure: une conférence de très haut niveau technique et très intéressant.

Ch’ti JUG: HTML5: WebSocket et autres protocole de communication

Dimanche 13 décembre 2009
Jeudi s’est tenu dans les locaux d’ADEO une session du Ch’ti Jug sur HTML5 et tout particulièrement les WebSockets: Kaazing HTML5 WebSocket Talk at the Ch’ti JUG Meeting in Lille, France

Pour ceux qui ne savent pas ce qu’est le Ch’ti Jug ou ce qu’est un Jug, voir l’introduction de mon article sur la session précédente:  Ch’ti Jug: les technologies Google

Une petite phrase de notre hôte, le groupe ADEO, qui rassemble entre autre les enseigne Leroy Merlin et Weldom. C’est donc ce qu’on appel dans le jargon des SSII un “client final”, et c’est la premièer fois qu’une session du JUG se tient chez un client final. Le responsable des developpement de chez ADEO qui nous a reçu (je ne me rappel plus de son nom ni de sa fonction exacte) nous as expliquer la démarche très simple et que beaucoup d’autre client finaux (ou DSI) devrait mettre en place. Il fait en sorte que ses équipes de développement s’organisent en communauté pour partager leur savoir et progresser ensemble. Et c’est dans cette optique qu’il trouve tout naturel de supporter les communautés extérieures qui permettent à ses équipes de prolonger en dehors du bureau leur esprit de communauté et de continuer à grandir dans leur travail (là je trouve que je l’ai presque aussi bien dit que lui:) ).

Bon, après cette longue digression, venons en a la présentation elle même. Elle été assuré par Peter Lubbers de chez Kaazing, qui été de passage à Paris pour une formation et as accepté de venir faire un tour dans le nord avant de repartir dans la Silicon Valley. Et ce qu’on peut dire c’est que la présentation été de grande qualité, digne des grandes conférences payantes de la communauté Java.

Pour commencer, Peter nous as exposé le problème, à grand renfort d’exemple et de démo: aujourd’hui de plus en plus d’applications web riche (RIA, Rich Web Application) nécessitent une communication temps réelle (ou quasi temps réelle). Les protocoles web existants ne sont pas capable de faire ça, ils sont basé sur HTTP qui ne permet qu’une communication half-duplexe (soit montante: une request, soit descendante: une response, mais pas les deux en même temps).
Il existe donc différents patterns de développement pour la mise en place de solution pour que les RIA puisse s’approcher le plus possible d’une communication temps réelle. Je ne vais pas vous les présenter tous en détail mais il sont basé sur ce qu’on appel le polling (normal ou long polling) et ils souffrent tous de trois choses:

  1. Limitation d’une communication half-duplex: une request est obligatoire avant toute response, le serveur ne peut pas envoyer de données sans qu’une request ai été initié au préalable.
  2. La communication temps réelle nécessite des mise à jours constante qui nécessite de nombreuses request/response en un laps de temps très court. Le protocole HTTP comprend des en-tête qui dans ce cas d’utilisation particulier peuvent être importante. La taille d’une en-tête HTTP standard étant de 500 à 2000 octets, dans le cas d’un polling vers 10 000 clients toutes les secondes basé sur une taille d’en-tête de 1K on a 200Ko/s (10 000 * 1Ko * 2, une entête pour la request et une pour la response) de bande passante prise uniquement pour les en-tête. Et si on calcul pour 100000 client avec un polling de 200ms (plus cohérent pour donner une impression de temps réel) ça nous donne 10Mo/s de bande passante uniquement pour les entêtes!
  3. Le browser ne pouvant accéder qu’a un serveur HTTP, on a nécessité de déployer un serveur d’application ou autre composant complexe pour réaliser ce polling.

Et voila la solution, les WebSockets. Ils permettent de se passer de tout ces problèmes, en voici le mécanisme, dans une explication simplifié:

  1. Le browser demande un upgrade de la connexion HTTP en web socket.
  2. Le serveur accèpte, la connexion HTTP devient un WebSocket vers le serveur: c’est un nouveau protocole directement au dessus de TCP.
  3. La communication s’effectue alors en full-duplexe: request et response sont maintenant indépendante et peuvent être émise en même temps. Ce qui ouvre la possibilité d’une réel push data vers le serveur.
  4. Les headers d’une request/response WebSocket sont minimum: 1 octet de début et un octet de fin! La bande passante ne sert donc uniquement qu’aux données!

On peut même imaginer faire directement communiquer un serveur de type JMS, Jabber ou autre directement avec un WebSocket sans passer par HTTP.

De plus, l’établissement d’une websocket est très facile, via JavaScript on fait juste initialise juste un objet websocket en lui passant l’URL (de type ws://hote:port/uri, websocket étant un réel protocole il a son propre addressage) et la méthode javascript à appeler en callback lors de la réception de la requête: WebSocket étant asynchrone.

Les possibilité sont grande pour tout ce qui nécessite des connexion de type temps réelle.

Peter Lubbers nous as ensuite présenté quelques autres nouveautés d’HTML5 accès sur la communications telle que:

  • L’XmtlHttpRequest Level 2: XmlHttpRequest cross domaine (avec mécanisme de sécurisation)
  • La communication cross domaine entre iframe (avec mécanisme de sécurisation)
  • Les PostEvents
  • Et bien d’autres choses …

Tout ça est bien beau, mais pour l’instant, seul les nighly builds de chrome (projet chromium) supportent ces nouveautés (et normalement la future version de Firefox, la 3.6, les supportera). En attendant: Kaazing a une solution:
Kaazing a créer une framework qui permet d’utiliser ces nouveauté, et si le browser ne le supportent pas nativement il va les émuler en utilisant soit un plugin du browser (flash, ActiveX, …) soit du JavaScript au mieux de ce que supporte le browser.
En plus, la société propose une passerelle qui permet d’accéder directement à une multitude de protocoles directement depuis des websocket sans passer par un serveur applicatif, en gros il permet de faire passerelle entre le protocole websocket et des protocoles telle que JMS ou Jabber. Allez sur le site de Kaazing si vous cherchez à en savoir plus.

Voila une conférences très complète sur le sujet et de grande qualité. Merci Peter et merci le Ch’ti Jug!

Ch’ti Jug: les technologies Google

Mercredi 11 novembre 2009

Hello, Lundi j’ai été à la session du Ch’ti Jug sur les technologies Google qui s’est passé à l’ISEN et était sponsorisée par SII. C’était la première fois que j’assistais à un évènement organisé par le Ch’ti Jug et comme c’était intéressant, j’aimerais partager avec vous là dessus.

Ch’ti Jug? Kezako? Pour ceux qui ne savent pas, un JUG est un groupe dont le but est d’échanger sur les technologies Java. JUG = Java User Group. il existe de nombreux groupe disséminé partout dans le monde, ils sont reconnu par SUN mais totalement indépendant. Pour plus d’information aller voir la page suivante sur le site de SUN: http://java.sun.com/community/usergroups/ .Le Ch’ti JUG est un JUG Lillois créé il y a quelques mois qui propose des session gratuite ouverte à tous autour des technologies Java.

La session sur les technologies Google s’est donc déroulée dans un amphi de l’ISEN rénové dernièrement et il faut l’avouer très bien fait pour ce type d’évènement. Après les mots d’introduction des JUG leader et de SII, voici la présentation qui commence réellement. L’intervenant était Didier GIRARD du Groupe SFEIR, après une introduction assez rapide (voir parfois assez vulgarisé et imprécise) sur le Cloud Computing et REST (si vous voulez en savoir plus sur REST, vous pouvez lire mon article à ce sujet ici: REST – Architecture Orientée Ressource), il a exposé sa vision de la stratégie de Google. Cette partie étant clairement la moins intéressante et faisant un peu “campagne de pub” pour Google … ce qui est normal, SFEIR étant spécialisé dans les technos Google.

Enfin, voici la partie intéressante: la présentation des différentes technologies de Google, comprenant de nombreuses démos faites depuis l’IDE Eclipse:

  • AppEngine: un mode d’hébergement “dans le Cloud” de Google qui permet de déployer gratuitement (!!!) ou presque des applications Java. Le conteneur est basé sur Jetty, c’est donc un simple conteneur de Servlet. Le principe est que tout le monde peut déployer des applications sur AppEngine gratuitement tant que l’application ne dépasse pas les cotas de base, après cela il faut payer. Basiquement les cotas sont à 5 millions de page vue par jour (il y a aussi des cotas plus complexe sur la bande passante, la charge, …). Très pratique pour du développement ou de la mise en production de petite application “personnelle”.  L’offre est couplé à une base de données propriétaire Google BigTable qui a la spécificité de ne pas être relationnelle. Cette base de données fait partie de ce que l’on appel le mouvement NoSql.
  • GWT: je ne connais pas encore très bien GWT mais en gros c’est la solution RIA de Google, le concurrent de Flex ou JavaFX. C’est une solution open source sur laquelle est basée de nombreux site de Google donc Wave dont je parlerais d’ici quelques lignes. Le principe est que le développeur code en Java et qu’un compilateur va transformer le tout en JavaScript pour l’exécution. GWT comprend de nombreux composants graphique tout fait, un exécuteur de test avant la compilation qui permet de tester et déboguer l’application sans la compiler (une compilation en JavaScript peut être très longues). Une démo classique d’un HelloWorld nous as été faites, pour finir le speaker a lâcher un “et on peut facilement l’héberger sous GWT” ce à quoi l’assemblé a répondu “allez-y”! Le défi est lancé, après une petite hésitation il a tenté et … réussit: Bravo! Déploiement réalisé en un click (après la configuration du compte appEngine) sans redémarrage du serveur (encore heureux, il est chez Google …).
  • Android: encore une démo d’un HelloWorld réalisé avec un plugin Eclipse :) Apparement aussi facile à développer qu’une application Java standard. Il faut juste utiliser l’API d’Android en plus de celle de Java. Le plugin Eclipse comprend un émulateur sur lequel on peut facilement tester son application. Après cela, le speaker a déployer en un click depuis. Eclipse l’application sur Android Market, s’y est connecté, à remplit deux-trois champs et … elle été disponible immédiatement pour les heureux possesseurs d’Android dans la salle. Impressionnant!
  • Wave: le petit dernier de chez Google: Wave. Au premier abord je n’ai pas trop vu l’intérêt de ce truc. Un collègue, et je l’en remercie, m’en a donné une invitation (il est en preview et donc uniquement accessible via invitation pour l’instant). Wave se veut une nouvelle manière de communiquer et de collaborer via l’utilisation de wave qui remplace en même temps: le mail, la messagerie instantané, google apps, igoogle, un forum, … Lorsque l’on créée une wave, on invite ses contacts à y participer ils peuvent alors voir en temps réel ce que l’on est en train de taper, y participer, coller des photos, des vidéos, ajouter des gadget (de type iGoogle). Les possibilité de collaboration sont impressionnante grâce à une synchronisation du texte lors de la frappe a la lettre prêt! Et l’algorithme de synchronisation (inspiré d’un algorithme développé par une des plus grande université mondiale …) ne se trompe paraît-il jamais et permet à deux personne de travailler en même temps sur le même texte! Les possibilité semble grande, on verra bien ce que ça donnera … Comme j’en ai un compte, je ne résiste pas, voici un petit screenshot :)
Google Wave

Google Wave

Pour terminer, nous avons eu droit à une petite présentation suivie d’une démo sur l’avenir de GWT: GWT2 et ses nouvelles fonctionnalités. Deux m’on marqué et sons à mon sens les plus intéressante de cette future version:

  • La possibilité de tester et déboguer l’application dans n’importe quel navigateur. GWT contient un mode de test “sans compilation”, auparavant celui-ci été disponible que depuis un browser embarqué dans le plugin de l’IDE. Maintenant, il est accessible depuis n’importe quel browser via une URL.
  • La possibilité d’utiliser des templates HTML pour des composants GWT. Vous pouvez ainsi en partie maitriser l’HTML généré par GWT, et le travail avec les designer s’en trouve facilité. Hélas cette fonctionnalité n’a pas été poussé assez loin à mon avis, car elle est basé sur un mix d’XML et d’HTML qui templétise juste un composant GWT et pas l’intégralité de la fenêtre. J’aurais préféré de loin l’implémentation excellente des templates HTML de Wicket …

Globalement, bien que longue (plus de 2h30), la présentation été très intéressantes. Et elle s’est terminée par un buffet de grande qualité (avec plein de petits gâteau aux chocolat … un de mes points faible) et avec de la bonne bière Chti :)

Implementer une architecture de service web RESTfull avec Restlet et son extention Spring

Jeudi 10 septembre 2009

Cet article fait suite mon article REST – Architecture Orientée Ressource en lui donnant une implémentation basé sur le framework Restlet.

Le principe de Restlet :

Restlet est un framework Java 5.0 qui obéit aux standard RESTful et permet de créer facilement des application RESTful. Il remplace la spécification J2EE par une API orientée REST : on développe des Restlet au lieu de développer des Servlet.

Il existe deux composant principaux:

  • Router : permet de router une requête HTTP vers une ressource.
  • Resource : la ressource REST d’un objet, une ressource permet plusieurs représentations différentes.
  • Représentation: la représentation visuelle de la ressource.

Dans cet exemple, je vais utiliser Velocity pour créer des représentation XML et XHTML et l’extension Spring de Restlet qui permet de définir un Router directement dans les fichier de configuration des beans de Spring et de faire de l’injection dans les classes de Resource.

Le fichier de configuration Spring :

C’est la base de l’utilisation de Restlet avec Spring, voici un exemple de fichier définissant un routeur et des ressources. Le routeur est définit par une map dont les entrée ont comme clé le pattern d’URL (les paramètres sont entre {}) et en valeur la ressource (dont le bean est localisé via le SpringFinder, pour assurer la création d’une ressource différente à chaque requête).
Il faut bien faire attention au fait qu’une resource soit de type ‘prototype’.

<bean id="/catalog" name="/catalog" class="org.restlet.ext.spring.SpringRouter">
    <property name="attachments">
        <map>
            <!--  product resource -->
            <entry key="/v{versionNumber}/product/{dcrName}.{language}.{representationType}">
                <bean class="org.restlet.ext.spring.SpringFinder">
                    <lookup-method name="createResource" bean="catalog.productResource"/>
                </bean>
            </entry>
            <entry key="/v{versionNumber}/product/{dcrName}/{format}.{language}.{representationType}">
                <bean class="org.restlet.ext.spring.SpringFinder">
                    <lookup-method name="createResource" bean="catalog.productResource"/>
                </bean>
            </entry>
            <!--  category resource -->
            <entry key="/v{versionNumber}/category/{catName}.{language}.{representationType}">
                <bean class="org.restlet.ext.spring.SpringFinder">
                    <lookup-method name="createResource" bean="catalog.categoryResource"/>
                </bean>
            </entry>
        </map>
    </property>
</bean>
<bean id="catalog.productResource" class="com.loicmathieu.resource.catalog.ProductResource"
        scope="prototype" parent="baseResource">
    <property name="modifiable" value="false"/>
    <property name="productService" ref="ProductService"/>
</bean>
<bean id="catalog.categoryResource" class="com.loicmathieu.resource.catalog.CategoryResource"
        scope="prototype" parent="baseResource">
    <property name="modifiable" value="false"/>
    <property name="categoryService" ref="CategoryService"/>
</bean>

J’utilise ici une BaseResource comme parent à toutes mes ressources (ce qui explique le parent=”baseResource”, à ne pas mettre si vous ne créez pas de base ressource)
, celle-ci contient du code commun à toutes mes ressources pour gérer la langue, le numéro de version, les différentes représentation… Je vous conseil de faire de même en fonction de ce que vous voulez réaliser.

On peut remarquer que j’ai mappé deux URL vers la ressource product, c’est tout à fait possible. Je vous donnerais plus tard un exemple d’utilisation.

La classe org.restlet.resource.Resource

C’est la classe de base d’une ressource, voici les principales méthodes qu’il faut surcharger pour écrire vos propre ressources:

  1. onInit(): lire les paramètres de la request
  2. represent(Variant v):  pour la méthode http ‘GET‘: récupération d’une ressource
  3. removeRepresentation(): pour la méthode http ‘DELETE‘: suppression d’une ressource
  4. acceptRepresentation (): pour la méthode http ‘POST‘: création d’une nouvelle ressource
  5. storeRepresentation(): pour la méthode http ‘PUT‘: modification d’une ressource existante

Exemple: la classe ProductResource

/**
 * @author Loïc Mathieu
 */
public class ProductResource extends BaseResource {
    // request parameters
    private String productName;
    private String format;

    // IoC parameter
    private ProductService productService;

     //IoC Setter
    public void setProductService(ProductService productService) {
        this.productService = productService;
    }

    @Override protected void onInit(Context context, Request request, Response response) {
        productName = (String) request.getAttributes().get("productName");
        format = (String) request.getAttributes().get("format");
    }

    @Override public Representation represent(Variant variant) throws ResourceException {
        Product product = productService.findProductByName(productName);

        // select the desired template
        String velocityTpl = "catalog.product.vm"";
            if (format != null && "small".equals(format)) {
            velocityTpl = "catalog.product.small.vm";
        }

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("product", product);

        switch (getExtension()) {
            case HTML:
                return new VelocityRepresentation(velocityTpl, data, getExtension().getMediaType());
            case XML:
                StringRepresentation sr = new StringRepresentation(product.getXmlRepresentation(), getExtension().getMediaType());
                return new DomRepresentation(sr);
            case TXT:
                return new StringRepresentation(product.getDisplayName());
            default:
                throw new RessourceException(Status.CLIENT_ERROR_BAD_REQUEST,
                        "a problem occured, please contact the administrator.",
                        " Unable to find a representation of type: " + getExtension());
        }
    }
}

Ce qu’il faut remarquer dans ce code source:

  • ligne 18 et 19: lecture des paramètre depuis la requête
  • ligne 26: celons la valeur du paramètre format j’utilise des templates Velocity différent
  • ligne 34: je switch sur l’extension de la ressource (la classe Extension est une enum qui lie .txt -> Extension.TXT, .html -> Extention.html, … Et qui est calculé dans ma base resource)
  • Pour chaque type d’extension, je génère un type de représentation différent
    • HTML: une représentation VelocityRepresentation qui utilise un template Velocity pour créer l’HTML. VelocityRepresentation est une sous classe de TemplateRepresentation qui facilite l’utilisation de Velocity. J’en donne l’implémentation plus bas.
    • TXT: une StringReprésentation
    • XML: pour plus de facilité je présume qu’un produit peut créer son propre XML. J’utilise ensuite une DomRepresentation.
    • ligne 42: très important, si l’extension n’est pas de type supporté pour la ressource, alors je lance une exception qui contient un code d’erreur HTTP. Ici une 400 Bad Request.

La classe VelocityRepresentation:

/**
 * @author Loïc Mathieu - LBI
 */
public class VelocityRepresentation extends TemplateRepresentation {

    public VelocityRepresentation(String templateName, Map<String, Object> dataModel, MediaType mediaType) {
        super(templateName, dataModel, mediaType);
        configureEngine();
    }

    public VelocityRepresentation(String templateName, MediaType mediaType) {
        super(templateName, mediaType);
        configureEngine();
    }

    /**
     * This method sets some configuration properties to the VelocityEngine.
     */
    protected void configureEngine() {
        getEngine().setProperty(RuntimeConstants.RESOURCE_LOADER, "class");
        getEngine().setProperty("class.resource.loader.class",
                "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
        getEngine().setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, new Log4JLogChute());
        getEngine().setProperty(Log4JLogChute.RUNTIME_LOG_LOG4J_LOGGER, "ELNINO");
    }
}

Utilisation de l’HTTP Component

Restlet peut utiliser un composant HTTP basique, très léger et très rapide qui permet de tester facilement une application, il peut aussi être utilisé en production bien que pour ma part je déploie l’application sur un serveur WebSphere en production donc je ne peut vous donner du feedback sur une utilisation en production.

<bean id="restletComponent" class="org.restlet.ext.spring.SpringComponent">
    <property name="server">
        <bean class="org.restlet.ext.spring.SpringServer">
            <constructor-arg value="http" />
            <constructor-arg value="3001" />
        </bean>
    </property>
    <property name="defaultTarget" ref="defaultRouter" />
</bean>

<bean id="defaultRouter" class="org.restlet.ext.spring.SpringRouter">
    <property name="attachments">
        <map>
            <entry key="/catalog">
                <bean class="org.restlet.ext.spring.SpringRouter" ref="/catalog"" />
            </entry>
        </map>
    </property>
</bean>

Ici, on définit un SpringComponent qui sera un serveur HTTP qui servira les ressource. Celui-ci a comme routeur par défaut un SpringRouter qui contient en unique attachement notre routeur de catalog. Mais on pourrais lui ajouter d’autre routeur pour définir un ensemble de ressources.

Il ne nous reste plus qu’à faire une classe java dont le main va charger nos fichier Spring, rechercher le bin du SpringComponent et le démarrer.

On accédera ensuite à l’application via une URL du type: http://localhost:3001/catalog/product/monProduct.en.html

Deployement comme une servlet

On peut aussi facillement inclure notre application restlet dans une servlet. Pour ceci il faut utiliser la RestletFrameworkServlet de l’extension Spring dans notre web.xml comme ci-dessous

<!-- Restlet adapter -->
<servlet>
    <servlet-name>api</servlet-name>
    <servlet-class>com.noelios.restlet.ext.spring.RestletFrameworkServlet</servlet-class>
    <init-param>
        <param-name>targetRestletBeanName</param-name>
        <param-value>restletApplication</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
     <servlet-name>api</servlet-name>
     <url-pattern>/*</url-pattern>
 </servlet-mapping>

Puis définir un context pour notre servlet qui va définir une application restlet qui utilisera, comme notre http component précédent, le défault routeur.

<bean id="restletApplication" class="org.restlet.Application">
    <property name="root" ref="defaultRouter" />
</bean>

<bean id="defaultRouter" class="org.restlet.ext.spring.SpringRouter">
    <property name="attachments">
        <map>
            <entry key="/catalog">
                <bean class="org.restlet.ext.spring.SpringRouter" ref="/catalog"" />
            </entry>
        </map>
    </property>
</bean>

On accédera ensuite à l’application via une URL du type: http://localhost:8080/<webContext>catalog/product/monProduct.en.html où webContext est le context du WAR de votre application.

J’espère que ceci vous aura montrer toute la puissance de Restlet et de son extension Spring. Le code montré ici est un exemple non fonctionnel tiré du code que j’ai créée pour ma société et qui tourne en production depuis plus d’un an.

Source des exemples

catalog-ctx.xml
ProductResource.java
VelocityRepresentation.java
restletComponent-ctx.xml
web.xml
api-servelt.xml

Sixième sens – Une interface homme-machine révolutionaire

Vendredi 28 août 2009

Qui n’a jamais rêvé de l’interface homme-machine de Minority Report?
En tout cas,moi, j’ai toujours été fasciné par ce passage.

Et bien, j’ai trouvé encore mieux, moins chère … et réel. Des chercheurs du MIT travaillent sur une interface basé sur une webcam ordinaire, un téléphone projecteur et … des bouts de scotch de couleurs sur les doigts (moins cher qu’un gants d’interface virtuel et moins encombrant … dans la vidéo ils disent plus jolie mais bon, ça, je vous laisse juger par vous même). Le projecteur du téléphone portable projette sur les objets et les personnes en face de vous des informations que vous pouvez ‘cliquer’ et manipuler avec vos doigts.

Personnellement je trouve ça révolutionnaire! Imaginez, pour moins de 400$ de matos tout ce que ça peut faire. Regardez la vidéo et vous comprendrez: http://www.pranavmistry.com/projects/sixthsense/#VIDEOS

L’équivalent gratuit (et le plus souvent open source) aux logiciel que j’utilisais

Vendredi 3 avril 2009

Changeant la plupart des pièces de mon ordinateur, je suis obligé de réinstaller le système d’exploitation. Je me suis dit, à la place de réinstaller mes vieux logiciels habituel (qui sont pour beaucoup, payant), pourquoi ne pas essayer de trouver des équivalent gratuit, et même open source (l’un ne voulant pas dire l’autre) à ces logiciel?

Je me souvenais avoir mis en bookmark quelque part un article qui donnait une liste de logiciel open source, je commence donc pas ceux de cette liste: http://whdb.com/2008/the-top-50-proprietary-programs-that-drive-you-crazy-and-their-open-source-alternatives/, puis compléterais par des recherches sur le net. (j’inclurais aussi dans la liste les logiciels gratuit et open source que j’utilise déjà, car je n’utilise pas que des logiciels payant, je ne suis pas Crésus!)

Voici la liste, elle n’est pas réellement ordonnée, je la donne dans l’ordre dans laquelle j’ai effectuer mes recherches, je ferrais certainement des mises à jours régulières pour ajouter de nouveau logiciel au fur et à mesure de leur découverte.

  1. Kompozer (dérivé de NVU) au lieu de Dreamweaver
  2. OpenOffice au lieu de Microsoft Office
  3. Picassa 3 au lieu de ACDSee ou Lightroom
  4. Ant Movie Catalog: pour gérer votre liste de DvD
  5. Firefox au lieu d’Internet Explorer
  6. Thunderbird au lieu de Outlook
  7. Notepad++ au lieu de Ultraedit
  8. 7-Zip au lieu de winzip ou winrar
  9. Ultrabackup au lieu de syncback
  10. Antivir au lieu de Norton Antivirus
  11. ImgBurn au lieu de Nero
  12. Gimp au lieu de Photoshop
  13. VLC Media Player pour lire vos vidéo, DVD, MP3, Streaming, … Remplacera sans problème un lecteur de DvD comme PowerDVD ou un lecteur de média comme Windows Media Player.
  14. XMind au lieu de MindMap, logiciel de “collaborative mind” permettant de créer des graphiques collaboratif (il peut remplacer aussi certaines utilisations de Microsoft Visio).

Et bien sur, pour ceux qui voudrait aller plus loin, il y a aussi Ubuntu, une distribution Linux facile d’accès et avec une grande communauté francophone qui peut avantageusement remplacer Windows (personnellement, je l’ai mis en double boot avec Windows sur mon portable, et je l’utilise régulièrement).

Voila, n’hésitez pas, ça ne coute rien et parfois, après, on ne peut plus s’en passer tellement ces logiciels sont simple d’utilisation et performant …