Friday, July 24, 2009

Two problems when writing the VbsNimbusService

Man, globus is not easy to use...

I encountered these two problems when writing the VbsNimbusService web service which integrates VBS with Nimbus:

1. We are trying to deserialize a workspace epr file in the execution of the service, but it reports a "no deserializer for {http://schemas.xmlsoap.org/ws/2004/03/addressing}AttributedURI" type of error when it comes to the XML type http://schemas.xmlsoap.org/ws/2004/03/addressing:AttributedURI. The problem is that the service found no type-mapping defined for this type. I did a lot of search and finally found a tip here: http://www.globus.org/toolkit/docs/4.0/common/javawscore/developer-index.html. There is the following notes about Java WS Core based client development:

"Any program that is based on Java WS Core should contain as a first entry in its classpath the directory of the Java WS Core installation. This is to ensure that the right client-config.wsdd is used by the client. That configuration file contains important client-side information such as handlers, type mappings, etc. "

That's it. There is a client-config.wsdd file under $GLOBUS_LOCATION which specifies deserialization classes for certain XML types. When you execute some clients deployed in globus, e.g., the Nimbus workspace client, their scripts make sure that the commands executing the clients' codes include $GLOBUS_LOCATION at the beginning of the CLASSPATH. But when you execute your own Java WS Core based clients, you need to add the directory containing that .wsdd file to the beginning of your CLASSPATH by yourself. And if that client is a web service itself, you will need to do this in the scripts that start your services' container. For example, if you deploy your service in tomcat, you will need to modify the catalina.sh file to specify the correct CLASSPATH.

2. The VbsNimbusService reports "Unkown CA" fault when doing authentication to the certificate of its own. VbsNimbusService uses a NimbusRPQueryClient to interact with the Nimbus workspace service. Like the Nimbus workspace client, NimbusRPQueryClient extends the org.globus.workspace.client_common.BaseClient class and thus also uses the credential got from GlobusCredential.getDefaultCredential() for authentication and authorization to the workspace service. The problem here is the trusted CA directory. For clients deployed in globus, the scripts running them specifies the trusted CA directory as the $X509_CERT_DIR environment variable, which contains the right trusted CAs. But when you are running your own Nimbus client without a globus container environment, the client's code will load the trusted CAs from some default directory. This "default directory" is just my guess, and I never even made it printed out so that I could copy the trusted CAs into it. Fortunately, I found the bug report here http://bugzilla.mcs.anl.gov/globus/show_bug.cgi?id=3843 and followed the instructions to set the trusted CA directory dynamically in the source codes of NimbusRPQueryClient, and finally made the VbsNimbusService work.

The instructions in the bug report above are not totally accurate. What we should actually do is to rewrite the setOptions(Stub stub) function in the class which extends org.globus.workspace.client_common.BaseClient (or org.globus.wsrf.client.BaseClient if you are not writing a Nimbus client), and add the following codes:

TrustedCertificates trustedCerts = TrustedCertificates.load("path to trusted certificates");
stub._setProperty(GSIConstants.TRUSTED_CERTIFICATES, trustedCerts);
super.setOptions(stub);

With this modification, your client should be able to set the right trusted CA directory without affecting the original execution of the BaseClient.

No comments: