Showing posts with label Inter Portlet communication. Show all posts
Showing posts with label Inter Portlet communication. Show all posts

InterPortlet Communication - Scenarios and Best Practices

I came across to many assignment in which I have implemented portlet communication in different ways based on various business needs. I also read various queries and responded solution on different forums where people are asking solution for interesting use cases for portlet communication.

I thought of writing this post just to summarize various portlet communication scenarios and what should the best practices applied for each of them.

There are various ways of achieving InterPortlet communication, depends on which portlet API and what portal server you are using.

Portlet communication when you have

1) JSR 168, Any Portal Server, Same Portlet application

Best Approach:- PortletSession with APPLICATION_SCOPE

2) JSR 168, IBM Portal Server, Same Portlet application

Best Approach:- PortletSession with APPLICATION_SCOPE

3) JSR 286, Any Portal Server, Different portlet application

Best approach depends on what type of value want to pass between source and target portlet. Here are various possibilities

 
a) String or array of String :- Public Render Parameter
 b) When data needs to be processed in receiver portlet:- Eventing concept
    
(Note: it is advisable to use public render parameters as they avoid the overhead for portlets event creation and wiring the portlets together.wiring portlets together is portal container specific and is an additional overhead.)

Have a look at my article on JSR 286 InterPortlet communication

4) JSR 286, IBM Portal Server, Different portlet application

   point 4 solution applies here, in addition to that if you want to pass Object
   Best approach:- DynaCache

Have a look at my article on
DynaCache scenarios and implementation


Some other Use cases
( IBM Portal server specific solution)

5) On click of portlet A, you want to trigger portlet B(same war or different war) on the same page or different page and passing string or array of string parameter
Solution:- IBM Advanced URL Generation Helper classes

Have a look at my post on InterPortlet communication in different WAR


6) On click of Portlet A, you want to show/hide some portlets
Solution:- IBM portal State API, please google it to find out more.


Other then these possibilities, if you have come across to any other use case, please feel free to share.
I would be more than happy to include all possible scenarios and best approach...

feel free to comment..

Page to page communication and/or IPC in different war

I came across to many threads on forums where people asking for page to page communication in which they have portlet A on page1 and portlet B on page2 and they want to establish communication between Portlet A and portlet B and also want to pass parameter from portletA to Portlet B.
I thougt of writing a solution for the same on my blog, instead of replying on every forum ;-)

anyways..., well for this kind of scenario and also usecases like IPC in different war, this will be helpful
Note:- This is only IBM Portal specific solution, because JSR168/286 doesn't provide any mechanism for page to page communication so far.
JSR286 has eventing by which IPC in different war can be achieved.

IBM provides a set of Helper classess, they call it
IBM's Advanced URL Genenration Helper Classes.

There are few set of classes i have worked with to achieve all above usecases.
PortletURLHelper
ServletURLHelper
OffLineURLHelper
All of these classess contains loverloaded generateUrl method.

For IPC or page to page communication you can use any of generateURL method and pass parameters like pageuniquename, portletuniquename, map and etc...

have a look at For IPC in differect war,
have a look at How to assigning unique name to page and portlet

JSR 286 InterPortlet communication

Interportlet communication(IPC) allows sharing of data between portlets.
In JSR 168, we use portlet session with Application Scope to share data between portles and this is possible within a portlet application, because session can't be shared across two different context (web/portlet application).


JSR 286 has introduced two ways to achieve IPC.

1) Public Render Parameter
2) Eventing

Let's dicsuss one by one with their Concept, Implementation and Usage Scenario

1) Public Render Parameter

Concept:-
Public Render parameters allows you to share data using render parameters.
Source portlet will set data using actionResponse.setrenderPrameter in processAction phase and target portlet will receive data using renderRequest.getPramete("param name").

Note:- In JSR168 render parameter was also there but not public.
Public means, render prameter set in processAction of one portlet can be retrieved in render method of any other portlets in the same/different war.

Implementation:-
a) You will require to set public render parameter at portlet application level.
List all the render prameter you like to publish/share.

<public-render-parameter>
<identifier>id1</identifier>
<qname xmlns:x="http://sun.com/params">x:param1</qname>
</public-render-parameter>
<public-render-parameter>
<identifier>id2</identifier>
<qname xmlns:x="http://sun.com/params">x:param2</qname>
</public-render-parameter>

b) Need to specify render prameters you would need a portlet to share
Specify prameter within portelts that would like access those prameters

<portlet>
<portlet-name>PortletA</portlet-name>
<supported-public-render-parameter>id1</supported-public-render-parameter>
<supported-public-render-parameter>id2</supported-public-render-parameter>
<portlet>
<portlet>
<portlet-name>PortletB</portlet-name>
<supported-public-render-parameter>id1</supported-public-render-parameter>
</portlet>
<portlet>
<portlet-name>PortletC</portlet-name>
<supported-public-render-parameter>id2</supported-public-render-parameter>
<portlet>

Usage scenario:-
a)
Since the public render parameters are encoded in the URL, so you will have option only to share data between portlets of type String and String arrays.
b) Since public render prameter are only available in render methods, so you will not be using it where processing is required in data.
c) Best to use in situations where, you have target portlet changing it's rendering view based on parameter retrieved without any processing on prameter value.

2) Eventing

Concept:-
Portlet event model is a loosely coupled, that allows creating portlets as stand-alone portlets that can be wired together with other portlets at runtime.
Source portlet publish an event and all other portlets ( within same war or different war), can register for that event.
Once target portlet receives an event, it can peform processing on data and then display results based on business need.

Implementation:-

a) Portlet which want to publish events should have follwoing entry at application level in portlet.xml.
If IPC is beween two different war, then this event definition should present in portlet.xml of both war.
Setting event definition.

<portlet-app ...>
<portlet>
. . .
. . .
</portlet>

<event-definition>
<qname xmlns:x="http://ExtremePortal.blogspot.com/Employee">x:Employee</qname>
<value-type>com.wps.Employee</value-type>
</event-definition>
</portlet-app>

b) Event publishing Portlet should specify events that they want to publish.

<portlet>
<description>SourcePortlet</description>
<portlet-name>SourcePortlet</portlet-name>
.................
<supported-publishing-event>
<qname xmlns:x="http://ExtremePortal.blogspot.com/Employee">x:Employee</qname>
</supported-publishing-event>
</portlet>

Setting an event into processAction of publishing portlet

public class SourcePortlet extends GenericPortlet {
public void processAction(ActionRequest request, ActionResponse response)
throws PortletException,IOException {
QName qname = new QName(""http://ExtremePortal.blogspot.com/Employee" , "Employee");
Employee emp = new Employee();
//set values in Employee
response.setEvent(qname, emp);
}
}


c) Event processing portlets should specify events that they want to process

<portlet>
<description>TargetPortlet1</description>
<portlet-name>TargetPortlet1</portlet-name>
<supported-processing-event>
<qname xmlns:x="http://ExtremePortal.blogspot.com/Employee">x:Employee</qname>
</supported-processing-event>
</portlet>

<portlet>
<description>TargetPortlet2</description>
<portlet-name>TargetPortlet2</portlet-name>
<supported-processing-event>
<qname xmlns:x="http://ExtremePortal.blogspot.com/Employee">x:Employee</qname>
</supported-processing-event>
</portlet>

Event process portlet needs to override processEvent method

public class TargetPortlet extends GenericPortlet {
public void processEvent(EventRequest request, EventResponse response) {
Event event = request.getEvent();
if(event.getName().equals("Employee")){
Employee emp = (Employee )event.getValue();
//process emp here
}
}
}

Usage scenario:-
a) Event technique should be used in situation where data shared needs to be processed in receiver portlet.
b) it is advisable to use public render parameters as they avoid the overhead for portlets event creation and wiring the portlets together.wiring portlets together is portal container specific and is an addtional overhead.



Interportlet Communication in different War

Interportlet communication in JSR 168 can be achieved through PortletSession with APPLICATION SCOPE, and as session can't be shared across two different war so we can't achieve IPC in different war files.

We can make use of IBM's Advance URL Generation classes API is to achieve IPC between different war files.
Using this API we can generate a link to any portal page and target any particular portlet on that page. We can also pass some parameter to target portlet.

One obvious use case for this, there are two portlets ( from different war file) added on same page, but there could be possibility where in page A has portlet A and page B has portlet B.

On click of a link on portlet A, portlet B on page B should get render and show data based on parameter retrieved from Portlet A.
With Advance URL Generation classes, we can achieve both the scenarios...
 
If we consider second use case, here we go to achieve that,
Create a url to Portlet B on Page B
Write this code in processAction method of Portlet A,
//Code
String paramValue[] = new String[1];paramValue[0]="Neeraj Sidhaye";
HashMap map= new HashMap();map.put("UserName", paramValue);
String targetURLStr = ServletURLHelper.generateUrl("PageB", "PortletB", map, actionRequest, actionResponse);
//Explaination
where, PortletB is unique name of the portlet and unique name must be assigned through xml access only. PageB is the unique name of the page, which can be assigned through portal administration by editing page properties.MAP is used to pass parameter to targeted portlet to achieve InterPortlet Communication.
//Code
actionResponse.sendRedirect(targetURLStr);
//Explaination This will redirect to generated url that is to Portlet B on page B.
// Code for Portlet B.
// In doView method of Portlet B, you just need to retrieve the map and iterate it to get UserName value.
Another helper class to achieve the same directly from on click of a link on jsp
// code - write this code on jsp
String targetUrlStr = PortletURLHelper.generateUrl(pageName, portletName, params, request, response)
// and then use this targetUrlStr value on href of a link
Now i am thinking of how to achieve the same using JSR168 or JSR 286 API.