xmlstarlet to remove XML stanzas

Given our environmnet has both WebSphere v7 and WebSphere v9, we must merge their respective plugins. There are similarly named clusters in both v7 and v9 (e.g. Level_1, Level_2, etc.), and for some reason the GenPluginCfg.sh will merge one (and only one) of the clusters. They’re not even the same clusters in test and prod. In addition, there are unique entries for the cluster in question.

I have noticed this before, but given everything worked as expected through our IHS (aka Apache), it did not register on our radar. However, when I updated our traffic to go through the latest IHS version, we began to see ServerIOTimeouts to the cluster that spans both WAS v7 and WAS v9. We have yet to pinpoint exactly why IHS v9 is more strict than IHS v7, but either way we had to fix this problem.

The error messages were saying it was due to the ServerIOTimeout, but the numbers were not matching with what I had explicitly set for Level_1 servers (60 seconds). This led me to the “Shared Cluster” that the plugin merge had created on its own.

ERROR: ws_common: ServerActionfromReadRC: ServerIOTimeout fired. Time out 1. retry count 0. serverIOTimeoutRetry -1, retry YES, rc 2, server Level_1_was_v9_01_1, URI /someUrl, client port 1234

The plugin-cfg.xml file with the merged and independent pieces look like this:

<ServerCluster CloneSeparatorChange="false" GetDWLMTable="false"
	IgnoreAffinityRequests="true" LoadBalance="Round Robin"
	Name="Shared_3_Cluster_0" PostBufferSize="64" PostSizeLimit="-1"
	RemoveSpecialHeaders="true" RetryInterval="60" ServerIOTimeoutRetry="-1">
	<Server CloneID="1basreo4a" ConnectTimeout="5"
		ExtendedHandshake="false" LoadBalanceWeight="77"
		MaxConnections="0"
		Name="wasv901Node_Level_1_was_v9_01_1"
		ServerIOTimeout="-1" WaitForContinue="false">
		<Transport ConnectionTTL="28" Hostname="wasv901"
			Port="9445" Protocol="https">
			<Property Name="keyring" Value="/ihs/security/plugin-key.kdb"/>
			<Property Name="stashfile" Value="/ihs/security/plugin-key.sth"/>
		</Transport>
	</Server>
	<Server CloneID="1692lco3o" ConnectTimeout="90"
		ExtendedHandshake="false" LoadBalanceWeight="77"
		MaxConnections="-1"
		Name="wasv701Node_Level_1_WAS_v7_01_0"
		ServerIOTimeout="-1" WaitForContinue="false">
		<Transport Hostname="wasv701.company.com" Port="30006" Protocol="http"/>
		<Transport Hostname="wasv701.company.com" Port="31006" Protocol="https">
			<Property Name="keyring" Value="/ihs/security/plugin-key.kdb"/>
			<Property Name="stashfile" Value="/ihs/security/plugin-key.sth"/>
		</Transport>
	</Server>
	<Server CloneID="1692lcpij" ConnectTimeout="90"
		ExtendedHandshake="false" LoadBalanceWeight="77"
		MaxConnections="-1"
		Name="wasv702Node_Level_1_WAS_v7_02_0"
		ServerIOTimeout="-1" WaitForContinue="false">
		<Transport Hostname="wasv702.company.com" Port="30006" Protocol="http"/>
		<Transport Hostname="wasv702.company.com" Port="31006" Protocol="https">
			<Property Name="keyring" Value="/ihs/security/plugin-key.kdb"/>
			<Property Name="stashfile" Value="/ihs/security/plugin-key.sth"/>
		</Transport>
	</Server>
	<Server CloneID="1bassd4fp" ConnectTimeout="5"
		ExtendedHandshake="false" LoadBalanceWeight="77"
		MaxConnections="0"
		Name="wasv902Node_Level_1_was_v9_02_1"
		ServerIOTimeout="-1" WaitForContinue="false">
		<Transport ConnectionTTL="28" Hostname="wasv902"
			Port="9445" Protocol="https">
			<Property Name="keyring" Value="/ihs/security/plugin-key.kdb"/>
			<Property Name="stashfile" Value="/ihs/security/plugin-key.sth"/>
		</Transport>
	</Server>
	<PrimaryServers>
		<Server Name="wasv901Node_Level_1_was_v9_01_1"/>
		<Server Name="wasv702Node_Level_1_WAS_v7_02_0"/>
		<Server Name="wasv902Node_Level_1_was_v9_02_1"/>
	</PrimaryServers>
	<BackupServers>
		<Server Name="wasv701Node_Level_1_WAS_v7_01_0"/>
	</BackupServers>
</ServerCluster>

	
<!-- WAS v7 -->
<ServerCluster CloneSeparatorChange="false" GetDWLMTable="false"
	IgnoreAffinityRequests="true" LoadBalance="Round Robin"
	Name="Level_1_0" PostBufferSize="64" PostSizeLimit="-1"
	RemoveSpecialHeaders="true" RetryInterval="60" ServerIOTimeoutRetry="-1">
	<Server CloneID="1692lco3o" ConnectTimeout="90"
		ExtendedHandshake="false" LoadBalanceWeight="77"
		MaxConnections="-1" Name="wasv701Node_Level_1_WAS_v7_01"
		ServerIOTimeout="60" WaitForContinue="false">
		<Transport Hostname="wasv701.company.com" Port="30006" Protocol="http"/>
		<Transport Hostname="wasv701.company.com" Port="31006" Protocol="https">
			<Property Name="keyring" Value="/ihs/security/plugin-key.kdb"/>
			<Property Name="stashfile" Value="/ihs/security/plugin-key.sth"/>
		</Transport>
	</Server>
	<Server CloneID="1692lcpij" ConnectTimeout="90"
		ExtendedHandshake="false" LoadBalanceWeight="77"
		MaxConnections="-1" Name="wasv702Node_Level_1_WAS_v7_02"
		ServerIOTimeout="60" WaitForContinue="false">
		<Transport Hostname="wasv702.company.com" Port="30006" Protocol="http"/>
		<Transport Hostname="wasv702.company.com" Port="31006" Protocol="https">
			<Property Name="keyring" Value="/ihs/security/plugin-key.kdb"/>
			<Property Name="stashfile" Value="/ihs/security/plugin-key.sth"/>
		</Transport>
	</Server>
	<PrimaryServers>
		<Server Name="wasv702Node_Level_1_WAS_v7_02"/>
	</PrimaryServers>
	<BackupServers>
		<Server Name="wasv701Node_Level_1_WAS_v7_01"/>
	</BackupServers>
</ServerCluster>


<!-- WAS v9 -->
<ServerCluster CloneSeparatorChange="false" GetDWLMTable="true"
	IgnoreAffinityRequests="false" LoadBalance="Round Robin"
	Name="Level_1_1" PostBufferSize="0" PostSizeLimit="-1"
	RemoveSpecialHeaders="true" RetryInterval="60" ServerIOTimeoutRetry="-1">
	<Server CloneID="1basreo4a" ConnectTimeout="5"
		ExtendedHandshake="false" LoadBalanceWeight="77"
		MaxConnections="0"
		Name="wasv901Node_Level_1_was_v9_01"
		ServerIOTimeout="60" WaitForContinue="false">
		<Transport ConnectionTTL="28" Hostname="wasv901"
			Port="9445" Protocol="https">
			<Property Name="keyring" Value="/ihs/security/plugin-key.kdb"/>
			<Property Name="stashfile" Value="/ihs/security/plugin-key.sth"/>
		</Transport>
	</Server>
	<Server CloneID="1bassd4fp" ConnectTimeout="5"
		ExtendedHandshake="false" LoadBalanceWeight="77"
		MaxConnections="0"
		Name="wasv902Node_Level_1_was_v9_02"
		ServerIOTimeout="60" WaitForContinue="false">
		<Transport ConnectionTTL="28" Hostname="wasv902"
			Port="9445" Protocol="https">
			<Property Name="keyring" Value="/ihs/security/plugin-key.kdb"/>
			<Property Name="stashfile" Value="/ihs/security/plugin-key.sth"/>
		</Transport>
	</Server>
	<PrimaryServers>
		<Server Name="wasv901Node_Level_1_was_v9_01"/>
		<Server Name="wasv902Node_Level_1_was_v9_02"/>
	</PrimaryServers>
</ServerCluster>

My first thought was to see if I could prevent the GenPluginCfg.sh script from merging these clusters together, but that proved to be a waste of time. I then thought to just delete this part from Test’s plugin-cfg.xml file to see if it worked, and to my delight it worked fine without issue.

Sometimes there are unintended consequences, so I put all this info into an IBM Support ticket, and had their brain power evaluate the problem at large. They said this is a poor implementation choice on their side (to merge the clusters), but they’ve seen it before and there was no time table to fix it.

I told them about my idea to just simply remove the “shared” related parts of the plugin-cfg.xml and they said that would be a perfectly fine way to fix this problem.

I first started trying to use some form of awk/sed/gawk to solve this, but those were proving to be close, but no cigar. This then led me to xmlstarlet to parse XML, which I put in another Unix script to manipulate the plugin-cfg.xml after the merge had occurred, but before it was sent out to my IHS servers:

xpathShared=`xml el -v ${PLUGIN_TEMP} | grep UriGroup | grep Shared_`
xmlstarlet ed -d "$xpathShared" plugin-cfg.xml > xml1

xpathShared=`xml el -v xml1 | grep ServerCluster | grep Shared_`
xmlstarlet ed -d "$xpathShared" xml1 > xml2

xpathShared=`xml el -v xml2 | grep Route | grep sharedCell_`
xmlstarlet ed -d "$xpathShared" xml2 > xml3

xpathShared=`xml el -v xml3 | grep UriGroup | grep sharedCell_`
xmlstarlet ed -d "$xpathShared" xml3 > xml4

xpathShared=`xml el -v xml4 | grep VirtualHost | grep sharedCell_`
xmlstarlet ed -d "$xpathShared" xml4 > plugin-cfg.xml

This script greatly simplified the removal of the unnecessary merged stanzas, and is much more maintainable then even if I had gotten the awk/sed commands to work.

WAS restart script to kill off hung threads

Our WebSphere environment has nightly restarts because some of the apps are so shitty that they cannot run for more than 24 hours at a time and app owners do not care (another conversation for another day). Given this piece of information a long time ago we implemented nightly restarts that will reboot all apps on a given cluster.

Every so often we get a Splunk notification that a cluster node is not back up and running, and then when we investigate, we find that no java processes are running on this machine. After digging into it, I discovered that our script attempts to shut down each AppServer, but since a rogue app has a hung thread that is preventing the stopServer.sh command from completing.

To combat this in our Restart_AppServer.sh script, I have utilized the ‘timeout’ and ‘pgrep’ commands.

The timeout command was pretty straight forward: if the call does not return in the provided amount of seconds, then kill the command trying to run.

pgrep is also a pretty straight forward command, but the only problem with it is that the Restart_AppServer.sh command contains a parameter that is the name of the server. So if you have an AppServer named ‘Level_1’ then when you do a ‘pgrep -f Level_1’ you will get 2 PIDs: the one for the AppServer, and one for the Restart_AppServer.sh.

To get around this I looked up the PID of the Restart_AppServer.sh script, and then removed it from the grep command using the ‘-v’ option which is used to remove results from the result set.

timeout to stop the server, but kills the attempt if it doesn’t complete in time.

timeout 120 ${WAS_ROOT}/bin/stopServer.sh ${wrk_server}

pgrep grabs the process ID(s) of whatever you’re grepping for.

CONTROLLER_SCRIPT_PID=`pgrep -f Controller`
echo &quot;********** pid =  ${CONTROLLER_SCRIPT_PID}&quot;

SERVER_PID=`pgrep -f $1 | grep -v ${CONTROLLER_SCRIPT_PID}`
echo &quot;********** $1 pid =  ${SERVER_PID}&quot;
if [[ ${SERVER_PID} != &quot;&quot; ]]
then
    echo &quot;### ERROR ### AppServer $1 could not be shutdown gracefully, and had to be killed&quot; &gt;&gt; ${TEMP_LOG}
    pgrep -f $1 | grep -v ${CONTROLLER_SCRIPT_PID} | xargs kill -9
fi

Fix WebSphere OutOfMemory error during deployment

Deployments within the WebSphere v7 environment were randomly failing with OutOfMemory (OOM) errors. We initially thought it was due to a very large EAR file being deployed, but after a while, this theory was inconsistent because OOMs occurred with small and large EARs alike. Within the SystemOut.log, we found this error:

[1/10/14 06:17:51:553 CST] 00000000 AbstractShell E   WASX7120E: Diagnostic information from exception with text "com.ibm.websphere.management.application.client.AppDeploymentException: com.ibm.websphere.management.application.client.AppDeploymentException [Root exception is java.lang.OutOfMemoryError]
java.lang.OutOfMemoryError: java.lang.OutOfMemoryError " follows:

 com.ibm.websphere.management.application.client.AppDeploymentException [Root exception is java.lang.OutOfMemoryError]
    at com.ibm.ws.management.application.client.AppInstallHelper.getAppDeploymentInfoGenericRead(AppInstallHelper.java:520)
    at com.ibm.ws.management.application.client.DefaultBindingHelper.prepareTask(DefaultBindingHelper.java:216)
    at com.ibm.ws.scripting.AdminAppClient.createPreferences(AdminAppClient.java:2885)
    ...
    at org.eclipse.core.launcher.Main.basicRun(Main.java:282)
    at org.eclipse.core.launcher.Main.run(Main.java:981)
    at com.ibm.wsspi.bootstrap.WSPreLauncher.launchEclipse(WSPreLauncher.java:341)
    at com.ibm.wsspi.bootstrap.WSPreLauncher.main(WSPreLauncher.java:111)
Caused by: java.lang.OutOfMemoryError
    at org.objectweb.asm.Type.getDescriptor(Unknown Source)
    at com.ibm.ws.amm.scan.util.info.impl.InfoImpl.getClassName(InfoImpl.java:217)
    at com.ibm.ws.amm.scan.util.info.impl.InfoImpl.getClassInfo(InfoImpl.java:158)
    ...

From the install script, we saw this error:

[1/10/14 06:17:52:941 CST] 00000000 AbstractShell A   WASX7093I: Issuing message: "WASX7017E: Exception received while running file "/websphere/utilities/scripts/installNewApplication.py"; exception information: com.ibm.websphere.management.application.client.AppDeploymentException: com.ibm.websphere.management.application.client.AppDeploymentException [Root exception is java.lang.OutOfMemoryError]
java.lang.OutOfMemoryError: java.lang.OutOfMemoryError

We knew we had to increase the heap size of the deployment manager, but that turned out to be a little less obvious then anticipated.

The Python script used to kickoff the install eventually calls the Profile’s (Dmgr) script: /websphere/AppServer/profiles/Dmgr/bin GenPluginCfg.sh

#!/bin/sh
binDir=`dirname ${0}`
. ${binDir}/setupCmdLine.sh
${WAS_HOME}/bin/GenPluginCfg.sh "$@"

The last line of the profile’s GenPluginCfg.sh calls the cell’s version of GenPluginCfg.sh, which is where the heap can be adjusted as needed (-Xmx):

"$JAVA_HOME/bin/java" -Xmx1024m 
  -Dserver.root="$WAS_HOME" 
  $CLIENTSAS 
  -Dws.ext.dirs="$WAS_EXT_DIRS" 
  $USER_INSTALL_PROP 
  $WAS_LOGGING 
  -classpath "$WAS_CLASSPATH" com.ibm.ws.bootstrap.WSLauncher 
  com.ibm.websphere.plugincfg.generator.PluginConfigGenerator "$WAS_HOME" "$CONFIG_ROOT" "$WAS_CELL" "$WAS_NODE" $@

Don’t forget to backup any script you plan to alter before making updates. No reason to make a fat-finger mistake that causes a cryptic error message and takes forever to figure out.

Cloned Cluster on WebSphere does not start

We had a need to create a new cluster of WebSphere 7 JVMs (Cluster_B) that are identical to an existing cluster (Cluster_A).  No problem, an easy task that I’ve done many times before. I proceeded to venture through the WAS console to create a new cluster using the existing Cluster_A_was01 member as a template. The new config was told to create new ports, I clicked through the save buttons, and gave the cluster members a few minutes to ensure they were synced up properly with the new configuration.

Everything worked as expected right up to the point that the server did not start after issuing the start command from the CLI (Command Line Interface).

websphere_01:~> /was/AppServer/profiles/AppServer/bin/startServer.sh Cluster_B
ADMU0116I: Tool information is being logged in file
/was/AppServer/profiles/AppServer/logs/Cluster_B/startServer.log
ADMU0128I: Starting tool with the AppServer profile
ADMU3100I: Reading configuration for server: Cluster_B
ADMU3200I: Server launched. Waiting for initialization status.
ADMU3011E: Server launched but failed initialization. startServer.log,
SystemOut.log(or job log in zOS) and other log files under
/was/AppServer/profiles/AppServer/logs/Cluster_B
should contain failure information.
websphere_01:~>

