MemberConnectionRequest - Ecriture en base après l'envoi de l'alerte (notification/email) ?

Eric Lannez · le 29/07/13 à 15:35

Bonjour,

Je pose cette question afin de décrire un comportement assez étrange qui me bloque dans mes développements.

Pour poser le contexte, le client souhaite que les demandes de mise en relation de l'ESN puissent être gérées (acceptées / refusées) directement depuis la notifcation ou le mail envoyés de la même manière que les invitations à rejoindre un espace collaboratif.

Pour cela, j'ai developpé un AlertPolicyFilter afin d'intercepter l'alerte envoyée et y greffer des liens renvoyant vers une jsp chargée de traiter la réponse de la personne (acceptation ou refus) à la manière des espaces co. Malheureusement, il s'avère que je ne parviens pas à récupérer la MCR dans mon AlertPolicyFilter : celle-ci ne semble pas avoir été insérée en base au moment ou j'interviens. En effet, quelque soit la façon dont j'essaie de récupérer celle-ci, soit je ne remonte aucune MCR soit une éventuellement MCR antérieure et déjà traitée. Pour information j'ai tenté de récupérer cette MCR via l'ESNManager, via HibernateUtil.query() et en construisant une requête Hibernate standard.

Ce comportement est assez étrange dans le sens ou les alertes sont envoyées dans la méthode performAfterWrite de la classe MemberConnectionRequest (ou je l'avoue j'ai décompilé du code natif de JCMS).

J'espère que mon problème est compréhensible et assez clairement exposé, sinon ne pas hésiter à me demander d'avantages de détails.

Merci d'avance pour votre aide,

Eric.

Version de JCMS : 8 SP1
Version du module ESN : 4.1

PS : en voulant ajouter un screen je me suis aperçu que je n'avais pas la possibiliré d'ajouter un média.

5 pts
Olivier Jaquemet · le 29/07/13 à 16:19

Bonjour 

Petite réponse rapide avant de faire analyser votre besoin en détail :

Les objets en base ne sont généralement [1] disponible (via une requete hibernate) que *après* le commit de la session hibernate dans laquelle ils ont été créés. Le AlertPolicyFilter dans lequel vous vous insérez, vous êtes effectivement dans la méthode performAfterWrite, mais la session n'est cependant pas commité (elle l'est à la fin de la requete HTTP ou du code qui invoque le performUpdate).

Une astuce assez classique consiste à faire un HibernateUtil.commitTransation() suivi dans beginTransaction() mais elle n'est exempt d'effet de bord. Je vous suggère plutot d'intercepté les création de MCR dans un DataController, de les stocker dans un manager (par thread, via une WeakHashMap pour garantir de ne pas faire de fuite de mémoire) et dans vor MailPolicyFilter de les récupérer

[1] sauf erreur de ma part, je crois que cela dépend de votre base et de la configuration du cache de second niveau

PS : concernant le dépot d'image, une action corrective est planifié par l'équipe Jalios Community

#2

Si j'ai bien compris ton besoin, tu veux accéder à l'instance du MCR depuis l'APF, mais tu ne peux pas faire de query hibernate pour cela.

Solution

  • implémente un DataController qui écoute le création de MCR, et à chaque création, stocke l'objet dans une classe quelconque (le manager dont je parle).
  • dans ton APF, récupère et retire le MCR
Olivier Jaquemet · le 29/07/13 à 16:56
#3

D'accord je pense avoir compris ta solution. Comme la MCR n'est pas encore créée en base tu me proposes d'intercépter sa création via le DataController puis de la stocker dans un manager et enfin de la récupérer dans mon APF.

Eric Lannez · le 29/07/13 à 17:02
#4

c'est bien ça.

Olivier Jaquemet · le 29/07/13 à 17:04
1 pt
Eric Lannez · le 20/08/13 à 10:24

Bonjour Olivier,

J'ai enfin pu tester la solution que tu proposes. Malheureusement, il s'avère que l'AlertPolicyFilter est appelé systématiquement avant que je passe dans mon dataController (que j'utilise la méthode beforeWrite ou afterWrite). Du coup, la MCR n'est pas mise en mémoire au moment où j'intercepte l'alerte envoyée ...

Est-ce un comportement normal ou bien as-tu une idée du problème ?

Merci d'avance pour ton aide,
Cordialement.

#1

L'invocation du code est le suivant :

  1. MemberConnectionRequest#performAfterWrite
  2. si OP_CREATE MemberConnectionRequest#processMemberConnectionRequest
  3. new AlertBuilder(... "connection-request"...)
  4. sendAlert

Donc si dans ton DataController tu intercepte les création de MemberConnectionRequest, alors la méthode beforeWrite est appelé avant la création et l'envoie de l'alerte

Olivier Jaquemet · le 20/08/13 à 11:34
#2

J'avais en effet identifié cet ordre d'invocation.

En revanche, après quelques recherches je me suis aperçu que je ne passais pas dans mon DataController. En effet, j'avais déclaré celui-ci de la manière suivante :

<datacontroller class="com.team360.jcmsplugin.intranet.esn.dataController.MemberConnectionRequestController" types="MemberConnectionRequest" />

Or les MemberConnectionRequest ne sont pas présent dans le répertoire types/ de l'application et nous avons donc dû déclarer le DataController comme suit :

<datacontroller class="com.team360.jcmsplugin.intranet.esn.dataController.MemberConnectionRequestController" types="com.jalios.jcmsplugin.esn.MemberConnectionRequest" />

Après avoir parcouru les différentes documentations, je n'ai pas trouvé de trace sur ce fonctionnement particulier. Peut-être ai-je manqué cette partie là dans mes recherches, sinon il serait intéressant de rajouter cette information là.

Merci encore pour ton aide Olivier, la solution de contournement fonctionne visiblement bien.

Eric Lannez · le 20/08/13 à 14:10
#3

Effectivement, la valeur qui peut être spécifiée dans l'attribut types répond aux règles suivantes :

  • Si le type communiqué correspond directement au "fully qualified name" d'une classe, la classe est renvoyée
  • Sinon, les packages suivants sont essayé, dans cet ordre :
    • generated.
    • com.jalios.jcms.
    • com.jalios.jcms.workspace.
    • com.jalios.jcms.portlet.
    • java.lang.

Il s'agit des règles de la méthode channel.getClass(String name) (que la javadoc ne précise pas)

Olivier Jaquemet · le 20/08/13 à 14:18
0 pt