Wednesday, 16 April 2014

Implementing Portlet Preferences

Process of building PortletPreferences / Personalization

1. Create PortletPreferences object and setValue() with request.getParameter or something else.
2. Store the portletpreference object into persistent storage using prefobj.store()
3. And can retrieve/set the stored preference object in XXX.jsp or any render method

-> In back-end this preference objects will stored into the Portal database with predefined conditions.
-> We have two important methods store() and reset(), where store() method stores the preference object into database and if we want to reset the values to default we can use reset() method.
-> We should not invoke the store() method in any portlet’s render method, in any portlet mode, which will result in an exception.
-> We can also validate preferences by using interface PreferencesValidator.
-> We can also set preference and preferences-validator in Portlet.xml file as below;

<portlet-app ...>
<portlet>
<portlet-name>yourportlet</portlet-name>
<portlet-class>portlet class path</portlet-class>
...
<portlet-preferences>
<preference>
<name>maxNumOfBooks</name>
<value>1000</value>
</preference>
<preferences-validator>
chapter10.code.listing.validators.BookCatalogPrefsValidator
</preferences-validator>
</portlet-preferences>
</portlet>
...
</portlet-app>


Code in file -- msperfportlet_view.jsp --

<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%-- Uncomment below lines to add portlet taglibs to jsp --%>
<%@ page import="javax.portlet.*"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%>

<portlet:defineObjects />

<%
    // We can also get preferences object here in jsp
    PortletPreferences jspprefs = renderRequest.getPreferences();
    //String prefvalues[] = jspprefs.getValues("category",new String[]{"-99"});
    List list = java.util.Arrays.asList(jspprefs.getValues("category",new String[]{"-99"}));
%>


<form action="<portlet:actionURL/>" method="POST">
       
    <h2>User Preference on Cricket</h2>
   
    <select name="cricketPref" multiple="multiple">
        <option value="test"<%=list.contains("test")?"selected":""%> id="userselection">Test Matches</option>
        <option value="od"<%=list.contains("od")?"selected":""%> id="userselection">OD Matches</option>
        <option value="ipl"<%=list.contains("ipl")?"selected":""%> id="userselection">IPL</option>
        <option value="icl"<%=list.contains("icl")?"selected":""%> id="userselection">ICL</option>
        <option value="t20"<%=list.contains("t20")?"selected":""%> id="userselection">T20</option>
    </select>
   
    <input type="submit" value="Submit" />
       

</form>



Code in file -- msperfportlet.java --

package ms.eb;

import javax.portlet.GenericPortlet;
import javax.portlet.ActionRequest;
import javax.portlet.RenderRequest;
import javax.portlet.ActionResponse;
import javax.portlet.RenderResponse;
import javax.portlet.PortletException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.PreferencesValidator;
import javax.portlet.ProcessAction;
import javax.portlet.RenderMode;
import javax.portlet.ValidatorException;

/**
 * msperfportlet Portlet Class
 */
public class msperfportlet extends GenericPortlet{// implements PreferencesValidator{
   
     
    //@ProcessAction(name = "savePreferences")
    public void processAction(ActionRequest request, ActionResponse response)throws PortletException, IOException {
       
        // Getting parameter values from msperfportlet_view.jsp
        String[] prefCategories = request.getParameterValues("cricketPref");
        for(int i=0; i<prefCategories.length; i++){
            System.out.println("Selected Preference Value is :: "+prefCategories[i]);
        }
       
        // Creating a PortletPreferences object and setting preference value using setValues
        PortletPreferences prefs = request.getPreferences();        
        if(prefCategories != null) {
            // Setting preffered categorites preffered value
            prefs.setValues("category", prefCategories);
        }
       
        // Storing preferences in a persistent store
        // This should be in only processAction method only
        prefs.store();          
       
        // Reseting preference value to default
        // We have to reset preference by reset() only but not with assigning null value to setValues() has null is also taken has valid entry
        //prefs.reset("category");
    }
   
    public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {
        response.setContentType("text/html");
        // We Can get preferences object in doview also but we cant store preferences object here
        /*PortletPreferences renderpref = request.getPreferences();
        String str[] = renderpref.getValues("category",new String[]{"-99"});
        for(int i=0; i<str.length; i++){
            System.out.println("Preference Value from doView() :: "+str[i]);
        }*/
        PortletRequestDispatcher dispatcher = getPortletContext().getRequestDispatcher("/WEB-INF/jsp/msperfportlet_view.jsp");
        dispatcher.include(request, response);
    }

    public void doEdit(RenderRequest request, RenderResponse response) throws PortletException, IOException {
        response.setContentType("text/html");      
        PortletRequestDispatcher dispatcher =
                getPortletContext().getRequestDispatcher("/WEB-INF/jsp/msperfportlet_edit.jsp");
        dispatcher.include(request, response);
    }
   
//    @RenderMode(name = "edit")
//    public void showPrefs(RenderRequest request, RenderResponse response)throws PortletException, IOException{
//        PortletRequestDispatcher dispatcher = getPortletContext().getRequestDispatcher("/WEB-INF/jsp/msperfportlet_edit.jsp");
//        dispatcher.include(request, response);
//    }

    public void doHelp(RenderRequest request, RenderResponse response) throws PortletException, IOException {
       
        response.setContentType("text/html");      
        PortletRequestDispatcher dispatcher =
                getPortletContext().getRequestDispatcher("/WEB-INF/jsp/msperfportlet_help.jsp");
        dispatcher.include(request, response);
    }

}




Monday, 10 February 2014

Fixing Cross Domain issue in WebSphere Portal with Connections

Environment - Integrated WebSphere Portal 8X with Connections 4.5 with SSO established.

Issue - Unable to retreive Connections Feed in Portlet without passing credentials.

Solution - To Resolve cross domain issue we have to update proxy-config.xml file and restart the server.

Process - Goto,

D:\IBM\WebSphere\wp_profile\config\cells\TIT-JAVA-010Cell\applications\AJAX Proxy Configuration.ear\deployments\AJAX Proxy Configuration\wp.proxy.config.war\WEB-INF\proxy-config.xml

    1. Take backup of proxy-config.xml
    2. Update the proxy-config.xml by adding below lines after <mapping ;
            <policy url="*" acf="none">
                <actions>
                    <method>GET</method>
                </actions>
            </policy>
    3. Update the proxy-config.xml by adding below lines for <policy url="{$ibm_connections_policy}" acf="none" basic-auth-support="true">
            <users>
                <user>AllAuthenticatedUsers</user>           
            </users>
    4. For my testing I also updated Connections Proxy-config.xml at location IBM/WebSphere/proxy-config.xml
   
    5. Restart the server.
   
    6. Next, call below url in portlet to retrive feed without using credentials;
            http://<hostname>:<port>/wps/proxy/http/conserver.com/path/on/server/somefile.xml
           
            Example : https://andiwspdb01.spil.com/social/proxy/http/andiswp01.spil.com/connections/opensocial/basic/rest/activitystreams/urn:lsid:lconn.ibm.com:communities.community:89743724-9899-488a-bd9d-491ee2fed4f6/@all/@status?rollup=true&format=atom
           
           
Ref Url :

http://www-10.lotus.com/ldd/portalwiki.nsf/xpDocViewer.xsp?lookupName=IBM+WebSphere+Portal+7+Product+Documentation#action=openDocument&res_title=Global_proxy_configuration_wp7&content=pdcontent

http://publib.boulder.ibm.com/infocenter/ltscnnct/v2r0/index.jsp?topic=/com.ibm.connections.25.help/t_admin_proxy_ltpa_token.html

http://publib.boulder.ibm.com/infocenter/ltscnnct/v2r0/index.jsp?topic=/com.ibm.connections.25.help/t_admin_config_ajax_proxy.html

http://www-10.lotus.com/ldd/lcwiki.nsf/dx/Setting_up_single_sign-on_between_IBM_Lotus_Connections_2.5_and_Computer_Associates_SiteMinder

http://www-10.lotus.com/ldd/lcwiki.nsf/xpDocViewer.xsp?lookupName=IBM+Connections+4.5+Documentation#action=openDocument&res_title=Enabling_the_AJAX_proxy_to_forward_user_credentials_ic45&content=pdcontent

http://infolib.lotus.com/resources/portal/8.0.0/doc/en_us/PT800ACD002/collab/i_coll_t_enable_lcserver_access.html

http://www-10.lotus.com/ldd/mashupswiki.nsf/page.xsp?documentId=655ED56EB51DE0C5852576CE004BA293&action=openDocument

http://www-10.lotus.com/ldd/mashupswiki.nsf/xpDocViewer.xsp?lookupName=IBM+Mashup+Center+2.0+documentation#action=openDocument&res_title=Configuring_the_AJAX_proxy_with_single_signon__Mashup_Center_2.0&content=pdcontent

http://www-10.lotus.com/ldd/portalwiki.nsf/dx/Troubleshooting_the_Ajax_Proxy_in_Portal

http://www-10.lotus.com/ldd/portalwiki.nsf/dx/The_Ajax_Proxy_in_Portal

Thursday, 6 February 2014

Creating JDBC Provider and DataSource in WebSphere Portal

Ref URL : http://www.websphereusergroup.org/steverobinson/blog/2012/07/23/using_mysql_with_websphere_application_server
 http://www.websphereusergroup.org/go/thread/view/108057/30020763/Error_trying_to_connect_Mysql_Database

 Problem: If server couldn't reach database server. To solve the problem, I got into "custom properties" and set the "url" property with jdbc connection string. Now everything works fine and operative

For MYSQL
---------

** required jar file 'mysql-connector-java-5.1.6.jar'

Process to configure JDBC Provider
----------------------------------
1. Goto Admin console, Resources -> JDBC -> JDBC Provider -> New
2. Select the  Database type  you would like to use from the dropdown list(here i used MYSql so i selected user-defined)
3. Provide Implementation class name for MYSql, i.e. 'com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource'
4. And specify a name and description for jdbc provider.
5. And specify 'mysql-connector-java-5.1.6.jar' file path, i.e. D:/jars/mysql-connector-java-5.1.6.jar
6. And provide Native library path(.dll file path) if requried

Now your JDBC Provider created.

Process to configure Datasource
-------------------------------
1. Goto Admin console, Resources -> Data sources -> New
2. Provide custom Datasourcename and JNDIname
3. Select an existing JDBC Provider just we created.
4. Specify 'Data store helper class name' value with this 'com.ibm.websphere.rsadapter.ConnectJDBCDataStoreHelper'
5. At 'Setup security aliases' dont select any thing just click next and finish.

Now your Data source created, now you have to provide authentication and database details.

6. Now click on Datasource just now we created
7. Here you can see 'JAAS - J2C authentication data' link click on that and select New
8. Now you provide
-> Alias, any name to refer for security
-> User ID, database userid i.e. root for mysql
-> Password, database password, and save.
9. Now here 'JAAS - J2C authentication data' has created which is used to connect to database
10. Now click on Datasource and goto 'Security settings' and configure following properties,
-> Component-managed authentication alias, from drop down select just now created alias name
-> Mapping-configuration alias, from drop down select 'DefaultPrincipalMapping'
-> Container-managed authentication alias, from drop down select just now created alias name, and save.
11. Now click on Datasource and click on 'Custom properties' link
12. Here we need to provide below three properties so that WAS can connect to MySQL
-> serverName (with ip address)
-> port (3306)
-> databaseName  (sumandb)
13. Now restart the portal server to apply changes.








Integrating Connections with Portal

ConfigEngine.bat install-paa -DPAALocation=D:\paa\SNPortlets.paa -DWasPassword=admin -DPortalAdminPwd=admin

ConfigEngine.bat deploy-paa -DappName=SNPortlets -DmaxTimeToWait=30 -DmaxAppTimeToWait=5 -DWasPassword=admin -DPortalAdminPwd=admin

ConfigEngine configure-SNPortlets -DICversion=4.5 -DICblogsHomepageHandle=homepage -DICemailSetting=email-exposed -DICtagSearchType=mysearch -DICdsxAdminId=wasadmin -DICdsxAdminPwd=Password1 -DICbaseURLunsecured=http://connections.socialnet.com -DICbaseURL=https://connections.socialnet.com -DWasPassword=admin -DPortalAdminPwd=admin

(OR, we have to configure connections host name in host file located at Windows/System32/drivers/etc/host)

ConfigEngine configure-SNPortlets -DICversion=4.5 -DICblogsHomepageHandle=homepage -DICemailSetting=email-exposed -DICtagSearchType=mysearch -DICdsxAdminId=wasadmin -DICdsxAdminPwd=Password1 -DICbaseURLunsecured=192.168.1.69 -DICbaseURL=https://192.168.1.69 -DWasPassword=admin -DPortalAdminPwd=admin

Changing WAS Admin Console password

It is not working properly have to do R&D

This is through manual process:
-------------------------------
1. We have to disable security in security.xml file so that we can directly login to IBM Console and change username and password.

2. Path of security.xml file "\IBM\WebSphere\wp_profile\config\cells\TIT-JAVA-010Cell\security.xml"

3. Change very first occurance of enabled="true" to enabled="false" so that security will be disabled.

4. Restart server and access Admin Console without login.

5. In leftside navigation goto Security->GlobalSecurity->SecurityConfigurationWizard->Next->Fedarated Repositories

6. Change username/password and save changes

7. Enable security and restart server. Now you can login into Admin Console with new credentials.


Ref Url : This is through scripting
-----------------------------------
http://kbee.de/2011/11/04/resetting-was-admin-password-when-the-browser-console-does-not-work-anymore/

About AJAX and retrieving connections feed example

AJAX
----
AJAX = Asynchronous JavaScript and XML.

AJAX is not a new programming language, but a new way to use existing(Internet) standards.

AJAX is the art of exchanging data with a server, and updating parts of a web page - without reloading the whole page.
AJAX is about updating parts of a web page, without reloading the whole page.

AJAX applications are browser- and platform-independent!

The keystone of AJAX is the XMLHttpRequest object.

The XMLHttpRequest object is used to exchange data with a server behind the scenes. This means that it is possible to update parts of a web page, without reloading the whole page.

-> 'XMLHttpRequest' object is used for data exchange asynchronusly.

Basic Flow of Ajax
------------------
1. When an event occurs in a browser, an 'XMLHttpRequest' object is created and send that request object to server.
2. In server Http request is processed and send responce to  browser.

There are few methods for XMLHttpRequest to process, they are,
open(method,url,async)
send(string)
setRequestHeader(header,value)

When async=true, 'onreadystatechange' event is used to execute response, this event is triggered every time the 'readyState' changes.

The 'readyState' property holds the status of the XMLHttpRequest.

Three important properties of the 'XMLHttpRequest' object:
onreadystatechange -
Stores a function (or the name of a function) to be called automatically each time the readyState property changes
readyState -
Holds the status of the XMLHttpRequest. Changes from 0 to 4:
0: request not initialized
1: server connection established
2: request received
3: processing request
4: request finished and response is ready
status -
200: "OK"
404: Page not found

To get the response data from the server we use properties 'responseText' & 'responseXML' for xmlhttprequest object.


Sample Example
--------------
<html>

<head>
<script type="text/javascript">
function loadXMLDoc()
{
var xmlhttp;

/* To create an 'XMLHttpRequest' object */
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();  // here xmlhttprequest object is created
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}

    /* 'onreadystatechange' is used when async=true, to execute when the response is ready */
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText; // responseText : gets the response data as a string
// responseXML  : gets the response data as XML
}
}

/* xmlhttprequest object methods are open(method,url,async), send(string) and setRequestHeader(header,value) */
xmlhttp.open("GET","ajax_info.txt",true);
xmlhttp.send();
}
</script>

</head>

<body>
<div id="myDiv"><h2>Let AJAX change this text</h2></div>
<button type="button" onclick="loadXMLDoc()">Change Content</button>
</body>
</html>


Example for retrieving websphere connections feed  in ajax:

var getMyKeyURL = "https://tecnics.connections.com/communities/service/atom/forms/communities/my?sortField=lastmod&inclForum=true&ps=3&forceRefresh=1386773191722";

$.ajax({
type : "GET",
url : getMyKeyURL,
dataType : "xml",
cache : false,
async : true,
success : function(data) {
alert("XML File is loaded!");
alert("data: "+data);
var author = $(data).find("author").last();
alert("author: "+author);
name = $(author).find("name").text();
alert("name: "+name);
myKey = $(author).find("userid").text();
alert("myKey : "+myKey);
},
error: function() {
alert("getMyKey error...!");
}
});



Adding Blog Library and Configuring broadcast links in WCM

Adding Blog Library in WCM
--------------------------
1. Add Blog Library from administration->portal content->web content libraries.
2. Here Blog is refered as SiteArea and Content is reffered as post.
3. Create the required content(post) and configure the portlet.

4. Now you see your websphere blog. In right side we have latest posts. If we click on the latest post it should show complete post with theme. This can be done using broadcast links.

How to configure broadcast links
--------------------------------
1. In 'Blog page' while configuring portlet, in advanced options, in Broadcast Links -- select 'following page' and specify 'page unique name'(ie. testBlog page).
2. Here 'testBlog page' is the new dummy page and 'unique name' should match. And specify same theme.
3. and for 'testBlog page' while configuring portlet, in advanced options, in Broadcast Links -- keep none.

broadcast link works


=============================================

Creating Blogs for Site
-----------------------
Create a content in 'Blog Template V70 library' -- 'central' site area, using authoring template 'Blog Home' which is in 'Web Resources v70'.