Showing posts with label portletloadmonitoring. Show all posts
Showing posts with label portletloadmonitoring. Show all posts

Using programmatic API for accessing PLM data

WebSphere Portal Server V 7.0 provides API's that you can use to access the PLM related data. I wanted to try it so i built sample portlet that will query all the portlets installed on portal server and get list of PLM related data for it. You can download it from here

In the HelloPLM portlet i am using AdminPortletModel get list of portlets on my server then i am iterating through each portlet, checking if portlet load monitoring is turned on for it (PortletLoadMetrics object is not null). If the plm is turned on for the portlet then i am reading values like if it is enabled, what is maximum allowed response time and maximum concurrent requests for the portlet


package com.wpcertification.wp70.plm;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import com.ibm.portal.ModelException;
import com.ibm.portal.ObjectID;
import com.ibm.portal.model.PortletModelHome;
import com.ibm.portal.plm.PortletLoadMetrics;
import com.ibm.portal.plm.service.PortletLoadMetricsService;
import com.ibm.portal.portletmodel.PortletDefinition;
import com.ibm.portal.portletmodel.admin.AdminPortletModel;
import com.ibm.portal.portletmodel.admin.PortletDefinitionList;

public class HelloPLMPortlet extends GenericPortlet{

PortletLoadMetricsService portletLoadMetricService = null;
PortletModelHome portletModelHome;
public void init() throws PortletException {
try {
InitialContext context = new InitialContext();
portletLoadMetricService =
(PortletLoadMetricsService)context.lookup(PortletLoadMetricsService.JNDI_NAME);
portletModelHome = (PortletModelHome)context.lookup(PortletModelHome.JNDI_NAME);
} catch (NamingException e) {
e.printStackTrace();
}
}

protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {
System.out.println("Entering HelloPLMPortlet.doView()");
response.setContentType("text/html");

try {
List plmDtoList = new ArrayList();
AdminPortletModel adminPortletModel =
portletModelHome.getPortletModelProvider().getAdminPortletModel((ServletRequest)request,
(ServletResponse) response);
PortletDefinitionList portletDefList = adminPortletModel.getPortletDefinitionList();
Iterator portletDefListIt = portletDefList.iterator();
while(portletDefListIt.hasNext()){
PortletDefinition portletDefinition = (PortletDefinition)portletDefListIt.next();
ObjectID portletDefObjectID = portletDefinition.getObjectID();
PLMDto plmDto =getPLMDTO(portletDefObjectID);
if(plmDto.getIsEnabled() != null)
plmDtoList.add(plmDto);
}
request.setAttribute("PLMDtoList", plmDtoList);
getPortletContext().getRequestDispatcher("/index.jsp").include(request, response);
} catch (ModelException e) {
e.printStackTrace();
}
System.out.println("Exiting HelloPLMPortlet.doView()");
}

private PLMDto getPLMDTO(ObjectID objectID ){
PLMDto plmDto = new PLMDto();
plmDto.setPortletUniqueName(objectID.getUniqueName());
PortletLoadMetrics portletLoadMetrics =
portletLoadMetricService.getPortletLoadMetrics(objectID);
System.out.println("Portlet Load Metrics " + portletLoadMetrics);
if(portletLoadMetrics == null)
return plmDto;
plmDto.setMaxAllowedRequest(portletLoadMetrics.getAverageResponseTime()+"");
plmDto.setMaxAllowedRequest(portletLoadMetrics.getCurrentNumberOfRequests()+"");
plmDto.setIsEnabled(Boolean.toString(portletLoadMetrics.isPortletEnabled()));
return plmDto;
}
}



When i tried accessing this portlet on my local machine i noticed that the PortletLoadMetrics object is null for all the portlets except for which i set either the max allowed response time or max no of concurrent request.

In my case only HelloPLM portlet has one of the PLM related preference so this is the output that i get

Configure Portlet Load monitoring for maximum number of concurrent request

You can configure portlet load monitoring for maximum response time but you can also configure it to handle maximum number of concurrent request. After you set maximum number of concurrent request, If the number of requests that the portlet serves at any time exceeds the maximum number of concurrent requests that you specify here, then Portlet load monitoring blocks further requests to this portlet. Instead of responding to the requests the portlet renders with a message stating that the portlet is not available. In order to re-enable this portlet for rendering, a portal administrator can enable the portlet by using the Manage Portlets administration portlet.

Example: I did set it maximum number of concurrent request to 2 by setting com.ibm.wps.pe.plm.maxrequest to 2 like this




Then i tried accessing the portlet in two different browser windows at the same time and i could see this message in the log and the portlet was blocked

[9/6/10 22:46:22:859 PDT] 00000077 GlobalPortlet W com.ibm.wps.pe.pc.waspc.plm.GlobalPortletLoadMonitoringFilter handlePreFilterInvocation() EJPPG3001W: Portlet Load Monitoring disabled the portlet with objectID: [ObjectIDImpl 'Z3_OGFLMKG10G0HE0IAR5N7GE3007', PORTLET_DEFINITION, VP: 0, [Domain: rel], DB: 0000-18BE6A290C0082E88054BBDC03DD00E0], portlet name: Hello PLM portlet, WAR file name: HelloPLM.war, EAR file display name: PA_HelloPLM because the portlet exceeded its maximum number of requests.

Configure Portlet Load monitoring for maximum response time

The WebSphere Portal Server 7.0 introduced concept of portlet load monitoring, it lets you set maximum response time for a portlet and if the response time exceeds that time, WPS will block that portlet and would disable further request to that portlet.

I wanted to try this feature so i followed these steps


  • First enable Portlet load monitoring at portal server level

  • Then i created HelloPLM simple portlet that takes 10 seconds to respond.

    package com.wpcertification.wp70.plm;
    import java.io.IOException;
    import javax.portlet.GenericPortlet;
    import javax.portlet.PortletException;
    import javax.portlet.RenderRequest;
    import javax.portlet.RenderResponse;
    public class HelloPLMPortlet extends GenericPortlet{

    protected void doView(RenderRequest request, RenderResponse response)
    throws PortletException, IOException {
    System.out.println("Entering HelloPLMPortlet.doView()");
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    e.printStackTrace(System.out);
    }
    response.setContentType("text/html");
    response.getWriter().println("Inside HelloPLMPortlet.doView()");
    System.out.println("Exiting HelloPLMPortlet.doView()");
    }
    }

    In the doView() method i am using Thread.sleep() call to block request for 10 seconds. You can download this sample application from here

  • Then i installed the portlet on the WPS 70 server

  • Once the portlet is installed, you can enable PLM for it by setting com.ibm.wps.pe.plm.average.time.processing preference. Value of this preference defines what is the maximum allowed time for this portlet. Example: If you want to specify the average response time allowed for a portlet as 3 seconds, set the portlet preference com.ibm.wps.pe.plm.average.time.processing to a value of 3000 (milliseconds) for this portlet. If portlet takes more than that time it will blocked


    In my case i am setting the maximum allowed time to 900 milliseconds which is less than 1 second

  • After setting the preference when i looked at the portlet in manager portlet, i could see that it had one additional button that would let me block the portlet manually


  • Then i went to a page which has HelloPLM portlet and it took 10 seconds to respond and on the first request it did render the output correctly but in the SystemOut.log file i could see this message

    [9/4/10 17:34:26:927 PDT] 00000067 GlobalPortlet W com.ibm.wps.pe.pc.waspc.plm.GlobalPortletLoadMonitoringFilter handlePreFilterInvocation() EJPPG3002W: Portlet Load Monitoring disabled the portlet with object ID: [ObjectIDImpl 'Z3_OGFLMKG10G0HE0IAR5N7GE3007', PORTLET_DEFINITION, VP: 0, [Domain: rel], DB: 0000-18BE6A290C0082E88054BBDC03DD00E0], portlet name: Hello PLM portlet, WAR file name: HelloPLM.war, EAR file display name: PA_HelloPLM because the portlet exceeded its average response time.

    The HelloPLM portlet took more than the allowed time so it was disabled

  • Now when i went to Manage portlet, portlet i could see that the portlet is disabled, from the request you can see that the portlet exceeded limit


  • Now if i go to the page which has the HelloPLM portlet, then i directly get portlet unavailable message without the portlet being called at all


  • You can unblock the portlet from Portal Admin Console

How to enable portlet load monitoring at portal server level

The portlet load monitoring is disabled by default, so if you want to use it first thing you will have to do is enable portlet load monitoring globally at portal server level. You will have to follow these steps to do that


  • Login into WebSphere Admin Console for Portal server

  • Go to the Resource Environment Provider -< WP_ConfigService -< Custom Properties

  • Set value of com.ibm.wps.plm.enabled property to true. It is false by default


  • Restart portal server



The portlet load monitoring is enabled at portal server level, so you will have to enable it for particular portlet.

What is portlet load monitoring

IBM WebSphere Portal now provides Portlet load monitoring. This can make your portal safer and more responsive.

Portlet load monitoring allows WebSphere Portal administrators to protect their portal by limiting the number of concurrent requests and the average response time allowed for JSR 168 or JSR 286 portlets. If a portlet exceeds either the defined maximum number of concurrent requests, or the average response time, then Portlet Load Monitoring no longer allows further requests by the portlet. Instead, the portal renders the portlet as unavailable, and the portlet code is no longer called for further requests. This way, the portal installation is protected from non-responsive portlets consuming an increasing number of threads.

Note: Portlet load monitoring monitors JSR 168 and JSR 286 portlets only.

You will have to follow these steps in order to use portlet load monitoring


  1. Enable portlet load monitoring at the portal server level

  2. Set preferences at portlet level for following things. You can set the preferences at development time by adding values in portlet.xml or you can use "Manage portlets" portle to set preferences during runtime

    • Number of concurrent request

    • Maximum time allowed inside portlet





Once the portlet load monitoring is enabled you can use the portal admin console to check if the portlet is being monitored then use it to either manually block a monitored portlet or manually unblock a portlet blocked by portlet monitoring tool