Usage of SessionMonitor class

hi All,

In our application, im trying to get the current logged in users and do some manipulations on the logged in users data.

For this purpose, m using SessionMonitor class which is present in wm_sessionMonitor jar file.

I am able to instantiate object for SessionMonitor class. but If I try to call any method present in SessionMonitor class, im getting following exception.

com.webmethods.rtl.debug.DebugException: GenericPortlet::getPortletTypeName is null
        at com.webmethods.rtl.util.Debug.assertCondition(Debug.java:649)
        at com.webmethods.rtl.util.Debug.assertStr(Debug.java:704)
        at com.webmethods.portal.service.portlet.impl.BasePortletBean.getPortletTypeName(BasePortletBean.java:179)
        at com.webmethods.portal.service.portlet.impl.BasePortletBean.getPortletInfo(BasePortletBean.java:436)
        at com.webmethods.portal.framework.portlet.beans.BasicPortletBean.isPrePCAPortlet(BasicPortletBean.java:296)
        at com.webmethods.portal.framework.portlet.beans.BasicPortletBean.getProperty(BasicPortletBean.java:177)
        at com.webmethods.portal.service.portlet.impl.BasePortletBean.getPropertyAsType(BasePortletBean.java:397)
        at com.webmethods.portal.service.portlet.impl.BasePortletBean.getPropertyAsType(BasePortletBean.java:392)
        at com.webmethods.portal.service.portlet.impl.BasePortletBean.getPropertyAsString(BasePortletBean.java:237)
        at com.webmethods.portal.service.portlet.impl.BasePortletBean.getPropertyAsString(BasePortletBean.java:247)
        at com.webmethods.portal.portlet.impl.wm_sessionmonitor.Sessionmonitor.getServerName(Sessionmonitor.java:44)
        at com.webmethods.portal.portlet.impl.wm_sessionmonitor.Sessionmonitor.getContexts(Sessionmonitor.java:60)

During portlet creation, I mentioned the portletType as ‘Generic Portlet’.

Not sure if it is trying to get the above mentioned portletType and failed to get it or any other reason causing this exception.

Couldn’t find any documentation on this class. Could you please let me know if you have any thoughts on this?

Kind regards,
Raja sekhar Kintali

You won’t be able to use classes that are deployed as part of other Portlets. This is the same restriction as war applications being able to invoke classes from other war applications.

What are you trying to accomplish? We haven’t officially released javadocs on the Session Management APIs, but those APIs are stable so i can probably post a code snippet.

Regards,
–mark

hi Mark,

My objective is to get all the current logged in users to the MWS server and run our business logic on each logged in ‘username’.

In other words, I have to get the current active sessions in MWS server and get the user details of all the current active sessions.

Kind regards,
Raja sekhar Kintali

That makes sense. How do you feel about listening to login and logout events and capturing this information “on the fly”?

hi Mark,

We can write sessionEvent listeners.

In this case, as soon as the login / logout event triggered, an entry (username) has to be created / updated into my database and
when super user* logs in and want to see all current logged in users, I have to fetch all the records from database (whichever we stored via session Event listener) and display the users and other information relevent to those users.

As sessionMonitor portlet is already listing all the logged in users- Keeping my project tight timelines in consideration, thought of reusing the same API (which is used in SessionMonitor Portlet)
to get all the current logged in users.

Could you please let me know if it is possible to get the API used in Session Monitor portlet? If not possible, then I have to go for the session Event Listeners only.

*super user - kind of Team lead for a group of users.

Thanks for your time in advance!
Kind regards,
Raja sekhar Kintali

Quick question, is this deployment in a cluster?

I’ve attached an example that i built with 8.2 FCS. If it doesn’t import into your version of Designer you should still be able to cut and paste the java class and the .view code into your project to try it out.

Please note, this will only report on users logged into the same node.

Regards,
–mark
LocalLoginMonitorApp.zip (15.9 KB)

hi Mark,

Yes, this deployment is in Cluster environment where 2 MWS nodes are present at the moment.

Kind regards,
Raja sekhar Kintali

Ok, So with this example you’ll have to browse to this portlet on both nodes.

hi Mark,

Thanks for the example.

I will try it in our environment and let you know the out come.

Kind regards,
Raja sekhar Kintali

hi Mark,

I am able to get the logged in users for current node. As per my understanding, this API can be used to get all the active sessions in current node only.

As our requirement is to display all the current active sessions from both the nodes and display in one UI page, I might need to go for login events approach.

Till that time, I may have to request business team to use 2 urls (for 2 nodes) to get all the current logged in users details.

Thank you for the example given, it is very helpful :slight_smile: .

Kind regards,
Raja sekhar Kintali

hi Mark,

Are there any listeners to listen to Login and logout events?

  1. I am aware of HttpSessionListener which listens to HttpSession events (sessionCreated, sessionDestroyed). I defined a custom class which implements SessionListener, and declared in web.xml of my portlet pacakge.

