IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JDBC Java Discussion :

Concept d'application réactive dans une application de gestion en Java et classe ORM de gestion de données


Sujet :

JDBC Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Inscrit en
    Février 2006
    Messages
    707
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 707
    Par défaut Concept d'application réactive dans une application de gestion en Java et classe ORM de gestion de données
    Bonjour,

    Peut-être connaissez-vous le podcast nipdev de la communauté niptech. Je l'ai découvert sur ituns.

    Dans ce cadre là, j'ai entendu parlé d'application réactive.

    Voici le lien pour ceux que ça intéresse.

    Épisode consacré aux applications réactives.

    http://nipcast.com/nipdev-13-les-app...ons-reactives/

    podcast nipdev

    http://nipcast.com/category/nipdev/

    Ce concept m'a l'aire assez séduisant et semble aller plus loin que le multi threding ou la gestion d'événement.

    Formé en java, je pensait appliquer une partie de ces concept dans ma prochaine application de gestion de facturation de rendez-vous ou encore dans mon une prochaine version de mon application de gestion d'un commerce d'abricot.

    Questions

    Le fait d'utiliser des api de type réactive application, est-ce une manière d'optimiser le programme ?

    A propos, d'optimisation, on m'a conseiller de profiler mon programme mais comment faire ça le plus simplement dans la dernière version d'eclipse ?

    Je prévoyait aussi utiliser un système de classe ORM pour gérer la base de donnée. Une classe par table.

    Mais en fait quelles sont les avantages et inconvénients de tout ça ?

    Merci de me répondre.

    S'ils fréquentent ce forum, je salue bien Fabrice oiseau ainsi que toute la communauté nipdev.et je les remercie pour ce sujet très intéressants.Je l'invite aussi à me répondre.

    Salutations à tous,

  2. #2
    Membre très actif
    Inscrit en
    Février 2006
    Messages
    707
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 707
    Par défaut Java et les applications réactives.
    Bonjour,

    Voici un résumé de ce que j'ai trouvé au sujet des applications réactivent

    http://nipcast.com/nipdev-13-les-app...ons-reactives/


    Spécialisent java, je ne suis pas formé en scala. Il semble toutefois qu'il s'agit d'un mélange entre python et java un peu comme jython.

    Puis-je faire des applications réactive avec akka en utilisant java ou faut-il utiliser Rex


    http://github.com/Netflix/RxJava

    Est-ce que quelqu'un a déjà utiliser cet api.

    Est-ce simple ?

    où trouver des exemples ?

    Merci de me répondre

    Salutations

  3. #3
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2006
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2006
    Messages : 70
    Par défaut
    L'application réactive est avant tout un paradigme (qui n'a rien de nouveau d'ailleurs), aussi il n'est pas spécialement lié à un framework.

    Il est tout à fait possible de faire du réactif avec du Java "de base".
    A mon sens, il a deux avantages :
    - diminuer le nombre de thread (1 thread = 1 tâche est une manière de faire complètement obsolète)
    - Obtenir des applications en temps réel relatif. C'est à dire qu'on ne peut pas assurer que la réponse sera obtenue en moins de x millisecondes, mais qu'elle sera traitée au plus tôt.

    Pour la gestion des threads, je prendrais l'exemple des socket.

    En java, les "Socket" sont bloquant. Créer un serveur avec des Socket de base nécessite de faire 1 thread par client connecté. Avec java.nio on peut passer par des Selector : un objet qui retourne uniquement les sockets ayant quelque chose à faire : un seul et unique thread estalors nécéssaire, quelque soit le nombre de client.

    Avec JEE, les serveurs d'applications utilisent déjà ces outils. Le serveur dispose alors d'un pool de thread (un petit nombre, quelques dizaines grand maximum). Chaque nouvelle requète sera traité par un thread libre du pool.
    Il faut donc voir les appels de nos EJB, Servlet... comme des évènements. Ce qui signifie aussi que ces évènements doivnet être très court : si tous les thread du pool sont utilisés, les autres "évènements" (les autres requètes HTTP) seront mise en attente.

    L'idée est donc de découper un traitement de requête en plusieurs traitement, pouvant être parallélisé :
    - soit les traitement peuvent d'exécuter en parallèle
    - soit les traitements sont séquentiels; à ce moment chaque traitement bloquant (ex: utilisation de la base de données) sera traité par un nouveau thread. Le thread appelant pouvant alors être "libéré"; c'est à dire qu'il va pouvoir se terminer rapidement, afin de traiter une nouvelle requète.

    Les dernières version de JEE gèrent les appel de bean dans d'autres thread par le biais de l'annotation @Asynchronous, et du retour de méthode avec l'objet Future<>. Ont peut également créer des pool de thread directement dans le serveur d'application (comme une connexion à une base de données) que l'on récupère dans notre programme avec JNDI, et les annotations de types @Resource


    La véritable difficulté technique il me semble, et de créer un callback de retour d'information asynchrone sur le client. Si le client est une page web, utilisant javascript et Ajax, le callback de retour sera celui de la requète HTTP. Or, si le serveur traite la requète par plusieurs thread consécutif, le retour du premier appel sera certes très rapide (le serveur ne gardant pas la mail, et délègue le traitement), mais la réponse ne sera tout simplement pas prête !

    Il faudrait donc faire des requêtes à interval régulière, pour savoir si la réponse est prête. En plus d'être peu performant, il est alors nécessaire de distinguer chaque couple requète/réponse par un système d'ID : si une réponse est prête, il faut se souvenir de quelle requête elle est issue.


    Le moyen le plus performant à mon avis reste les websocket : les requètes / réponses sont envoyées et reçus immédiatement par un "flux", et non par des multitudes de requêtes.
    De plus, les flux de données sont particulièrement adaptés aux applications réactives : si la réponse contient des centaines de résultats, sans liens spécifiques entre entre eux, on peut commencer à renvoyer les premiers résultats générés, alors que le traitement coté serveur n'est pas encore terminé.

  4. #4
    Membre confirmé
    Homme Profil pro
    Expert MDE
    Inscrit en
    Janvier 2008
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Expert MDE
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2008
    Messages : 183
    Par défaut
    + 1 pour Websocket.

    Intra Appli, tu peux aussi utiliser du JMS et un concept de bus de message (tous les messages transitent par un et un seul broker, te permettant de monitorer le tout/greffer des traitements globaux.
    Chacun de ces messages, qu'ils soient JMS/Websocket sont transformés par par le broker pour être écouté par un protocole où l'autre (comme ça, pas d'ennui de conversion de message).
    Tu peux aussi utiliser des EIP ( patterns d'intégration d'entreprise) pour router tes messages (voir Apache Camel).

    Bref le but est de rester asynchrone sur toute ta stack: aux niveau des E/S (nio2/streams/Futures), services (JMS/STOMP over Websocket (ActiveMQ)), etc... Et de tout découpler en microservices autonomes et sans états (Stateless) pour augmenter les opportunités de parallèlisation et de réutilisabilité.

  5. #5
    Membre très actif
    Inscrit en
    Février 2006
    Messages
    707
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 707
    Par défaut Exemple d'un serveur de débogage
    Bonjour,

    Vous parlez de Serveur ça tombe bien puisque j'en ai un pour pouvoir charger de réceptionner les message qu'il soit d'erreur et autre d'un programme.

    Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
     
    package debugserver;
    import java.awt.*;
     
    import javax.swing.*;
     
    import abricotshopmanager.AbricoshopManager;
     
    import java.net.*;
    import java.io.*;
    import java.text.DateFormat;
    import java.util.*;
     
     
     
     
    public class Server {
      final static int PORT = 4321;
     
      static Socket service;
     
     
      public Server () { 
     
    	  init();
      }
     
     
     
     
      private void init() {
     
     
        	Dimension dimScrean = Toolkit.getDefaultToolkit().getScreenSize();
        	JFrame server = new JFrame("server");
        	server.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        	server.setSize(150,0);
        	// Mettre la fenêtre en bas à droite
        	server.setLocation(dimScrean.width - server.getWidth(),dimScrean.height - server.getHeight());
     
        	server.setVisible(true);
          // préparation du serveur
          // réseau
     
    	  try {
     
    	  ServerSocket ecoute = new ServerSocket(PORT);
     
    	  while (true) {
    	        service = ecoute.accept();
    	        Thread serviceThread = new Thread (new ServiceThread() );
    	        serviceThread.start();
    	        serviceThread.setName("connect thread");
    	      }      
     
     
          }
     
     
        catch (BindException be) {
        	System.err.println("Le serveur a quitter car un autre et déjà en utilisation");
        	System.exit(-1);
        }  
        catch (IOException ioe) {
          System.err.println(("Problème au niveau du serveur : "+ ioe.getMessage()) + "il est : "+formateDate() );
          ioe.printStackTrace();
        }
      }
     
     
     
     
     
    /**
     * Cette méthode créer et formate la date du jour
     @return String
     */
     static String formateDate() {
    	  TimeZone tz =  TimeZone.getTimeZone("Europe/Paris");
     
      Calendar calendar = Calendar.getInstance(tz);
      Date date = new Date();
          TimeZone.setDefault(TimeZone.getTimeZone("Europe/Paris"));
          calendar.setTime(date);
          DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, Locale.FRENCH);
     
    	return ("Report_"+df.format(date)+" "+calendar.get(Calendar.HOUR_OF_DAY)+'_'+calendar.get(Calendar.MINUTE)+'_'+ calendar.get(Calendar.SECOND)+".log").replace('/', '_');
     
     
    }
     
     
      public static void main (String [] args) {
        new Server();
      }
     
    }
    class ServiceThread implements Runnable {
     
    	public void run() {
    		// TODO Auto-generated method stub
    		 BufferedReader rd;
    		 String message;
    		 try {
    			 rd = new BufferedReader(new InputStreamReader(Server. service.
    			getInputStream()));
    			 System.out.println("Nouvelle connection à : "+Server.formateDate());
     
    			 while ( (message = rd.readLine()) != null) {
    				 writeInfile(message);
     
     
    	  }
    	} 
    		 catch (IOException ioe) {
    			 System.out.println("Le client a quitté : "+Server. formateDate());   
    			 if (! ioe.getMessage().contains("reset")) {
    				 System.err.println("L'erreur suivante s'est produite à  :"+Server.formateDate()+" \n le message est :"+ ioe.getMessage());
    				 ioe.printStackTrace();  
    		 	}
    		}
    	}
     
    	private synchronized void writeInfile (String message) {
    				 String messgage = null;
     
    				File fileErrorOutput = new File (Server.formateDate());
    				FileOutputStream fileError = null;
    				PrintStream fosErrorSender = null;
     
    		try {
    			fileError = new FileOutputStream(fileErrorOutput,true);
    			fosErrorSender = new PrintStream(fileErrorOutput);
     
    	          System.out.println(new String("Nouveau message  +" +
                          fileErrorOutput.getName()));
    fosErrorSender.println(message);
    System.out.println(message);
    fosErrorSender.flush();
    		}
    		catch (IOException ioe) {
    			System.err.println("Imposible d'écrire dans le fichier de log "+fileErrorOutput.getName() + "il est : "+formateDate() + "Message : "+ioe.getMessage());
    			ioe.printStackTrace();
    		}
     
    		finally {
    			try {
    				fosErrorSender.close();
     
    				fileError.close();
     
    				if (fileErrorOutput.length() == 0) { // aucune erreur n'est survenue
    					fileErrorOutput.delete();
    					System.out.println("Le fichier a été supprimé");
    					}
    				}
    			catch (FileNotFoundException fne) {
    				System.err.println("Le fichier : " + fileErrorOutput.getName() +" N'a pas été trouvé dans le répertoire du serveur.  Il est :" + Server.formateDate()+ "Message : "+fne.getMessage() );
    			}
    			catch (IOException ioe) {
    				System.err.println("Un problème est survenu lors de l'écriture dans le ficher : "+fileErrorOutput.getName());
    				ioe.getStackTrace();
    				}
    		}	
     
     
    	}
     
        public static String formateDate() {
      		  TimeZone tz =  TimeZone.getTimeZone("Europe/Paris");
     
      	  Calendar calendar = Calendar.getInstance(tz);
      	  java.util.Date date = new java.util.Date();
     
      	      TimeZone.setDefault(tz);
     
      	      calendar.setTime(date);
     
      	      DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, Locale.FRENCH);
      	      if (AbricoshopManager.isDebug()) {
      			   System.out.println("Retourner une date formatée.");
      		   }
     
      		return (df.format(date)+" "+calendar.get(Calendar.HOUR_OF_DAY)+'_'+calendar.get(Calendar.MINUTE)+'_'+ calendar.get(Calendar.SECOND));
     
     
      	}
    }
    Qu'est-ce que ce code vous inspire ?

    Comment peut-on modifier ce code pour le rendre ce code réacrtif.

    A mon avis, le principal problème ce situe au niveau des while (true)

    J'aurais voulus mettree des événement à la réception de lla requête du programme client.sachant que ce programme utilise le protocole tcp avec des streem et non des datagramepacket.


    Les deux code que j'aimerais mettre en événement ou réactif et que j'estime bloquant.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    	  ServerSocket ecoute = new ServerSocket(PORT);
     
    	  while (true) {
    	        service = ecoute.accept();
    	        Thread serviceThread = new Thread (new ServiceThread() );
    	        serviceThread.start();
    	        serviceThread.setName("connect thread");
    	      }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    			 while ( (message = rd.readLine()) != null) {
    Quel est votre avis là dessus ?

    Merci pour votre aide.

    Salutations

  6. #6
    Membre confirmé
    Homme Profil pro
    Expert MDE
    Inscrit en
    Janvier 2008
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Expert MDE
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2008
    Messages : 183
    Par défaut
    Re-,

    Pourquoi as-tu une architecture client/serveur sur une application locale? Dans le but d'en faire une distribuée à l'avenir?
    De même, je pense qu'il y a un souci de nommage, j'ai du mal à voir une JFrame côté serveur .

    Niveau socket, ce sont des opérations de très (très) bas niveau, ça irait pour un petit projet perso (mais du coup je vois mal l'intérêt de distribuer le tout).
    Il existe en Java des APIs de bien plus haut niveau: les Servlets (et notamment les Websockets, qui permettent l'asynchrone).
    Cela nécessite de faire tourner ton code serveur sur un conteneur de Servlet (type Tomcat, WildFly...).
    Si tu veux te lancer dans l'aventure, voici la documentation relative en utilisant le Spring framework (tu pourras trouver des exemples sur Spring un peu partout sur Internet): http://spring.io/guides/gs/messaging-stomp-websocket/.

    La même chose avec la norme JEE7: http://docs.oracle.com/javaee/7/tuto.../websocket.htm

  7. #7
    Membre très actif
    Inscrit en
    Février 2006
    Messages
    707
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 707
    Par défaut Serveur d'applications et application à fenêtre
    Bonjour,

    Il me faudrait pouvoir appeler les api du serveur d'application et l'utiliser pour une application swing à fenêtre. N'est-ce possible ?

    Pas ailleurs , Pour le serveur dont je vous ai montré le code, il s'agit d'une ébauche de serveur chargé d'afficher les messages de sortie des messages est des erreurs de mon programme. Existe-il quelque chose du genre en open source, JEE ou autre serveurs ?

    Merci de me répondre.

    Salutations



    Citation Envoyé par Sebajuste Voir le message
    L'application réactive est avant tout un paradigme (qui n'a rien de nouveau d'ailleurs), aussi il n'est pas spécialement lié à un framework.

    Il est tout à fait possible de faire du réactif avec du Java "de base".
    A mon sens, il a deux avantages :
    - diminuer le nombre de thread (1 thread = 1 tâche est une manière de faire complètement obsolète)
    - Obtenir des applications en temps réel relatif. C'est à dire qu'on ne peut pas assurer que la réponse sera obtenue en moins de x millisecondes, mais qu'elle sera traitée au plus tôt.

    Pour la gestion des threads, je prendrais l'exemple des socket.

    En java, les "Socket" sont bloquant. Créer un serveur avec des Socket de base nécessite de faire 1 thread par client connecté. Avec java.nio on peut passer par des Selector : un objet qui retourne uniquement les sockets ayant quelque chose à faire : un seul et unique thread estalors nécéssaire, quelque soit le nombre de client.

    Avec JEE, les serveurs d'applications utilisent déjà ces outils. Le serveur dispose alors d'un pool de thread (un petit nombre, quelques dizaines grand maximum). Chaque nouvelle requète sera traité par un thread libre du pool.
    Il faut donc voir les appels de nos EJB, Servlet... comme des évènements. Ce qui signifie aussi que ces évènements doivnet être très court : si tous les thread du pool sont utilisés, les autres "évènements" (les autres requètes HTTP) seront mise en attente.

    L'idée est donc de découper un traitement de requête en plusieurs traitement, pouvant être parallélisé :
    - soit les traitement peuvent d'exécuter en parallèle
    - soit les traitements sont séquentiels; à ce moment chaque traitement bloquant (ex: utilisation de la base de données) sera traité par un nouveau thread. Le thread appelant pouvant alors être "libéré"; c'est à dire qu'il va pouvoir se terminer rapidement, afin de traiter une nouvelle requète.

    Les dernières version de JEE gèrent les appel de bean dans d'autres thread par le biais de l'annotation @Asynchronous, et du retour de méthode avec l'objet Future<>. Ont peut également créer des pool de thread directement dans le serveur d'application (comme une connexion à une base de données) que l'on récupère dans notre programme avec JNDI, et les annotations de types @Resource


    La véritable difficulté technique il me semble, et de créer un callback de retour d'information asynchrone sur le client. Si le client est une page web, utilisant javascript et Ajax, le callback de retour sera celui de la requète HTTP. Or, si le serveur traite la requète par plusieurs thread consécutif, le retour du premier appel sera certes très rapide (le serveur ne gardant pas la mail, et délègue le traitement), mais la réponse ne sera tout simplement pas prête !

    Il faudrait donc faire des requêtes à interval régulière, pour savoir si la réponse est prête. En plus d'être peu performant, il est alors nécessaire de distinguer chaque couple requète/réponse par un système d'ID : si une réponse est prête, il faut se souvenir de quelle requête elle est issue.


    Le moyen le plus performant à mon avis reste les websocket : les requètes / réponses sont envoyées et reçus immédiatement par un "flux", et non par des multitudes de requêtes.
    De plus, les flux de données sont particulièrement adaptés aux applications réactives : si la réponse contient des centaines de résultats, sans liens spécifiques entre entre eux, on peut commencer à renvoyer les premiers résultats générés, alors que le traitement coté serveur n'est pas encore terminé.

  8. #8
    Membre confirmé
    Homme Profil pro
    Expert MDE
    Inscrit en
    Janvier 2008
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Expert MDE
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2008
    Messages : 183
    Par défaut
    Il me faudrait pouvoir appeler les api du serveur d'application et l'utiliser pour une application swing à fenêtre. N'est-ce possible?
    C'est exactement ce que tu vas faire. Par contre, ton client et ton serveur ne tournant pas sur la même JVM, il te faudra convertir ton message en quelque chose qui puisse transiter par les tuyaux. Tu as plusieurs choix:
    * RPC/RMI pour des appels "directs"
    * SOAP/REST qui passent par la couche http qui te permettent d'exposer ton API pour (potentiellement) d'autres clients (pas spécifiquement du point à point).

    Pas ailleurs , Pour le serveur dont je vous ai montré le code, il s'agit d'une ébauche de serveur chargé d'afficher les messages de sortie des messages est des erreurs de mon programme. Existe-il quelque chose du genre en open source, JEE ou autre serveurs ?
    Oui, ça s'appelle le logging: partout dans ton code tu vas enregistrer tes message via l'API standard de Logging (Slf4j), ce qui va centraliser les appels vers une API. cette API utilise un concept d'"appender" pour écrire, libre à toi de créer un appender de ton choix (fichier, sortie console, fenêtre swing...)

  9. #9
    Membre très actif
    Inscrit en
    Février 2006
    Messages
    707
    Détails du profil
    Informations forums :
    Inscription : Février 2006
    Messages : 707
    Par défaut Loggin et verbosité
    Bonjour,

    Dans les logiciels libre, j'ai souvent remarqué l'existence de l'option nervosité -v. Est-ce que vous voulez parler de ça dans votre message ?

    Merci de me répondre

    Salutations

Discussions similaires

  1. [Élaboration] Embarquer une application web dans une application cliente
    Par R1D3M4N dans le forum Architecture
    Réponses: 1
    Dernier message: 20/11/2010, 21h27
  2. Réponses: 1
    Dernier message: 20/02/2010, 19h38
  3. Réponses: 1
    Dernier message: 29/07/2009, 10h01
  4. Réponses: 2
    Dernier message: 15/10/2006, 18h01
  5. Réponses: 3
    Dernier message: 08/07/2006, 19h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo