Showing posts with label Best Practices. Show all posts
Showing posts with label Best Practices. Show all posts

Portlet Preferences Usage - Best Practices


PortletPreferences should be used very carefully and in situations only when there is a valid use case for it.
So ideally, one should have good knowledge of portlet preference and most imortantly, where to apply it.

The PortletPreferences object provides the ability to store information persistently about how a client wants to use a particular portlet. 

For example, with the stock portlet, a user can provide stock code information to the portlet, and the portlet will store that information persistently using the PortletPreferences object. The next time the user visits the view mode of the portlet, the stock details for that user's choice will be displayed. 
Persistently storing this information, is all done behind the scenes for you by the portal framework.

So when you use portlet preference, did you ever think about where does portlet preference gets stored? In hard drive, some KB's data in DB or as CLOB or something that is not efficient. 
So how to store portlet preference is completely upto portal vendors and hence we as a developer or DB administrator don't have much control over the data which is stored in portlet preference.

Let's talk about application efficiency, where in if you want to store just a Boolean flag and if you choose to store it in portlet preference, you don't know how it will be stored and what size it would use for storage compared to if we chose to use our own DB to store the flag which would just take few tiny bit of space.

Furthermore, mining information from data stored in portlet prefernce is almost very difficult.

So, If you don't know how the portal stores your PortletPreferences data, and you don't know how the portal ties a particular preference to a particular user, you're going to have a pretty hard time mining your own data.

The best use of portlet preference could fall in below situations where a user wants 

1) To have red background.
2) configurable pagination numbers
3) configurable TimeZone
4) configurable portotol ( http or https etc )
5) Configurable fonts etc.

Conclusion -


  • Use portlet preference for simple configurable parameters
  • Don't ever use preference to store information where it would become impossible to do data mining from preference storage because you don't have control over preference storage.

Anonymous user session - Best practice

You might have required to enable session for Anonymous user for some business requirement and you might have done it by creating a custom property in portal configuration service called WP NavigatorService.
Creating a new custom property called public.session and value as true for WP NavigatorService.
This setting creates anonymous session for every user and for every portlet, which will definitely be a performance hit.

Now you may think how it will be performance hit, let me explain in brief
If the portlet does not require a session for critical operation, then perhaps any subfunctions within the portlet require the session can be suppressed to anonymous users.
This should be evaluated for each individual portlet.

If request.getPortletSession() or request.getPortletSession(true) are called when the user is not logged in and WebSphere Portal is not configured to use a session for anonymous users, each request from each client creates an extraneous PortletSession object that is lost and consumes JVM memory. This causes more frequent JVM garbage collection and hurts overall WebSphere Portal performance.


To overcome this performance issue, we can make use of JSR 286 new concept called Container Runtime Options.
With this concept, we can create Anonymous user session for a perticular portlet.

All you have to do is just add <container-runtime-option> tag to portlet.xml for a specific portlet you want to enable anonymous user session.
com.ibm.portal.public.session is the parameter name and set value as true.
       
Example:-

<container-runtime-option>
  <name>com.ibm.portal.public.session</name>
  <value>true</value>
</container-runtime-option>

Best Practices - Common js,img,css files shared by multiple projects

One day, I was just reading developerworks forum queries and response.
Usually I love to read and reply more and more portal quires posted on forums.

During that time, I just came across to a query where, somebody asked about "where to keep common js,css,img files  and refer them into your multiple portlet projects"
I replied there and also thought about sharing on my blog.

Following are the best practices to keep all your common js,img,css files shared by multiple portlets project

For your dev,stag,prod environments :-

The best place would be to put all these static files(js,img,css) on your Web Server and just refer them  from your jsp files.
Example:- If you have copied js,img,css folders to staticFiles on WebServer then refere them in your jsp as below

<script src="/staticFiles/js/test.js" type="text/javascript"
></script>

same applies for css and img.

For your localhost portal:-

Since there will be no WebServer on local environment, you can do following steps to achieve the same.

Create a Web Project. 

Put all your js,css,img files to web content folder.
Export this project as EAR and 

Install this EAR through WAS console and 
Provide application context root as /staticFiles.
Click Finish and Save.

Now, in your portlet jsp files, refer your js,img or css files like

<script src="/staticFiles/js/test.js" type="text/javascript"></script>


Same applies for css and img.

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..

DynaCache in cluster environment

It has been really long time i haven't posted any articles on my blog. somehow was busy with couple of projects.

Finally today i got some time and thought of immediately write a post before it's too late again... anyways..

So friends, here in one of my assignment we are using dynacache to share object across application.

I posted my query on IBM developer works asking for how DynaCache works in cluster environment and i got one reply, so just thought of sharing on my blog.

DynaCache behaviour in clustered environment is somewhat different and need to take special attention.

Fist, if you don't have data replication domain setup in cluster environment each node has its own copy of the dynacache and which may cause issues in case of fail over or in case when objects are shared between diff application.

To use the your dynacache as global object across the cluster , you need create one data replication domain for the all nodes in the cluster and enable the data replication service.


To enable data replication service of dynacache, please refer to Configuring cache replication
article in infocenter



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

WPS Shared Library Creation and Usage scenarios

You might be aware of default Shared library of WPS, which is <PortalServer> /shared/app folder and it is the place where we keep the jar files which we want to be shared across all applications deployed on portal. Jar files placed here are loaded with portal class loader.

You can find entry for this portal shared library entry on WAS under

Environment --> Shared Libraries --> WPSlib



In the same way, there could be scenarios where you have several portlet applications deployed on portal and some of them might be using common libraries. 
We generally keep libraries in individual applications lib folder but few jars files might be common to some applications. In this case, there is no meaning to put these common jars to individual applications lib folder. Ultimately we will be increasing size of EAR or WAR  and reloading of same jar file from different application.

Best solution to this would be to create our own shared library.
The way WPS share library works, we can also create our own shared library and put common jars there so that all our applications make use of them and now we don't require to put those common jars in our application specific lib folder.

Here i tell you, how to achieve the same.
First, we will create a folder on drive, and then we will copy our common jar files to this folder.
For example:- /shared/app/appsharedlib

Next step would be to create a shared library entry in WAS and pointing it to above path
1) login to WAS as admin
2) navigate to Environment --> Shared Libraries
3) select your node where you want to create library
4) click on New
5) provide following details on the screen
Name:-
Classpath:- ${WPS_HOME}/shared/app/appsharedlib
6) click on ok and then save.
7) Restart Portal and WAS.

You can now test by putting all the common jars to our appsharedlib folder and remove those jars from applications lib directory.

DynaCache scenarios and implementation

I have seen so many queries where people are looking for solution to share object between different portlet applicataions.I just thought of writing this post for detailed solution for these kind of use cases.
So friends, If you have custom object and you want to share that object across any portlet application deployed on your portal environment,
DynaCache is the place where you can store your object and get the object where ever required back from DynaCache.

DynaCache Scenarios
scenarios i have worked with was
In my custom login portlet, i was required to store custom object at the time lo login and the same object should be available to all portlet applications deployed on portal.

For this, In my login portlet i stored the object into DynaCache and get the object from DynaCache where ever required.


There could be other scenarios as well, where you want to Cache data in JSR 168 portlets, Share information between IBM portlets and JSR 168 portlets
 

Technically, WebSphere Application Server provides the DistributedMap interface as a simple interface for the dynacache.

DynaCache implementation

First, you need to enable global dynacache service in the WebSphere Application Server administrative console.
By default, this service is enabled but in case if it's disabled, follow the steps below to enable it

1. Open the administrative console.
2. Select Servers => Application Servers in the administrative console navigation tree.
3. Click the WebSphere Portal server.
4. Select Additional Properties => Dynamic Cache Service.
5. In the Startup state field, select Enable service at server startup.
6. Click Apply or OK.
7. Restart WebSphere Application Server and WebSphere Portal Server.

Registering and configuring a new dynacache

Next, you need to register and configure a new dynacache instance for use by the portlet service

1. Open the administrative console.
2. Select Resources => Cache instance = > Object cache instances.
3. click New.
4. provide values to mandatory fields.

(I am giving JNDI values as services/cache/MyCustomObjectCache )

5. Click Ok and then Save.

Accessing/lookup of DynaCache service

Next, we will access/lookup DyanaCache Service. In portlets, where ever you are storing or getting the object to/from dyanacahe, you will have to lookup the service first and then you can store or get the object to/from dynacache.
Best paractice would be to lookup this service at the time of initialization.(init method of portlet)

//declare a class level variable
private DistributedMap distributedDynaCacheMap = null;

public void init(PortletConfig portletConfig) throws PortletException {

super.init(portletConfig);
Context context;

try {

context = new InitialContext();
distributedDynaCacheMap = (DistributedMap)context.lookup("services/cache/MyCustomObjectCache");

} catch (NamingException e) {

throw new PortletException();
}

Now, you have got your dynacache service lookedup...

To store object into dynacahe, simply call put method.

distributedDynaCacheMap.put(Object arg0, Object arg1);

To get object from dynacache in any of portlet, first you need to access/lookup the service and just call get method on distributedDynaCacheMap.

distributedDynaCacheMap.get(object argo);

Custom portlet service - usage and implementation

Concept:- Accessing a portlet service requires a JNDI lookup for a PortletServiceHome. To use the portlet service, you retrieve a service object from the home, cast it to the service-specific interface and invoke service methods.
Let us talk about a scenario where implementation of custom portlet service solved my use case.

I had a use case where in, i was required to create a variable and make it available globally across the portal.

In detail, i wrote my own login portlet for wps 6.1.0.1 and when user hit my portlet using url http://localhost:10040/wps/InvokePortalLogin/InvokeLoginServlet?ID=5678
here i retrieve this ID in my servlet which is part of login portlet app, and redirect to portlet using IBM's Advance generation URL helper classes.
Now i was required to store this ID in login portlet in such a location so that it should be available to all the portlet apps deployed on portal.
I achieved this by creating a custom portlet service and put this data into HashMap ( there is mapping of userid as key and ID as value in map )using service methods.

Now whichever portlets need this ID after authentication, just lookup this service and call service methods to get ID of the logged in user.
things you should have knowledge of to implement usecase similar to above are
a) basic Java, J2EE concepts and Portal concepts, specially WPS
b) Login Portlet Customization
c) URL Generation API's
d) Portlet service concept
e) Custom Portlet Service concepts

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.

Authentication Filter implementation

In WPS, Authentication filters are used to show custom portal pages after logging through login Portlet.

One possible use case could be like this,

If user Dave login to portal, he should see Finance portal page
If user Andrew login to Portal, he should see Sports portal page

Other use case that i worked with is,

User login using Login Portlet (My own developed Login Portlet) and after
authentication user will be redirected to custom screens of login portlet itself
and after providing certain information on custom screens, he will be logged in to portal.

For all these kind of use cases, You need to write your own login portlet and implement Authentication Filters

I am just gathering all the technotes that i came across while working with Authentication Filters

Setting service configuration properties, in this case it would be WP Authentication Service

This New security APIs in WebSphere helped me lot to understand following, hope it will help for all reader as well.

a) LoginPortletService and various filters
b) Capabilities of the remember me cookie
c) Remember me cookie portlet service
c) Using the Puma Service in a public context and
d) Authentication filters

Portal and other libraries required for writing a Portal Authentication Filter


if you find any error at portal startup, after creating Custom Properties in WP Authentication Service on WAS,