Cognos Servlet Gateway Error: CAM-CRP-0157

I am making some updates to the Servlet Gateway, while another team member was making updates to the Dispatcher. He made his updates first, and then I deployed a new version of my Gateway, which gave users the following error after they entered their username & password:

<errorDetail><errorCode>-13</errorCode><errorMessage>CAM-CRP-0157 Unable to complete a call to the cryptographic provider’s unwrap function.</errorMessage><errorStack><errorCode>-13</errorCode><errorMessage>CAM-CRP-0285 Unable to find an appropriate Common Symmetric Key (CSK) to decrypt the data.</errorMessage></errorStack></errorDetail>

We solved this problem by following the steps in this link:

http://www-01.ibm.com/support/docview.wss?uid=swg21340774

Keep in mind that some of the items you are deleting are files, and some are directories.

We have no flippin’ idea how this problem occurred, and we will probably not look too hard into it unless it happens again.
These types of rogue errors with no good explanation occur too frequently in Cognos.

crap, I’ve got to work on sh*tty IBM Portal stuff again

I’m having to make updates to our IBM Portal again, and honestly, I’m not too excited about it. As a developer, it is very frustrating working on a technology that is as backwards and non-intuitive as IBM Portal.

Portal probably has its place in solving some business problem (although I have not seen one yet), but I’d really like to meet the salesperson who sold my company on the fact that IBM Portal would solve their issues.

What we are trying to accomplish could so easily be done with simple Servlets and static HTML pages with a CMS system front-end. Hell, you don’t even need Spring MVC or Struts.

WebSphere Portal: Export Page error

I am very surprised to see that more people have not run into this issue in WebSphere 6.0.1.6:

Scenario: You go to export a page from the Portal Console, and you receive a 403 Forbidden page, instead of the exported file. I then went through the logs and discovered the error:

[10/7/09 14:04:53:935 CDT] 00000062 WebCollaborat A SECJ0129E: Authorization failed for scconlo while invoking GET on default_host:/wps/PA_1_NO2UF4I1186E1026H4BLVI00L6/exportServlet, Authorization failed, Not granted any of the required roles: exportPortalPagesRole
[10/7/09 14:05:27:796 CDT] 00000062 WebCollaborat A SECJ0129E: Authorization failed for scconlo while invoking GET on default_host:/wps/PA_1_NO2UF4I1186E1026H4BLVI00L6/exportServlet, Authorization failed, Not granted any of the required roles: exportPortalPagesRole

However, I do a Google Search for “websphere portal 403 exportPortalPagesRole” (http://lmgtfy.com/?q=websphere+portal+403+exportPortalPagesRole), and there is 1 result returned: http://dev.binarysoul.net/2009/08/11/2-bugs-in-websphere-portal-6-0-1-6-fix-pack/

This is a great post by “Jonathan”, which details the problem and the solution.

Check it out if you have the aforementioned issue.

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.

WebSphere Portal & Log4j Hell

I am still getting acquainted with WebSphere Portal, and to make things more difficult, I do not have a debug-able server to test on (yet).  This is very disappointing because I think debugging is a great way to become more familiar with a new technology.

Anyway, due to the lack of a debugger, I am constantly having to use logging as a means to debug my code base.  It did not take long before I became quite disappointed with the WebSphere provided logging capabilities, and desired to integrate log4j within my Portlet.  However, this was much more difficult then it should have been.

I setup JCL (Jakarta Commons Logging) like I have used on any other project in my past (web.xml listener, log4j.xml, include the proper .jars, etc.), but I saw some very odd functionality: when my portlet was deployed, the MyPortlet.log file was created, but nothing was logged into the file.

My first thoughts were that I had improperly configured my log4j.xml, so I swapped out an even simpler log4j.properties file with a new file name (MyPortlet_2.log) just to see if that file would be created as well.  I then deployed my portlet, and again it created the log file (MyPortlet_2.log) but nothing was logged there.

I then checked SystemOut.log, SystemError.log, and trace.log, and none of them had my log messages.  This was very odd, so I then decided to see what the implementation was returned by the code:

private Log log = LogFactory.getLog(MyPortletClass.class);

I saw that log was an instance of Jdk14Logger, instead of the JCL version I was expecting. I then looked at the server to see what libraries were in the classpath above my portlet, and discovered that the “ws-commons-logging.jar” contains a file named “commons-logging.properties”, and low and behold, it had:

org.apache.commons.logging.LogFactory = org.apache.commons.logging.impl.Jdk14Factory org.apache.commons.logging.Log = org.apache.commons.logging.impl.Jdk14Logger

Not at all what I was expecting.  I then realized the problem: there was a commons-logging.properties higher in the classpath then the one I was providing.

After many hours of Google searches and Websphere Portal research, I finally figured discovered a few options to elegantly solve this problem: http://www-01.ibm.com/support/docview.wss?uid=swg27010153&aid=1
However, I did not want to go down any of these paths. So, I simply just used the Log4j interfaces instead of using the Commons-Logging (JCL) interfaces, and it worked like a charm.

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Foo {

private Log log = LogFactory.getLog(Foo.class);

}

***** My version

import org.apache.log4j.Logger;
public class blah{

private static final Logger logger = Logger.getLogger(LdapService.class);

}

SoapUI

I am on a two-man team that has been hired by a client to test one of the 3rd party’s (3P-A) Web Services with another one of their 3rd (3P-B)party’s Web Services. The way we will be testing these services is via SoapUI.

I have used SoapUI on previous projects, but it was at a very, very basic level (simple mocked requests and verify responses visually). For this client, we want to perform verification (assertions) programatically, and perform load testing. Their services are still in progress, and we will need to Mock both 3rd party services from their provided WSDLs.

  • What this article covers:
    • Project setup
    • Basic Properties
    • Test Suites
    • Assertions
    • Request/ Response configuration
    • Load Testing
    • Mock Services

  • What this article does NOT cover:
    • WS-Security
    • High volume Transactions
    • Integration with Ant and TestNG (future article)
    • Groovy Scripting

Review

Overall, this tool has been very helpful at every client. There are some shortcomings, which I point out, but so far it is the easiest of all the other Web Service testing tools (JMeter, Grinder) to get started with. It may not be as robust as others, but so far it appears to be the easiest to use.


Project Setup

You will need

– Eclipse

– JDK 1.5+

– Tomcat 5+

– SoapUI 2.5.1

  • SoapUI 3.0 is coming soon, but we will use 2.5.1

With the help of some service code I found online (http://www.javacoda.com/blog/?p=22) I have created my own services and put together two simple WSDL operations for us to test.

Download the service code <link>, and import it into an Eclipse project. Once you have the project in your workspace, place the build.xml file into the Ant window. Open the build.xml file and replace the tomcat.dir with your Tomcat instance’s location.

You can now deploy the service’s war file by following these steps: double-click the “deploy” Ant target, start Tomcat, and navigate to http://localhost:8080/jaxws_example_1/services/order?wsdl. If you see the WSDL, everything was setup successfully. If you see errors, you may want to verify that your port number is correct within Tomcat’s /conf/server.xml file, and you may want to start over from scratch if problems persist.


SoapUI Setup

Open SoapUI, and from the menu, select File-> New Soap Project. Give your project a name (e.g. SoapProject_1), and for the WSDL location, put: http://localhost:8080/jaxws_example_1/services/order?wsdl. Make sure that the 3rd check box from the top is check, which will automatically create your Mock Service. A couple more pop-ups will appear because we have checked these check boxes, but simply click “OK” on each of them (the defaults are what we desire).

One of the more annoying nuances of SoapUI is that it does not automatically save your updates. You must save them automatically. Push either Ctrl-S or the save symbol near the top left of the window, and save the soapui-project.xml file (use its default name) to your desired location.

Your SoapUI workspace should now look like the following:

Navigator_pane

Properties

Properties are project variables, which can be set at any level of your project.

Double click on the top level node (SoapProject_1) of your project, which will bring up the project’s configuration window, and select the “Properties” tab on the bottom left. From here, select the “Add a property to the property list” button.

Add_Endpoint_Property_to_Project

Name your property “DefaultOrderServiceEndpoint_Property”, and give it the default location of: http://localhost:8080/jaxws_example_1/services/order. In the future, you can reference this property via: ${#Project# DefaultOrderServiceEndpoint_Property}. This will be a handy property, which will allow us to easily change the endpoint our tests are pointing at.

For example, if a WSDL has been agreed upon by the client and service dev teams, the client dev team can use SoapUI to Mock the services (more on this later) and not lose time while the service dev team is still in progress. The client team will then update this property to point to their Mock Service instead of the default endpoint value. They will also be able to mock the responses coming back from the Mocked Service method calls as well (more on this later too).

Test Suites

A Test Suite is a group of tests that can include any number of “Steps” that can be be run together in one execution, or individually in isolation. There are two types of tests: Functional Tests and Load Tests.

– Functional Tests

Right-click on the top level node for the project (SoapProject_1), and select “New Test Suite”. Next, right-click on the newly created Test Suite 1, and select “New Test Case”. This will bring up a window where you can add steps to the test. Let’s add a new request step by right-clicking on the “Test Case 1”, and give it the name “placeOrderTest”. Then select the placeOrder method from the drop down list, and select all of the check boxes before you select OK. You can now run the test by right-clicking on the Test Suite 1, select “Launch TestRunner”, and select OK.

You probably noticed that our tests did not pass all of the Assertions (more on Assertions later). This is because the default character of choice by SoapUI is a single “?”, which threw a fault when it tried to convert the price into a number. We now need to go into the request and add some additional valid dummy data to all fields.

Alter_Request_Values

We also want the endpoint to be configurable by using a property, which we created earlier. Click on the drop down URL at the top center of the window above and select “Add new endpoint”. Set the endpoint to the Project property we created earlier: “${#Project# DefaultOrderServiceEndpoint_Property}”. This will allow you to set the endpoint at the global level for the tests.

If you would like to add additional steps to the Test Case, simply right click on the test case and select “Add Step”. Try and add the delayForProvidedNumberOfSeconds() method to the Test Suite, and run both Test Cases at once. Don’t forget to set the endpoint to point to the Property we configured earlier.

Note: Another problem with SoapUI’s implementation of the Test Suite feature is that it completely ignores Load Tests that exist within the Test Suite. I understand their logic for this, and can easily see where it could be annoying to run load tests along with your function tests, especially when some load tests can take a great deal of time. However, I wish they would have separated the Load Tests into their own suites, so I could run all of my Load Tests together in one execution.

– Load Tests

Under our “Test Case 1” node, there is the sub-element: Load Tests. Right click on this sub-element, and select “New Load Test”. By default, it includes the Test Steps already provided in the Test Suite. You can now tweak the settings as you see fit in order to Load Test your services. Please see the SoapUI documentation on the different Load Test settings and strategies: http://www.soapui.org/userguide/loadtest/configuration.html

Note: The Burst Strategy does NOT work in the 2.5.1 version of SoapUI. In a forum thread that I started, they said that it should work in the nightly releases, but I checked out the http://www.eviware.com/forums/index.php?topic=1830.0 and it did NOT work in that release either.

Update: The nightly build has been fixed as of 6/05, and will be included in the 3.0 release.

Assertions

Assertions can be applied at almost any level within a SoapUI project. As you have already seen, we had SoapUI generate a few Assertions in the last section when we setup our Test Suite.

The two most likely places you will use assertions:

– Load Testing: http://www.soapui.org/userguide/loadtest/assertions.html

– Test Cases: http://www.soapui.org/userguide/functional/response-assertions.html

Mock Services

SoapUI allows you to create your own Mock Services from a given WSDL, which will allow you to customize the responses to certain requests. Since we created these Mock Services when we first setup the project (one of the checkboxes from earlier), all we have to do now is set the services port and then start the services.

Double-click on the “DefaultOrderServicePortBinding Mock Service”, and then click on the options icon next to the green arrow (looks like tools). Set your port to 3033, click OK, and then click on the green arrow. Your Mock Service is now up and running. Adjust the Property that we set earlier in this article (DefaultOrderServiceEndpoint_Property ) to use port 3033 instead of the default.

One of the more annoying aspects of SoapUI is that you can start the Mock Services externally (outside of the GUI and outside the console), but you cannot stop it. The reason I wanted to start and stop this manually was in order to avoid starting SoapUI every time I wanted to run my tests against Mock Services. I had to abandon this flow, and just settle for starting and stopping my Mock Services manually. It appears that no fix for this flow is on the candidate list for near-future releases: http://www.eviware.com/forums/index.php?topic=1806.msg6652#msg6652.

In Conclusion

I will definitely use the SoapUI toolkit on my next Web Services project. The ease of use is its most appealing aspect, and I really like that it integrates with Ant. The ability to run the tests that I create in SoapUI from within Ant is a huge benefit. This reduces my time and effort to write these tests, and allows for better test coverage of the exposed WSDL operations.

One of its biggest disappointments so far is its extremely basic Graphical display for the Load Test data. This is very archaic, and some basic updates could go a very long way. (e.g. put metrics on the left and bottom parts of the graph)