Customizing WebSphere Service Registry and Repository using Java APIs

This article shows you how to customize WebSphere Service Registry and Repository using its flexible Java APIs, via two scenarios for the common administrative task of removing duplicate WSDL files: using a standalone EJB client, and using a Java validator plug-in.

Share:

Peter Cullen (pete.cullen@uk.ibm.com), Test Architect, IBM

Photo of Peter CullenPeter Cullen is a Software Engineer and Test Architect on the WebSphere Service Registry and Repository (WSRR) Team at the IBM Software Development Lab in Hursley, United Kingdom. Prior to working with WSRR, Peter spent seven years working on the WebSphere MQ team, where he specialized in functional testing. You can contact Peter at pete.cullen@uk.ibm.com.



Sarah Eggleston (sarah_eggleston@uk.ibm.com), Consultant, IBM Software Services for WebSphere, IBM

Photo of Sarah EgglestonSarah Eggleston is a consultant with IBM Software Services for WebSphere, and is based at the IBM Software Development Lab in Hursley, United Kingdom. She specializes in WebSphere Service Registry and Repository and governance, and her background includes Java development and support for WebSphere Application Server and WebSphere Service Registry and Repository. You can contact Sarah at sarah_eggleston@uk.ibm.com.



Isobel Nicholson (isobelnicholson@googlemail.com), Foundation Software Engineer, WebSphere Service Registry and Repository team, IBM

Photo of Isobel NicholsonIsobel Nicholson was previously a Foundation Software Engineer on the WebSphere Service Registry and Repository team at the IBM Software Development Lab in Hursley, United Kingdom. You can contact Isobel at isobelnicholson@googlemail.com.



10 August 2011

Also available in Chinese

Introduction

This article shows you how to write, compile, and execute Java™ code that uses APIs from IBM® WebSphere® Service Registry and Repository (hereafter called WSRR) to interact with the product. The article provides code snippets of the important calls in the body of the article, and complete source code in the file wsrr_examples.zip, which you can download at the bottom of the article.

The article assumes that you are familiar with WebSphere Application Server, Java programming, WSDL and XSD syntax, and WebSphere Service Registry and Repository V7. The examples are intended for technical users who would like to learn more about implementing code using the WSRR APIs. References and paths are given for WSRR V7.5 and Websphere Application Server V7.0, and the examples in the text are for Microsoft™ Windows™. The Java code should work with earlier WebSphere Service Registry and Repository versions such as V6.3 and V7.0. In order to use WebSphere Application Server V6.1, you will need to modify the environment classpath configuration.

Duplicate data scenario

In WSRR, WSDL and XSD documents are identified through a combination of the name, namespace, and version. By default, it is possible to load duplicate WSDLs or XSDs with the same name, namespace and version (or with no version) into WSRR. Once loaded, all documents and their associated internal objects are stored under a unique bsruri key, so internal processing can differentiate them, but they contain the same data. Therefore it is difficult for users to determine which of two duplicate entities they should use. You can see the bsruri key in the WSRR user interface detail display for any object, as well as in the results of an API query.

Example 1 in this article, the EJB client example, removes duplicate WSDLs that have already been loaded into the repository. This example should be used with care, because it deletes user data. The WSDL files have common names, namespaces, and versions, but different bsruris and creation timestamps, and the example uses these distinctions to decide which file to delete.

Example 2 in this article, the WSRR Java validator plug-in example, prevents further duplicate WSDLs from being loaded into WSRR.

WebSphere Service Registry and Repository APIs

It is possible to access content in WSRR through several interfaces, including REST. For more information about the different interfaces, see Resources at the bottom of the article.

For Java programmers, there are two client options, the EJB API and the Web services API. For more information about these two APIs, see Resources at the bottom of the article.

This example executes the EJB client as a pure Java class file invoked from the command line. You can use Java code in other Java and J2EE applications, as with all WebSphere Application Server clients.

Important: WebSphere Service Registry and Repository interfaces provide full access to your data, including create, delete, and update. Therefore you should thoroughly test the examples and any API clients before executing them against a production system.

Setting up the environment

Configuring the classpath for compiling

In order to access the EJB and WSRR client APIs, you need to add JAR files to your classpath, which can be found within Websphere Application Server after you have installed WSRR. For more information about the WebSphere Application Server environment configuration in the context of security and thin clients, see Resources at the bottom of the article. You'll need these settings to compile both examples, and for the runtime environment where you execute the EJB client for Example 1.

Sample configuration for WebSphere Application Server V7 on Microsoft Windows

In your environment configuration, provide the location of the WebSphere Application Server home, the WSRR and Java directories, and the location of the WSRR JAR files needed with the client API. Both examples execute a query against the ServiceRegistrySession EJB, so you also need to provide the location of the WebSphere Application Server EJB client JAR file.

Sample environment settings for WebSphere Application Server on Windows
set WAS_HOME=c:\ibm\appserver 
set WSRR_HOME=%WAS_HOME%\wsrr 
set JAVA_HOME=%WAS_HOME%\java\bin 

set CP1=.;%WSRR_HOME%\ServiceRegistryClient.jar;%WSRR_HOME%\sdo-int.jar; 
set CP2=%WAS_HOME%\runtimes\com.ibm.ws.ejb.thinclient_7.0.0.jar; 

set CLASSPATH=%CLASSPATH%;%CP1%;%CP2%;

For More information about how to build and load the plug-in JAR file, see Producing the JAR file below.

Example 1. Using an EJB client to remove duplicate WSDL files

Creating an EJB client and setting up the connection to the WSRR session bean

The JNDI name used to identify the home interface will be different depending on which version of WSRR you are using. The examples in this article assume that you are using V7.5, and therefore the basic call to create an EJB client looks like this:

Object ejbHome = 
   initialContext.lookup("ejb/com/ibm/serviceregistry/7_5/ServiceRegistrySessionHome");

If you are using a previous version of WSRR, then update the interface JNDI name accordingly. For more information, see Resources at the bottom of the article.

When you create an EJB client in a secure environment, if you have enabled application security in the Websphere Application Server hosting WebSphere Service Registry and Repository, then you need to make extra calls to authenticate your user id and password.

Set up the security and login context for an EJB
WSCallbackHandlerImpl callBackHandler = new WSCallbackHandlerImpl(userid, password);

Context initialContext = new InitialContext();
LoginContext loginContext = new LoginContext("WSLogin", callBackHandler);
loginContext.login();

Subject subject = loginContext.getSubject(); 
ContextManagerFactory.getInstance().setInvocationSubject(subject); 

Object ejbHome = initialContext.lookup 
("ejb/com/ibm/serviceregistry/7_5/ServiceRegistrySessionHome");

ServiceRegistrySessionHome srHome = (ServiceRegistrySessionHome) 
PortableRemoteObject.narrow(ejbHome, ServiceRegistrySessionHome.class);

ServiceRegistrySession session = srHome.create();

Important: While it is always recommended that you run with security enabled in a production environment, the EJB client application from this article can be run in a development environment where security is disabled. The example source provides two different methods, getServiceRegistrySession and getServiceRegistrySessionNoSecurity, so that you can see the different approaches depending on your security configuration.

Using the WSRR EJB client API

After you have created the ServiceRegistrySession object, you can use API calls from the WSRR session bean. For more information, see Resources at the bottom of the article.

In order to delete duplicate WSDLs, the two functions that the example uses are executeQuery (to look up the WSDLs in the Registry) and delete (by bsruri). The query syntax requires you to include the type of document (or object) that you are querying for the document properties that you would like returned (the example uses bsrURI, lastModified, name, namespace, and version).

Create the property query and configure properties for the parameters you are interested in
// create a property query object
PropertyQuery typeSearch = (PropertyQuery)DataFactory.INSTANCE.create 
   (TypeConstants.SR_URI, TypeConstants.TYPE_PROPERTYQUERY); 
// set the type of documents to look for
String expression1 = "/WSRR/WSDLDocument";
typeSearch.setQueryExpression(expression1);
// set the properties to retrieve
BSRSDOHelper.INSTANCE.addProperty(typeSearch, "p1", "name");
BSRSDOHelper.INSTANCE.addProperty(typeSearch, "p2", "namespace");
BSRSDOHelper.INSTANCE.addProperty(typeSearch, "p3", "version");
BSRSDOHelper.INSTANCE.addProperty(typeSearch, "p4", "bsrURI");
BSRSDOHelper.INSTANCE.addProperty(typeSearch, "p5", "lastModified");

// execute the query
List WSDLList = serviceRegistry.executeQuery(typeSearch);
Process the results of the query
// process the contents of the list in a loop
PropertyQueryResult queryResult = (PropertyQueryResult)WSDLList.get(i);

// retrieve the properties for each result 
String name = BSRSDOHelper 
   .INSTANCE.getPropertyQueryResultValue(queryResult,"name");
String namespace = BSRSDOHelper
   .INSTANCE.getPropertyQueryResultValue (queryResult,"namespace");
String version = BSRSDOHelper
   .INSTANCE.getPropertyQueryResultValue (queryResult,"version");
String date = BSRSDOHelper
   .INSTANCE.getPropertyQueryResultValue(queryResult,"lastModified");
String bsrURI =	BSRSDOHelper
   .INSTANCE.getPropertyQueryResultValue(queryResult,"bsrURI");

You can use the results from the query in your application logic. An example is provided in the sample source code, which you can download at the bottom of the article.

Delete a WSDL file
serviceRegistry.delete(bsrURI);

Standalone ("thin") clients in a secure environment

To execute a thin application server client in a secure environment, you also need to provide the client with runtime access to three properties files. You can set these as part of your environment configuration. If the files are expected to be in the same location in all of your environments. You can also configure their location in the source for the client:

Configure the location of the Websphere Application Server security properties files
System.setProperty("com.ibm.SSL.ConfigURL","file:///" + <wasHome> + 
"/profiles/" + <profileName> + "/properties/ssl.client.props"); 
System.setProperty("java.security.auth.login.config","file:///" + <wasHome> + 
"/profiles/" + <profileName> + "/properties/wsjaas_client.conf"); 
System.setProperty("com.ibm.CORBA.ConfigURL","file:///" + <wasHome> + 
"/profiles/" + <profileName> + "/properties/sas.client.props");

The default file locations are all in the same directory: <was_home>/profiles/<profile_name>/properties.

  • ssl.client.props
  • sas.client.props
  • wsjaas_client.conf

The sample code provided with this article has the location configured in the Java source code.

Producing the .class file

Compile the Java code using the command-line Java tool javac. This example uses a package name of com.mycorp.ejbclient. The source must be located in a directory structure that matches, such as c:\<wsrr_apps_dir>\com\mycorp\ejbclient. To compile the source Java file, configure the classpath as described above in Configuring the classpath for compiling. Then execute:

c:\<wsrr_apps_dir>javac 
com/mycorp/ejbclient/WSDLDuplicateRemover.java

Testing the .class file

To run the .class file, configure the same classpath that you used for compiling, as described above in Configuring the classpath for compiling. Then execute:

c:\<wsrr_apps_dir>java 
com/mycorp/ejbclient/WSDLDuplicateRemover [websphere_appserver_dir] 
[profile] [userid] [password] [hostname] [port]

If duplicates are found, the example client reports them like this:

The WSDL basic.wsdl from http://ibm.com/sr/test/wsdl/basic.wsdl is duplicated in the 
registry. The older version, b10222b1-33c0-40a1.b449.03280a034918, has been deleted.

If no duplicates are found, the example client returns with no changes made:

WSDLDuplicateRemover has finished processing

You can extend this example to delete other types of WSRR document, such as XSDs. If there are dependencies on a document, you will not be able to delete it. To find out if there is a potential dependency, you can use the UI or the Governance Bean to do impact analysis.

Troubleshooting

CORBA Connection refused

Example ConnectException
at com.mycorp.ejbclient.WSDLDuplicateRemover.main
(WSDLDuplicateRemover.java:90)

Caused by: org.omg.CORBA.TRANSIENT: java.net.ConnectException: 
Connection refused: connect:host=9.x.y.z,port=2809  vmcid: IBM  minor code: E02  
completed: No 
at com.ibm.CORBA.transport.TransportConnectionBase.connect
(TransportConnectionBase.java:425)
...

The client can't locate an application server on host 9.x.y.z,port 2809. Check that both port and IP address are correct, and that the application server is running.


CORBA NO_PERMISSION and SECJ0053E

Example SECJ0053E
Remote exception in WSDLDuplicateRemover java.rmi.AccessException: CORBA 
NO_PERMISSION 0x0 No; nested exception is:
org.omg.CORBA.NO_PERMISSION:
>> SERVER (id=4773e3aa, host=localhost) TRACE START:
>>    org.omg.CORBA.NO_PERMISSION: java.rmi.AccessException:  ; nested 
exception is:
com.ibm.websphere.csi.CSIAccessException: SECJ0053E: Authorization fail
d for ??? while invoking (Home)ServiceRegistry#ServiceRegistryAPIEJB.jar#Service
RegistrySession60 create::2 null  vmcid: 0x0  minor code: 0  completed: No

This error is usually caused by a basic connection failure, such as attempting to make a non-secured connection with a secure application server. If you are using the code from the files supplied with this article, make sure you use the getServiceRegistrySession method rather than the getServiceRegistrySessionNoSecurity method, and that you have passed in the correct parameters for your environment settings.


CORBA NO_PERMISSION and authentication failed

Example authentication failure
Login exception in WSDLDuplicateRemover com.ibm.websphere.security.auth.
WSLoginFailedException: Authentication Failed.
Note: The propagation of native registry error information is disabled by 
default. You may enable it by setting the property 
"com.ibm.websphere.security.registr y.propagateExceptionsToClient=true" 
using the server's administration console at Security -> Global Security -> 
Custom Properties.

The authentication failed error is usually caused by an incorrect user id or password.


SecurityException: Unable to locate a login configuration

Example IOException
java.lang.SecurityException: Unable to locate a login configuration at 
com.ibm.security.auth.login.ConfigFile.init(ConfigFile.java:124) at 
java.lang.J9VMInternals.newInstanceImpl(Native Method) at 
java.lang.Class.newInstance(Class.java:1328) at 
javax.security.auth.login.Configuration$3.run(Configuration.java:267) …
Caused by: java.io.IOException: Unable to locate a login configuration

This security exception is usually caused by a problem locating the three properties files (ssl.client.props, sas.client.props, and wsjaas_client.conf) or with the contents of those files If one of the files cannot be found, you should see a Path not found message. If the files are present, check whether the contents are correct.

Example 2. Using a WSRR validator plug-in to prevent loading duplicate WSDLs

WSRR plug-ins

The EJB client from Example 1 can be executed by a user on demand. WSRR also lets you create user code and embed it into the WSRR profile as a plug-in, so that it is executed during processing for every object loaded or modified in WSRR. For more information about creating and configuring plug-ins, see Resources at the bottom of the article.

When you write a plug-in application, you provide implementation code that WSRR executes every time one of the interface methods is called (directly through an API or indirectly through the UI). The interface methods you can implement for a validator are create, update, and delete.

Creating a validator plug-in

You can write a WSRR validator plug-in by creating a Java class that implements the interface com.ibm.serviceregistry.ServiceRegistryValidator:

Validator declaration
package com.mycorp.plugins.example;

import java.util.List;

import com.ibm.serviceregistry.ServiceRegistryStatus;
import com.ibm.serviceregistry.ServiceRegistryValidator;
import com.ibm.serviceregistry.delegate.DelegateFactory;
import com.ibm.serviceregistry.delegate.RepositoryDelegate;
import com.ibm.serviceregistry.sdo.OriginalObject;
import com.ibm.serviceregistry.sdo.PropertyQuery;
import com.ibm.serviceregistry.sdo.PropertyQueryResult;
import com.ibm.serviceregistry.sdo.WSDLDocument;
import com.ibm.serviceregistry.sdo.helper.BSRSDOHelper;
import com.ibm.serviceregistry.sdo.helper.DataFactory;
import com.ibm.serviceregistry.sdo.helper.TypeConstants;

public class NoDuplicatesValidator implements ServiceRegistryValidator {
Using the Repository Delegate
private RepositoryDelegate getRepositoryDelegate() throws Exception {
   return DelegateFactory.createRepositoryDelegate();
}

You don't need to write any specific code for security, even in a secure environment, because this plug-in runs within the WSRR application and inherits security credentials from WSRR.

The create method that you need to implement will be passed the content of the new object being created, and you can use SDO information from it in the validator logic:

Implement the create method from the Validator API
public ServiceRegistryStatus create(OriginalObject newObject) {

   final String methodName = "create";

   final String newName = newObject.getName();
   final String newNamespace = newObject.getNamespace();
   final String newVersion = newObject.getVersion();

   ServiceRegistryStatus srStatus = new ServiceRegistryStatus();

   if (newObject instanceof WSDLDocument) {
      logMsg(methodName, "Processing WSDL Document with name: " + newName
         + ", namespace:" + newNamespace + " and version: " + newVersion);
Look up all the WSDL documents already in the repository
try {
   // create the query
   final PropertyQuery query = (PropertyQuery) DataFactory.INSTANCE.create(
   TypeConstants.SR_URI, TypeConstants.TYPE_PROPERTYQUERY);
   final String myExpression = "/WSRR/WSDLDocument[@name='" + newName +
   "' and @namespace='" + newNamespace + "' and @version='" + newVersion + "']";

   query.setQueryExpression(myExpression);
   BSRSDOHelper.INSTANCE.addProperty(query, "p1", "name");

   // retrieve an instance of the registry and execute the query
   final RepositoryDelegate repositoryDelegate = getRepositoryDelegate();
   List<PropertyQueryResult> wsdlList = repositoryDelegate.executeQuery(query);
Process the WSDL list checking for duplicates
 // if we have one or more results, then the document already exists in the registry
         if (wsdlList.size() >= 1) {
            final String errorMsg = newName + " is a duplicate of an existing document."
               + " WSDLs must be unique.";

            srStatus.addDiagnostic(ServiceRegistryStatus.ERROR, errorMsg);
         }
      } catch (Exception e) {
         logMsg(methodName, e.getCause().toString());
         srStatus.addException(e);
      }
   }
return srStatus;

Producing the JAR file

Compiling the Java code and producing a JAR file that you load into WSRR as a configuration item is straightforward using the command line Java tools javac and jar. This example uses a package name of com.mycorp.plugins.example. The source needs to be located in a directory structure that matches, such as: c:\<wsrr_apps_dir>\com\mycorp\plugins\example.

Ensure that the CLASSPATH has been configured as described above under Classpath configuration for compiling. From the parent directory, for example c:\<wsrr_apps_dir>, execute the following command:

javac -Xlint:unchecked com/mycorp/plugins/example/NoDuplicatesValidator.java

One warning message will be produced, which is expected because the executeQuery method returns a raw list, which could hold any type of object. We are confident that it will only ever return a list of PropertyQueryResults, so you can safely ignore the warning from the compiler. It is possible to check the type of each element in the returned list and cast it to PropertyQueryResult.

Java compile warning
com/mycorp/plugins/example/NoDuplicatesValidator.java:43: warning:
[unchecked] unchecked conversion
found   : java.util.List
required: java.util.List<com.ibm.serviceregistry.sdo.PropertyQueryResult>
   List<PropertyQueryResult> wsdlList = registrySession.executeQuery(query);
                                                              ^
1 warning

After the code has been compiled, create the JAR file that you will load into WSRR. From the c:\<wsrr_apps_dir> directory, execute the following command:

jar -cvf NoDuplicatesValidator.jar com/mycorp/plugins/example/NoDuplicatesValidator.class

Loading the JAR file into WSRR

In the WSRR UI, switch to the Configuration perspective:

  1. Select Active Profile => Plug-in JARs => Load JAR plug-in.
  2. After the plug-in JAR has been loaded, it needs to be enabled: Select Active Profile => Validators => Validation properties plug-in (ValidationProperties).
  3. Append the fully qualified name of your validator to the validators= entry in the properties file, then save the changes. If you have used the examples in this article, the name will be com.mycorp.plugins.example.NoDuplicatesValidator. The validator is now enabled.

Test the plug-in

With the validator plug-in enabled, load a WSDL with the same name, namespace, and version as an existing WSDL, or with no version, and you should see this error:

Figure 1. GSR0044E from WSRR validator
GSR0044E from WSRR validator

Related information

Although the API includes a parameter for WARNING, the UI can only process ERROR or SUCCESS results (WARNING is treated as SUCCESS), so for most practical purposes, the WARNING option should not be used.

You can write notifier, modifier, or governance plug-ins as well as validator plug-ins, and the API is similar. For more information about plug-ins, see Resources below.

Conclusion

The WebSphere Service Registry and Repository Java APIs enable you to create standalone EJB clients and plug-in runtime code that can manage and enhance your user data, and then serve as reusable, automatable assets.


Download

DescriptionNameSize
Code samplewsrr_examples.zip12 KB

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=752208
ArticleTitle=Customizing WebSphere Service Registry and Repository using Java APIs
publish-date=08102011