Besoin de critiques sur une archi.

Besoin de critiques sur une archi. - Java - Programmation

Marsh Posté le 31-10-2006 à 08:19:35    

j'aurai besoin que les gurus qui traînent par là critiquent un peu les idées que j'ai pour une architecture d'application.
 
donc déjà, le besoin :  
Le produit est sensé permettre le transport et la transformation des flux de la boite. Potentiellement, toute application (quelque soit le langage) doit pouvoir envoyer un flux vers le produit pour demander théoriquement n'importe quoi. Le n'importe quoi doit avoir été implémenté par le produit quand même, c'est du genre transformation, regroupage, utilisation d'outils tiers sur le flux, sortie PDF, impression... Avec éventuellement une notion de priorité sur les flux, pour l'impression par exemple... Le flux d'entrée sera normalisé à terme, mais aujourd'hui il peut avoir n'importe quelle tête.
 
mes idées :  
puisque tout doit pouvoir parler, j'ai pensé à des points d'entrée multiples (webServices, API, Servlet...) qui normaliseraient le flux reçu (en attendant que les applications clientes le fassent elles-même) et l'enverrait vers un EJB Session (stateless ?) qui analyserait le flux pour voir quels sont les traitements à appliquer.  
Chaque traitement possible sera wrappé par un EJB Message (MDB) (gestion de la priorité) qui écouterai une file d'attente. Une file spécifique à chaque traitement donc.
Le sessionBean enverrait donc un message sur la file du traitement et attendrait une réponse dans un topic JMS. A la fin du traitement, le mdb posterai un message sur ce topic. Le topic étant commun à toutes les instances de session bean. Comme chaque flux est identifié, le bean vérifie si le message concerne sont flux, et passe au traitement suivant la cas échéant.  
 
et parce que sinon c'est pas drôle, je vous annonce que JMS et les EJB c'est tout nouveau pour moi, donc si c'est de la mouise, dites-le moi, merci d'avance.


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 31-10-2006 à 08:19:35   

Reply

Marsh Posté le 31-10-2006 à 09:01:04    

A priori tes idées sont bonnes mais tu t'es posé la question pourquoi tu voulais utiliser des EJB ?  
Essaye de regarder l'alternative Spring + ActiveMQ (ou MQ d'IBM) , tu peux implementer des trés sympatique MDP (message driven Pojo) , c'est leger, flexible car tu te fermes pas la porte car par la suite tu pourras wrapper tes mdp par des EJB ...
http://www.nofluffjuststuff.com/bl [...] emId=96149
 
Sinon si tu as des questions specifique je pourrais peut etre t'aider, vu que je bosse sur une appli d'integration entierement basé sur EJB/MQ

Reply

Marsh Posté le 31-10-2006 à 09:32:33    

Merci de ton avis éclairé.
 
je pensais mettre un ejb parce que je voulais attendre une réponse de mes mdb, et ça me semblais mieux comme ça.
 
Pour Spring, j'ai peur de rajouter une couche en plus, en j'avais regardé (rapidement) Spring il y a quelques temps, et ça me semblait pas mal abscons...


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 31-10-2006 à 09:53:03    

bon, ben ce que j'ai lu dans l'article que tu as linké est très simpa, ça semble intéressant. J'ai plus qu'à comprendre ce que sont l'injection de dépendances et AOP... et voir ce que Spring propose...


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 31-10-2006 à 10:05:58    

et hop une petite intro spring http://ego.developpez.com/spring/
 

Reply

Marsh Posté le 31-10-2006 à 10:07:59    

merci merci.
 
Mais bon, comme ça te semble pas être trop pourri (même si j'aimerai avoir d'autres avis, pour la route), je vais commencer par maquéter ce que je décrivais plus haut. Après, je recommencerai avec Spring, pour apprécier la différence.
 


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 31-10-2006 à 10:11:17    

oki, tu bosses avec quel serveur d'appli, JBoss ? et ton implémentation JMS tu a choisis quoi ? je te conseille ActiveMQ

Reply

Marsh Posté le 31-10-2006 à 10:23:02    

on est tout bleu ici, donc c'est IBM à fond. Le serveur est WebSphere 6.0 et j'essaie d'utiliser le moteur JMS inclus et de me passer de WebSphere MQ (MQ Series). En plus il faudrait que le tout soit valider (pareil pour Spring d'ailleurs, et même pour cette archi à base d'EJB).


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 31-10-2006 à 15:12:06    

hum... j'ai quelques soucis (évidemment) avec ce code là :

Code :
  1. public class TheSessionBeanBean implements SessionBean {
  2.  
  3.     private static final long serialVersionUID = 2531865006068619999L;
  4.  
  5.     private SessionContext sessionContext;
  6.  
  7.  
  8.     private Connection taskConnection;
  9.  
  10.     private Session taskSession;
  11.  
  12.     private MessageProducer taskSender;
  13.     
  14.  
  15.     private Session topicSession;
  16.     private MessageConsumer topicSubscriber;
  17.     private Connection topicConnection;
  18.  
  19.     private InitialContext initContext;
  20.     
  21.     public void ejbCreate() throws EJBException {
  22.         System.out.println("dans ejbCreate" );
  23.         try{
  24.         initContext = new InitialContext();
  25.         
  26.         ConnectionFactory taskFactory = (ConnectionFactory) initContext.lookup("jms/con/def" );
  27.         taskConnection = taskFactory.createConnection();
  28.         taskSession = taskConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
  29.         
  30.         ConnectionFactory topicFactory = (ConnectionFactory) initContext.lookup("jms/con/topic" );
  31.         topicConnection = topicFactory.createConnection();
  32.         topicSession =
  33.             topicConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
  34.         } catch (Throwable e) {
  35.             e.printStackTrace();
  36.         }
  37.         
  38.     }
  39.     public void ejbActivate() throws EJBException, RemoteException {
  40.         System.out.println("dans ejbActivate" );
  41.     }
  42.  
  43.     public void ejbPassivate() throws EJBException, RemoteException {
  44.         System.out.println("dans ejbPassivate" );
  45.     }
  46.  
  47.     public void ejbRemove() throws EJBException, RemoteException {
  48.         System.out.println("dans ejbRemove" );
  49.         try {
  50.             if (topicSubscriber != null) {
  51.                 topicSubscriber.close();
  52.             }
  53.             if (topicSession != null) {
  54.                 topicSession.close();
  55.             }
  56.             if (topicConnection != null) {
  57.                 topicConnection.close();
  58.             }
  59.             if (taskSender != null) {
  60.                 taskSender.close();
  61.             }
  62.             if (taskSession != null) {
  63.                 taskSession.close();
  64.             }
  65.             if (taskConnection != null) {
  66.                 taskConnection.close();
  67.             }
  68.             if (initContext != null) {
  69.                 initContext.close();
  70.             }
  71.         } catch (Throwable e) {
  72.             e.printStackTrace();
  73.         }
  74.     }
  75.  
  76.     public void setSessionContext(SessionContext arg0) throws EJBException, RemoteException {
  77.         System.out.println("dans setSessionContext" );
  78.         sessionContext = arg0;
  79.     }
  80.     public SessionContext getSessionContext() {
  81.         System.out.println("dans getSessionContext" );
  82.         return sessionContext;
  83.     }
  84.     
  85.     public String traiterFlux(String flux) {
  86.         try{
  87.             Destination destination = (Destination) initContext.lookup("jms/q/myListener" );
  88.             taskSender = taskSession.createProducer(destination);
  89.             taskSender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
  90.             taskSender.setTimeToLive(0);
  91.             taskConnection.start();
  92.             Message message = taskSession.createObjectMessage(new ModelBean("traite ça : "+flux));
  93.             taskSender.send(message);
  94.             
  95.  
  96.             Destination topic = (Destination) initContext.lookup("jms/topic/ordonnanceur" );
  97.             
  98.             topicSubscriber = topicSession.createConsumer(topic);
  99.             topicConnection.start();
  100.             Message reponse = topicSubscriber.receive();
  101.             if (reponse == null) {
  102.                 return "réponse null";
  103.             }
  104.             return ((TextMessage) reponse).getText();    
  105.         }
  106.          catch (Throwable e) {
  107.             e.printStackTrace();
  108.             return "problème";
  109.         }
  110.     }
  111. }


 
le mdb ne reçoit jamais de message suite à taskSender.send(message); et je fais un Message reponse = topicSubscriber.receive(10000), le mdb commence à travailler après la fin du traitement de l'EJB...
 
qu'est-ce que j'ai raté ?


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 31-10-2006 à 15:47:56    

il se passe rien du tout ou bien ca tre balance un stack trace ?

Reply

Marsh Posté le 31-10-2006 à 15:47:56   

Reply

Marsh Posté le 31-10-2006 à 16:02:58    

pas de stack trace, et pas d'appel j'ai mis un point d'arret dans onMessage...
 
chui en train de remanier la gestion des connexions, et accessoirement de les fermer proprement dans des blocks finally...


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 31-10-2006 à 16:11:09    

en fait, il me renvoie systématiquement "réponse null" et ensuite seulement il passe dans le mdb.
 
un problème de connexion/session ?!


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 31-10-2006 à 16:14:21    

Ouais surement, tu utilises WS MQ ? Tu vois pas ton message dans le MQ manager ?  
sinon dans la console d'admin de ws tu peux tester ta connexion JMS

Reply

Marsh Posté le 31-10-2006 à 16:17:41    

le problème c'est que individuellement, tout fonctionne. C'est uniquement quand je veux tout appeler que ça commence à faire n'imp...
 
Je peux poster dans le topic, dans la queue, je peux recevoir... mais poster dans la queue puis attendre une réponse dans le topic, pas poussib'


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 01-11-2006 à 00:54:27    

brisssou a écrit :

donc déjà, le besoin :  
Le produit est sensé permettre le transport et la transformation des flux de la boite. Potentiellement, toute application (quelque soit le langage) doit pouvoir envoyer un flux vers le produit pour demander théoriquement n'importe quoi. Le n'importe quoi doit avoir été implémenté par le produit quand même, c'est du genre transformation, regroupage, utilisation d'outils tiers sur le flux, sortie PDF, impression... Avec éventuellement une notion de priorité sur les flux, pour l'impression par exemple... Le flux d'entrée sera normalisé à terme, mais aujourd'hui il peut avoir n'importe quelle tête.


 
c'est pas un besoin, ça, c'est un fantasme de spec technique.


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 01-11-2006 à 09:05:35    

et pourtant...


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 01-11-2006 à 13:04:35    

pourtant ?
je pinaille juste sur le vocabulaire, hein, pas sur la faisabilité ou l'interet du truc ..


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 01-11-2006 à 16:32:50    

ah ok
 
bref, spec ou besoin, ça doit faire ça à la fin.
 
sinon, pas d'avis sur le reste ?


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 01-11-2006 à 19:29:50    

j'peux pas avoir d'avis valable sur une archi sans connaître les besoins [:spamafote]


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 01-11-2006 à 21:57:31    

euh... c'est ça le besoin, sérieux.
 
tu attends quoi toi ?


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 01-11-2006 à 23:30:15    

tu repasseras quand on saura pour quel secteur d'activité et pour quel service c'est :hello:

Reply

Marsh Posté le 02-11-2006 à 08:45:10    

disons qu'il n'y a pas de cible précise en fait. C'est sensé tout gérer. Tout doit pouvoir entrer, tout doit pouvoir sortir, et doit pouvoir appliquer n'importe quel traitement sur l'entrée pour fabriquer la sortie.
 
principalement, ça doit prendre en entrée un fichier de conf (flux de données), l'envoyer vers un moteur de composition (fabrication de documents) et les retourner en PDF. Mais ce n'est que la première tâche qui sera implémentée, ensuite, une ribambelle d'autre seront ajoutées, que l'on ne connait même pas aujourd'hui.


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 02-11-2006 à 09:03:13    

et ben commence par faire ça, et puis ton boss il reviendra quand il aura une nouvelle feature.


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 02-11-2006 à 09:05:50    

oui, mais le but c'est faire le dev en prévoyant d'implémenter plus tard toutes les features possibles et imaginables.
 
sinon, pour mes soucis d'envoi/réception, pas d'idées ?


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 02-11-2006 à 09:10:59    

brisssou a écrit :

oui, mais le but c'est faire le dev en prévoyant d'implémenter plus tard toutes les features possibles et imaginables.


KISS, YAGNI
 
Et surtout, n'oubliez pas que 51% des projets d'ERP atteignent soit le double du temps soit le double du budget soit les 2 par rapport aux estimations initiales. 30% des projets ERP sont abandonnés.
 
Quel est le rapport ? ben c'est typiquement le principe des projets ERP le "prévoyant d'implémenter plus tard toutes les features possibles et imaginables."


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 02-11-2006 à 09:59:52    

j'avais bien vu que c'était un truc du style, mais comme on a le temps et le budget, on se lance. Et java a été vendu à mes chefs comme étant la panacée universelle, donc bon...
 
et c'est plus que de la prévision, dans la deuxième boucle, on ajoutera des systèmes de tri des données, de regroupement, d'affranchissement... plein de trucs super cool quoi ([:mlc]). Résultat, j'essaye de voir comment pouvoir implémenter tout et rien à la fois, en gardant tout ça simple. Et je pense même avoir plus ou moins réussi, c'est pas si tordu que ça, si ?
 
bref, personne voit pourquoi je peux pas recevoir de message ? :D


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 02-11-2006 à 10:08:04    

tu peux montrer le code de ton mdb ?  
sinon t'as tester avec topicSubscriber.receiveNoWait() ?  
 

Reply

Marsh Posté le 02-11-2006 à 10:15:39    

receiveNoWait() renvoie null aussi, comme le mdb n'est pas appelé...
 

Code :
  1. package fr.test.jms;
  2.  
  3. import javax.ejb.EJBException;
  4. import javax.ejb.MessageDrivenBean;
  5. import javax.ejb.MessageDrivenContext;
  6. import javax.jms.Connection;
  7. import javax.jms.ConnectionFactory;
  8. import javax.jms.Destination;
  9. import javax.jms.Message;
  10. import javax.jms.MessageListener;
  11. import javax.jms.MessageProducer;
  12. import javax.jms.ObjectMessage;
  13. import javax.jms.Session;
  14. import javax.naming.InitialContext;
  15.  
  16. import fr.test.jms.model.ModelBean;
  17.  
  18. public class TheBean implements MessageDrivenBean, MessageListener {
  19.  
  20.     private static final long serialVersionUID = 3403509142076163275L;
  21.  
  22.     private InitialContext initContext;
  23.     private Connection connection;
  24.     private Session publisherSession;
  25.     private MessageProducer publisher;
  26.     
  27.     
  28.     public TheBean() {
  29.     }
  30.  
  31.     public void ejbCreate() {
  32.         System.out.println("dans ejbCreate" );
  33.         try {
  34.             initContext = new InitialContext();
  35.             ConnectionFactory factory =
  36.                 (ConnectionFactory) initContext.lookup("jms/con/topic" );
  37.             connection = factory.createConnection();
  38.             publisherSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
  39.         } catch (Throwable e)  {
  40.             e.printStackTrace(System.out);
  41.         }
  42.     }
  43.  
  44.     public void ejbRemove() throws EJBException {
  45.         System.out.println("dans ejbRemove" );
  46.     }
  47.  
  48.     public void setMessageDrivenContext(MessageDrivenContext arg0)
  49.             throws EJBException {
  50.         System.out.println("dans setMessageDrivenContext" );
  51.     }
  52.  
  53.     public void onMessage(Message arg0) {
  54.         System.out.println("dans onMessage " );
  55.         ObjectMessage txtMsg = (ObjectMessage) arg0;
  56.         try {
  57.             String champ = ((ModelBean) txtMsg.getObject()).getChamp();
  58.             System.out.println(champ);
  59.             System.out.println("fin " );
  60.             
  61.             Destination topic = (Destination) initContext.lookup("jms/topic/ordonnanceur" );
  62.             publisher = publisherSession.createProducer(topic);
  63.             connection.start();
  64.             publisher.send(publisherSession.createTextMessage(champ + " reçu !" ));
  65.         } catch (Exception e) {
  66.             e.printStackTrace(System.out);
  67.         }
  68.     }
  69.  
  70. }


 
mais le truc, c'est que le code de l'ejb session a l'air de s'exécuter de façon atomique, il ne semble pas y avoir de concurrence dans l'exécution de l'ejb et du mdb... c'est ça qui me fout dedans.


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 02-11-2006 à 10:18:09    

et voilà la trace :

Code :
  1. [02/11/06 10:09:12:722 CET] 00000047 SystemOut     O dans setSessionContext
  2. [02/11/06 10:09:12:722 CET] 00000047 SystemOut     O dans ejbCreate
  3. [02/11/06 10:09:15:798 CET] 00000047 SystemOut     O réponse null
  4. [02/11/06 10:09:15:798 CET] 00000060 SystemOut     O dans setMessageDrivenContext
  5. [02/11/06 10:09:15:798 CET] 00000060 SystemOut     O dans ejbCreate
  6. [02/11/06 10:09:15:876 CET] 00000060 SystemOut     O dans onMessage
  7. [02/11/06 10:09:15:876 CET] 00000060 SystemOut     O traite ça : sdfjlh
  8. [02/11/06 10:09:15:923 CET] 00000060 SystemOut     O fin


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 02-11-2006 à 10:25:39    

intéressant : http://java.sun.com/j2ee/1.4/docs/ [...] ml#wp92878

Citation :


// Don't do this!
outMsg.setJMSReplyTo(replyQueue);
producer.send(outQueue, outMsg);
consumer = session.createConsumer(replyQueue);
inMsg = consumer.receive();
session.commit();  


 
cargocult, me voilà !! je vais ajouter un p'tit commit, pour rire...


Message édité par brisssou le 02-11-2006 à 10:26:01

---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 02-11-2006 à 11:17:30    

Ou essaye de foutre ton receive dans une boucle  et catch timeoutexception , juste pour voir si ca fini par arriver, car quand je vois ta stack trace , t'es plus tres loin de la soluce, (tom mdb recois bien le message)

Reply

Marsh Posté le 02-11-2006 à 11:20:11    

j'ai poireauté 5 minutes l'autre jour, le mdb reçoit le message uniquement une fois l'appel à l'ejb terminé.
 
s'trop les boules !
 
et je comprends pas comment démarrer une transaction... je sens que c'est de la conf coté serveur.


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 02-11-2006 à 11:44:48    

YYYYYEEEEEEEESSSSSSSSS !
 
dans le descripteur ejb-jar.xml, il fallait mettre le type de transaction de l'ejb-session sur Bean, et non pas Container. Et pouf ! ça marche comme je veux.


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed