Forums de discussion

Getting started with JMS in Liferay Portlet

Max Hamulyak, modifié il y a 9 années.

Getting started with JMS in Liferay Portlet

Junior Member Publications: 29 Date d'inscription: 13/10/14 Publications récentes
Hello,

I am currently finishing up my Liferay Portlet Project, one of the last features I have to implement is an subscriber to an ActiveMq event, I know the topic and the actions I need to subscribe to, however I have no idea how to configure this subscriber, how will I achieve this using Liferay ?

Regards
Max
thumbnail
David H Nebinger, modifié il y a 9 années.

RE: Getting started with JMS in Liferay Portlet

Liferay Legend Publications: 14919 Date d'inscription: 02/09/06 Publications récentes
You have to figure out a couple of things before you pursue this endeavor...

First is how the subscription is handled. If it is a system-based subscription (the server is getting the messages, not a user) then your connection can be global but you run into issues as to how to display to multiple users. If it is user based, then you have to establish a connection for the user and manage that connection (keep it alive while user is logged in, shut it down when user logs out or user session expires, whichever comes first), and you still have to determine what happens if user is logged in multiple times (multiple browsers).

You can alleviate some of these issues by creating a message driven bean that receives the message and publishes to the Liferay message bus (LMB ). Using this pattern, the portlet can get the message from the LMB regardless of how many times they're logged in or whether messages should be seen by multiple users. The one issue to be aware of here is that the MDB can receive messages and push to the LMB even when users are not logged in, so the messages can be consumed from JMS yet get lost (i.e. Liferay restarts before someone gets the message from the LMB ). LMB is not a good fit for all use cases, but it can be good for some.

From a portlet issue, you need to figure out how you're going to handle getting the message anyway. A portlet will (normally) only update when a render request is being processed, so you might think about grabbing messages then, but you really should avoid doing anything heavy in the render phase because as a user refreshes the portal you will be re-rendering your content and don't want to take on a big delay.

This also means that you should be capturing and retaining the messages in the portlet session so that you can support multiple re-renders without losing previously displayed messages.

The entire thing is a challenge, but I can tell you that it is entirely doable. You just need to have a solid plan going in so you end up with the right implementation when you're done.
Max Hamulyak, modifié il y a 9 années.

RE: Getting started with JMS in Liferay Portlet

Junior Member Publications: 29 Date d'inscription: 13/10/14 Publications récentes
David H Nebinger:
You have to figure out a couple of things before you pursue this endeavor...

First is how the subscription is handled. If it is a system-based subscription (the server is getting the messages, not a user) then your connection can be global but you run into issues as to how to display to multiple users. If it is user based, then you have to establish a connection for the user and manage that connection (keep it alive while user is logged in, shut it down when user logs out or user session expires, whichever comes first), and you still have to determine what happens if user is logged in multiple times (multiple browsers).

You can alleviate some of these issues by creating a message driven bean that receives the message and publishes to the Liferay message bus (LMB ). Using this pattern, the portlet can get the message from the LMB regardless of how many times they're logged in or whether messages should be seen by multiple users. The one issue to be aware of here is that the MDB can receive messages and push to the LMB even when users are not logged in, so the messages can be consumed from JMS yet get lost (i.e. Liferay restarts before someone gets the message from the LMB ). LMB is not a good fit for all use cases, but it can be good for some.

From a portlet issue, you need to figure out how you're going to handle getting the message anyway. A portlet will (normally) only update when a render request is being processed, so you might think about grabbing messages then, but you really should avoid doing anything heavy in the render phase because as a user refreshes the portal you will be re-rendering your content and don't want to take on a big delay.

This also means that you should be capturing and retaining the messages in the portlet session so that you can support multiple re-renders without losing previously displayed messages.

The entire thing is a challenge, but I can tell you that it is entirely doable. You just need to have a solid plan going in so you end up with the right implementation when you're done.



Thank you for your answer, the issue at hand is the following, using Liferay I created an alternative front-end for an existing application. That application requires a locking mechanism to ensure that only one person has access to a specific document at the time. Using ActiveMq both front-ends will be notified about either a lock or an unlock of a document. So both Front-Ends act as a subscribe/listener to an ActiveMQ channel. I need a mechanisme, in my Liferay plugin project to manage a collection of locks, remove locks on a unlock event, en notify on a lock event. In a perfect world this would be on a portal level, not on the portlet level. So say for example I execute an action from on portlet, I need to notify this global service so it can in turn notify the active mq to notify other front-ends, and in the portlets I need to be able to access the collection of locks, so I can display the current unlocked, or locked documents. I have been able to build a listener to a ActiveMQ source, and receive message, (for testing purposes the listener process was started on render phase of the portlet) However I am uncertain how to achieve this on a global level, for example store them in the PortalSession.

Regards
Max
thumbnail
David H Nebinger, modifié il y a 9 années.

RE: Getting started with JMS in Liferay Portlet

Liferay Legend Publications: 14919 Date d'inscription: 02/09/06 Publications récentes
Max Hamulyak:
That application requires a locking mechanism to ensure that only one person has access to a specific document at the time.


Sorry, but I think an AMQ solution to this is overkill. The classic solution to this problem would be either a database table or a filesystem lock file (if on same system).

In AMQ you have the outage issues, if a network link is down the "lock" message would not be delivered and multiple users could potentially get in. Whereas a DB failure, well you could just not let the user into the document anyway. Same thing with the filesystem, either you can see where the lock should be and create it, or you just don't let the user in.

Both of those options would also be much simpler to implement than an AMQ solution...
Max Hamulyak, modifié il y a 9 années.

RE: Getting started with JMS in Liferay Portlet

Junior Member Publications: 29 Date d'inscription: 13/10/14 Publications récentes
ActiveMQ is already in use in the existing system,as of this moment I am able to listen to the ActiveMQ topic on a portlet level, however it would be more resource friendly to achieve this on a portal level. So all the portlet users get the updated content in one access point.
Is it possible to listen to ActiveMQ on portal level, and based on the active mq message, store something on the server (locks can expire) and access it from a portlet?
Regards
Max
thumbnail
David H Nebinger, modifié il y a 9 années.

RE: Getting started with JMS in Liferay Portlet

Liferay Legend Publications: 14919 Date d'inscription: 02/09/06 Publications récentes
Well sure, I guess. A custom SB using an empty (no column) entity, add a setLock() and isLocked() method to front a boolean, that would act as a portal-wide global value that all portlets would have access to...