This is a new server, that was cloned from an existing one, so there could be a conflict of a param that I missed (ports, cookie names, etc.).  I look inside the Cluster_B log directory, and there is no SystemOut.log to be found.

websphere_01:~> cd /was/AppServer/profiles/AppServer/logs/Cluster_B
websphere_01:/was/AppServer/profiles/AppServer/logs/Cluster_B> ls -latr
total 16
-rw-r–r–  1 websphereUser websphereGroup    0 2014-02-26 15:19 native_stdout.log
-rw-r–r–  1 websphereUser websphereGroup    5 2014-02-26 15:35 Cluster_B.pid
-rw-r–r–  1 websphereUser websphereGroup 1935 2014-02-28 13:26 startServer.log
-rw-r–r–  1 websphereUser websphereGroup 2259 2014-02-28 13:26 native_stderr.log

Note that I tried to start the server, it failed, and told me to look in the SystemOut.log.  There is no SystemOut.log listed.  I’m now in uncharted waters.  I’ve never seen an instance of starting up a new JVM where no SystemOut.log or SystemErr.log is created.  Thanks for mutton WebSphere.

After verifying the ports are different from the cloned JVM from Cluster_A, kicking kittens, and other config comparisons, I thought to look at the JVM args, which would be identical to Cluster_A, since it is a clone.  I see that AppDynamics is there, and right next them are the bane of the past couple of hours: a check mark next to Debug with the port set to 7777, just like Cluster_A’s debug configuration.

To be sure that the identical debug ports are the issue (and not AppD), I first remove the AppDynamics JVM params and try again.  Failure.  Next the debug config is removed altogether, and the server boots right up.  I changed the debug port on Cluster_B to 7778, reboot, and it again starts right up.

It would have been nice for the WAS server to let me know that there was a debug port conflict, instead of me fumbling around in the dark with no idea of where to start.  It would have saved me a couple of hours, and several kicks to kittens.

 

JMeter timestamps in excel

I’m doing some APM (app performance management) on a very sh!tty app written in 1995 for a migration from WebSphere 6.1 to WAS 7.0, and I ran into an issue when trying to paste some JMeter timestamps into an email. The formatting was all off when just highlighting the aggregate data and pasting it into an email, so I thought I’d try Excel.

To my surprise, the data was paste job into Excel went right into columns and rows, which was a nice perk. Unfortunately, the timestamps did not automatically port to dates, but luckily I found this formula, which will be useful in the future since we are using JMeter more and more for APM at work.

= (CELL_REFERNCE / 86400000) + 25569

After making the formula change above, and setting the column’s format to date, I was able to then select the table and paste it into an email for all to see.

WebSphere 7 app startup exception without a hint

I received the error below after making an update to my app. As you can see there is nothing but IBM specific code in the stack trace. So I had a good idea which app was causing the error, but there is no indication as to which part of my code is the offender. After multiple debug sessions and System.println.out() in the constructor, I was able to find that my .properties files were not being loaded properly.

It’s not that WebSphere is a terrible app server, it’s just that it’s so freakin’ expensive for what you get.


[9/19/13 16:17:55:564 CDT] 0000002e servlet E com.ibm.ws.webcontainer.servlet.ServletWrapper run [Servlet Error]-[class java.lang.NullPointerException: null]: java.lang.ClassNotFoundException: class java.lang.NullPointerException: null
at java.beans.Beans.instantiate(Unknown Source)
at java.beans.Beans.instantiate(Unknown Source)
at com.ibm.ws.webcontainer.servlet.ServletWrapper$1.run(ServletWrapper.java:1909)
at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:118)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.loadServlet(ServletWrapper.java:1900)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:730)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:502)
at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:181)
at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:3944)
at com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:276)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:931)
at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1592)
at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:186)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:452)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:511)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:305)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java:276)
at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:214)
at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:113)
at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)
at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
at com.ibm.io.async.AsyncChannelFuture$1.run(AsyncChannelFuture.java:205)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1646)

WebSphere Portal: log4j to SystemOut.log

A requirement came across my desk to make the log4j output be directed to the SystemOut.log file instead of the logfile of choice configured within log4j. (See my previous post on WebSphere Portal & Log4j) I am still pretty knew to WebSphere and where output goes and what is considered the “console” log file, but I thought I would just start by configuring my log4j.xml file to output all data to the console instead of the log file I originally configured.

Luckily this update worked like a charm. That is the first time something worked as expected with Portal, and will probably be the last.

WebSphere Portal: Access Page Parameters from Portlet

I had a scenario where I wanted to retrieve certain WebSphere Page parameters that are setup on a page.
This occurred because we had a Portal Page and a Virtual Portal Page using the same Portlet, and
we wanted certain business logic to be applied depending upon the parameter setup via the admin console
for each of the respective pages.

I do not in any way admit to knowing exactly what is going on below here. It took a long time to
search the web and find this piece of information, and I hope someone else finds it here faster then
it took me to find it.

public Map retrieveStringsFromPageParameters(PortletRequest req, PortletResponse resp, List pageParamsToRetrieve){
Map toRet = null;
try{
Context ctx = new InitialContext();

PortletServiceHome psh = (PortletServiceHome) ctx.lookup("portletservice/" + NavigationSelectionModelProvider.class.getName());

if (psh != null) {
ContentMetaDataModelProvider cmdmProvider = (ContentMetaDataModelProvider) psh.getPortletService(ContentMetaDataModelProvider .class);
ContentMetaDataModel cmdm = cmdmProvider.getContentMetaDataModel(req, resp);
NavigationSelectionModelProvider provider = (NavigationSelectionModelProvider) psh.getPortletService(NavigationSelectionModelProvider.class);
NavigationSelectionModel model = provider.getNavigationSelectionModel(req, resp);
NavigationNode selectedNode = (NavigationNode) model.getSelectedNode();

if (selectedNode != null) {
MetaData md = cmdm.getMetaData(selectedNode);

if(md != null){
toRet = new HashMap();
for(Iterator itr = pageParamsToRetrieve.iterator(); itr.hasNext(); ){
String pageParamToGet = (String) itr.next();
String pageParamValue = (String)md.getValue(pageParamToGet);

toRet.put(pageParamToGet, pageParamValue);
}
}
}
}
}catch (Exception e){
logger.debug(e);
}
return toRet;
}

Get DistinguishedName from LTPA Cookie

This code will grab the DistinguishedName from the LTPA Cookie, but you can retrieve anything else you need as well.
I used this code within a Custom Tag that I created.


public static synchronized String getDistinguishedNameFromLtpaCookie(HttpServletRequest req){
Cookie[] cookies = req.getCookies();
String cookieVal = null;

if(null != cookies) {
for(int i = 0; i &amp;lt; cookies.length; i++) {
if(cookies[i].getName().equalsIgnoreCase(LTPA_TOKEN)) {
cookieVal = cookies[i].getValue();
break;
}
}
}

String uniqueId = null;
String distinguishedName = null;

try{
byte[] cookieBytes = com.ibm.websphere.security.WSSecurityHelper.convertCookieStringToBytes(cookieVal);
uniqueId = com.ibm.wsspi.security.token.WSSecurityPropagationHelper.validateLTPAToken(cookieBytes);
distinguishedName = com.ibm.wsspi.security.token.WSSecurityPropagationHelper.getUserFromUniqueID(uniqueId);
} catch(Exception e){
System.out.println(&quot;UserDomainLookupTag.doStartTag(): Exception occurred while retrieving LTPA cookie: &quot; + e);
}

return distinguishedName;
}

The required WebSphere jars:

– wssec.jar
– sas.jar


your code here

Websphere Portal: Reference Custom Tag in Theme

This is for WebSphere Portal v6.0

(do a google search if you do not know how to create a Tag)

Put your custom jar that contains the Tag classes in:
/opt/IBM/WebSphere/PortalServer/shared/app

Put your TLD files in:
/opt/IBM/WebSphere/AppServer/profiles/<profile>/installedApps/<node>/wps.ear/wps.war/WEB-INF/tld

What I do not understand is how the tld is read. I would have expected to have to register the TLD
in some web.xml file, but that is not the case here. So WebSphere has to be doing this in the background somewhere.

Restart your Portal server, and you can now reference your tag from within your theme.

One HUGE drawback of this solution is that you have to restart the Portal server
if you make an update to your TLD or Tag jar and push them out to their
respective locations.