In sessionDestroyed() method, to perform some operations, I want to retrieve some details from current session. But the session values are always coming as null.

Before session expiration, in portal screens, I set attributes into session in all the following ways.

	1) IContext context = com.webmethods.portal.bizPolicy.impl.ContextFactory.acquireContext(true);
	   context.setAttribute("iContextAttr", "IContext Attr", IContext.SCOPE_SESSION);
			
	2) PortletSessionImpl portletSessionImpl = (PortletSessionImpl) this.getFacesContext().getExternalContext().getSession(false);
	   portletSessionImpl.setAttribute("sessionImplAttr", "Session Impl Attr");
			
	3) HttpServletRequest currentRequest = PortalServlet.getCurrentRequest();
	   HttpSession session = currentRequest.getSession(true);
	   session.setAttribute("sessionAttr", "Session Attribute");

If I try to get these values in sessionDestroyed() method of my Custom Session Listener - I am getting following results:

	1)  [b]Result[/b]: null
	
	2)  [b]Result[/b]: null pointer exception - External context is null - hence cannot invoke getSession method.
	
	3) [b]Result[/b]: null pointer exception  - Current Request is null - hence can not invoke getSession method;
	   
	4) HttpSession sessionObj = sessionObj.getSession(); (sessionObj is the input parameter of type SessionEvent, in sessionDestroyed() method)
	   sessionObj.getAttribute("sessionAttr");
	   [b]Result[/b]: null
[color="green"]Is there any other way where I can set attributes to session, so that those values can be retrieved in sessionListener methods?[/color]

I tried in a sample dynamic web project, which includes only 1 jsp and 1 servlet. In that project, i am able to get session attributes(which I set in jsp page befor session gets destroyed) in sessionListener methods.

Kind regards,
Raja sekhar Kintali

Each portlet can be thought of as a session object. How about this approach:

  1. Create a blank ui portlet and place it in the shell.
  2. During initialization of that portlet, create your session init logic
  3. Override the release() method of that portlet and execute your session close logic.

You can save whatever state you need as member variables on the view page bean.

Hope this helps,
–mark

hi Mark,

Thanks for the brilliant suggestion.

I will try this approach and will let you know the outcome.

Kind regards,
Raja sekhar Kintali

hi Mark,

  1. Created blank portlet, put its scope as session in faces-config.xml.

  2. overriden release method

    In release() method Iam trying to call a webservice to store some details into database before this managed bean got purged.
    During execution of this webservice call, it is always giving following exception.

    java.lang.NullPointerException
    at com.webMethods.caf.faces.data.ContentProviderUtils.getValue(ContentProviderUtils.java:150)
    at com.webMethods.caf.faces.data.object.ObjectMethodContentProvider.getParameterValue(ObjectMethodContentProvider.java:227)
    at com.webMethods.caf.faces.data.ws.glue.GlueWSClientContentProvider.getParameterValue(GlueWSClientContentProvider.java:267)
    at com.webMethods.caf.faces.data.object.ObjectMethodContentProvider.getMethodArgs(ObjectMethodContentProvider.java:220)
    at com.webMethods.caf.faces.data.object.ObjectMethodContentProvider.refresh(ObjectMethodContentProvider.java:366)
    at com.webMethods.caf.sessionportlet.SessionPortletDefaultviewView.release(SessionPortletDefaultviewView.java:70) - This is in my custom portlet at com.webMethods.caf.faces.bean.BaseFacesSessionBean.valueUnbound(BaseFacesSessionBean.java:59)
    at org.mortbay.jetty.servlet.AbstractSessionManager$Session.unbindValue(AbstractSessionManager.java:953)
    at org.mortbay.jetty.servlet.AbstractSessionManager$Session.invalidate(AbstractSessionManager.java:761)
    at org.mortbay.jetty.servlet.AbstractSessionManager$Session.invalidate(AbstractSessionManager.java:793)
    at com.webMethods.portal.portlet.impl.wm_logout.LogoutHandler.handle(LogoutHandler.java:32)
    at com.webMethods.portal.framework.dispatch.DispatchManager.handle(DispatchManager.java:438)
    at com.webMethods.portal.framework.dispatch.DispatchManager.handleDispatch(DispatchManager.java:371)
    at com.webMethods.portal.framework.impl.PortalServlet.service(PortalServlet.java:242)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)

    Not sure if all the objects referenced by this webservice is purged even before all the code present in release() method got executed?( tried
    keeping super.release() method call at the end of the release() method present in my customized portlet. - But no success).

webservice connector managed bean scope also is defined as ‘Session’ in faces-config.xml. (I removed expireWithPageFlow property as well to make sure that both the managed beans persists till session gets expired).

Could you please let me know if you have any thoughts on this?

Sorry for making this thread so long and bugging you a lot :( 

Kind regards,
Raja sekhar Kintali

It seems like the webservice connector is failing when it attempts to get the input args to the webservice.

Could you take a look at the input data and manually test to see if it is available prior to calling refresh() on the web service connector?

–mark