Wednesday, November 26, 2014

Updating web.xml for WebSphere Portal

I just found out that starting WebSphere Portal 8, if we need to update web.xml of wps.ear, it is not sufficient to just update web.xml. We also need to update web_merged.xml. The following is the source of information

https://www.ibm.com/developerworks/community/blogs/PortalL2Thoughts/entry/how_to_update_and_redeploy_wps_ear12?lang=en


Friday, November 7, 2014

Deploying theme's static file from one server to the other server

1. Use your browser to get the static files:
http://<firstServer>:<portNumber>/wps/mycontenthandler/dav/themelist/<themename>?mime-type=application/zip

2. Save the zip file and copy the file into the second server

3. In the second server go to /apps/IBM/WebSphere/wp_profile/ConfigEngine

4. Run:
./ConfigEngine.sh webdav-deploy-zip-file -DTargetURI=dav:themelist/<themename/ -DZipFilePath=<path to the zip file> -DUpdateMode=merge -DPortalAdminPwd=<portal admin password> -DWasPassword=<was admin password>

Saturday, October 11, 2014

Installing Business Process Manager Advanced - Process Server

I spent most of Saturday today to try install IBM Business Process Manager Advanced: Process Server. I try to follow the document in IBM Knowledge Center in this address:

http://www-01.ibm.com/support/knowledgecenter/SSFTN5_8.5.5/com.ibm.wbpm.imuc.ebpmps.doc/topics/inst_lin_db2.html

However, it is not straight forward. Here are the issues:
1. In the documentation "Creating DB2 Databases" (http://www-01.ibm.com/support/knowledgecenter/SSFTN5_8.5.5/com.ibm.wbpm.imuc.ebpmps.doc/topics/db_typ_nd_lin_db2.html), it says that we can create database using "createDatabase.sql" file located in "BPM_HOME/BPM/dbscripts/DB2/", however since I have not install completely, that folder and file does not exist. I ended up to create the databases manually using this command:


create database @DB_NAME@ automatic storage yes  using codeset UTF-8 territory US pagesize 32768;
connect to @DB_NAME@;
-- A user temporary tablespace is required to support stored procedures in BPM
create user temporary tablespace usrtmpspc1;
grant dbadm on database to user @DB_USER@;
UPDATE DB CFG FOR @DB_NAME@ USING LOGFILSIZ 16384 DEFERRED;
UPDATE DB CFG FOR @DB_NAME@ USING LOGSECOND 64 DEFERRED;
connect reset;

Note: this is only needed because I want to use existing remote database server.

2. Launchpad will automatically install Installation Manager by default if the installation manager has not been installed in the system. However, it will use default location in /var. However, in my system the /var is small and launchpad requires 3GB minimum. I ended up have to install installation manager prior to running ./launchpad.sh. In addition to that even my system is 64 bit, I need to install 32-bit installation manager.


3. The other thing, do not automatically updates with the latest fixes. The reason is the code will automatically update all fixes including the fixes for 32-bit (note: my system is 64-bit).

Once the above obstacles have been resolved, the installation program start running.


Friday, April 15, 2011

Getting WCM data from IBM's seedlist application.

Using Seedlist 1.0 server, we can retrieve WCM data, the following is IBM's document on how to retrieve WCM data using seedlist REST API

Seedlist REST API

If you are using Dojo to call the API you probably will use xhrGet method, and you can handle the result as XML data (setting handleAs: "xml").

The question is how to retrieve the value of a field.

First of all, we need to get the values from each WCM document. This  can be done by:

data.documentElement.children["<number>"].nodeName.   If the nodeName is "atom:entry" then the children is a  document item. Here is the sample  data.documentElement.children["9"].nodeName

Once we already have the document information, we need to get the specific property from the content item, here is how
console.log("data.documentElement.children["<number>"].children["<number>"].nodeName. The value of nodeName should be "wplc:field". This will indicate that the object is a property of the document.

To know the name of the property you need to use the following statement
data.documentElement.children["<number>"].children["<number>"].attributes[0].nodeValue.  The value of nodeValue is the name of the property

Lastly you need to get the real value of the property by

data.documentElement.children["<number>"].children["<number>"].textContent.  The statement will result on the value of the specific property.

Sample (to get "Name" property of a specific content):

If the value of data.documentElement.children["9"].children["17"].nodeName == "wplc:field" then
   if the value of data.documentElement.children["9"].children["17"].attributes[0].nodeValue == "Name" then
        The value of "Name" is data.documentElement.children["9"].children["17"].textContent

If the statement above is not true then we need to loop through to another array element.

This is based on my test on WebSphere Portal 7.





Friday, February 25, 2011

Changing portal page to use a layout template

If you create a portal page from portal administration user interface:


the chances are you will not be able to use the "PageBuilder2" feature to add new portlet into the page (using "Actions" - "Customize").  To enable the page to use the feature you need to do the following:
1. Export the page definition into xml file
2. Update the xml file by adding the following parameter for the specific <content node>


            <parameter name="com.ibm.portal.layout.template.expiration" type="string" update="set"><![CDATA[1297730961223]]></parameter>
            <parameter name="com.ibm.portal.layout.template.file.name.html" type="string" update="set"><![CDATA[layout.html]]></parameter>
            <parameter name="com.ibm.portal.layout.template.lastmodified" type="string" update="set"><![CDATA[1297644561353]]></parameter>
            <parameter name="com.ibm.portal.layout.template.markup" type="string" update="set"><![CDATA[html]]></parameter>
            <parameter name="com.ibm.portal.layout.template.ref" type="string" update="set"><![CDATA[dav:fs-type1/layout-templates/3ColumnCenter]]></parameter>

into the <content-node> stanza for the specified portal page.

3. We also need to update the type of the content node to "staticpage"

<content-node action="update" active="true" allportletsallowed="true" content-parentref="Z6_020K9B1A0823E0IE07U5O500O0" create-type="explicit" domain="rel" objectid="Z6_020K9B1A0GIU80IE2099SD20H6" ordinal="600" type="staticpage">

4. Re-import the xml file

Hope this helps..

Friday, February 18, 2011

Using SAP extension in WebSphere Portlet Factory and WebSphere Application Server Community Edition

I have WebSphere Portlet Factory 7.0 running on Ubuntu Linux 10.10. I also used WAS CE  version 2.1.1.4 as the test environment.

I have to do the following to allow SAP extension

  • Get the SAPJCo from SAP administrator
  • Install the SAPJCO according to the documentation provided by SAP for linux environment
  • Add class path variable into /etc/environment:
           CLASSPATH="/opt/sapjco/sapjco.jar"
  • Add path to the /opt/sapjco folder. (This is also done in /etc/environment file).  The following is the content of my /etc/environment file
                  PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/sapjco"
                      LD_LIBRARY_PATH="/opt/sapjco"
                        CLASSPATH="/opt/sapjco/sapjco.jar"
      • Add "LD_LIBRARY_PATH=/opt/sapjco" at the end of /etc/bash.bashrc file
      • Restart your system
      • Follow the instruction in http://publib.boulder.ibm.com/infocenter/wpfhelp/v6r1m0/index.jsp?topic=/com.bowstreet.designer.doc/get_start/sap_getting_started.htm
      After the above steps, I am able to do a "Test Connection" from the builder, however, when trying to test the application, I got "noclassdeffounderror" for the jco class. In order to fix that, I have to update geronimo.sh file and add /opt/sapjco, into $EXT_DIRS variable.

      Restart your server after that. Then you should be able to test the model

      Thursday, October 7, 2010

      Redirecting 404 error if users type in invalid URL which starts with /wps/portal

      As a default behavior in portal 6.1.x, if a user type in a url, which starts in /wps/portal/*, in a browser's window, the portal server will automatically redirect user to the first available anonymous page in portal. The example of the URL includes: http://<serveraddress>/wps/portal/invalidpage. Sometimes this behavior is not acceptable by some portal users, the requirements is to let the user knows that the page does not exist or no longer exist.

      In order to change this behavior we need to intercept the http status code 404, and modify the default redirection to redirect to a specified page. The best way to do that is to write a servlet filter and a wrapper for the servlet response.

      • The servlet filter:
        package com.servletFilter;

        import javax.servlet.Filter;
        import javax.servlet.FilterConfig;
        import javax.servlet.ServletException;
        import javax.servlet.http.HttpServletResponse;


        /**
         *
         * This is the servlet filter that wrap the servlet response object
         * and use it in the FilterChain
         * The wrapper will store the status code and do the re-direct if necessary
         */
        public class Redirect404 implements Filter {
          

            public void destroy() {
                // TODO Auto-generated method stub

            }

            public void doFilter(javax.servlet.ServletRequest request, 
                      javax.servlet.ServletResponse response,
                      javax.servlet.FilterChain chain)
                  throws java.io.IOException, javax.servlet.ServletException{

                HttpStatusServletResponse statusResponse =
                    new HttpStatusServletResponse((HttpServletResponse) response);
                chain.doFilter(request, statusResponse);
                int status = statusResponse.getStatus();
                System.out.println("******** Status: " + status);
            }   

            public void init(FilterConfig arg0) throws ServletException {
               
            }
        }
         

        •  The servlet response wrapper
        package com.servletFilter;

        import java.io.IOException;

        import javax.servlet.http.HttpServletResponse;
        import javax.servlet.http.HttpServletResponseWrapper;

        /**
         *
         * This is a wrapper class which is used to store the HTTP Status Code and modify the redirect.
         * 
         */
        public class HttpStatusServletResponse extends HttpServletResponseWrapper {

            private int httpStatus;

            public HttpStatusServletResponse(HttpServletResponse response) {
                super(response);
            }

            @Override
            public void sendError(int sc) throws IOException {
                httpStatus = sc;
                    super.sendError(sc);
            }

            @Override
            public void sendError(int sc, String msg) throws IOException {
                httpStatus = sc;
                    super.sendError(sc, msg);
            }

            @Override
            public void sendRedirect(String location) throws IOException {
                System.out.println("******* Calling sendRedirect, location is: " + location);
                if (httpStatus == SC_NOT_FOUND)
                    location = "/wps/portal/404Error";
                super.sendRedirect(location);
            }

            @Override
            public void setStatus(int sc) {
                httpStatus = sc;
                super.setStatus(sc);
            }

            @Override
            public void flushBuffer() throws java.io.IOException {
                    super.flushBuffer();
            }
           
            public int getStatus() {
                return httpStatus;
            }

        }

          We need to place these class files in a place the classpath of WebSphere Portal server. I placed it in: <portal_root>/shared/ext.

          We also need to modify the web.xml of wps.war, to add the filter definition and filter mapping. The following is the definition:
              <filter>
                  <filter-name>Error 404 Redirect</filter-name>
                  <filter-class>com.servletFilter.Redirect404</filter-class>
              </filter>
              <filter-mapping>
                  <filter-name>Error 404 Redirect</filter-name>
                  <url-pattern>/portal/*</url-pattern>
              </filter-mapping>



          To update web.xml, you will need to export wps.ear (using wsadmin.sh|bat), expand wps.ear (using EARExpander.sh|bat), update web.xml (located at wps.war/WEB-INF), collapse back the wps.ear (using EARExpander.sh|bat), and install the new wps.ear back to portal server (using wsadmin.sh).  The detailed instruction can be found in the following reference: How to redirect to a custom error page when HTTP 404 Not Found encountered on Non-URL Resources ("Resolving the problem" section).


          References: