Building and deploying a simple Web Services Resource in IBM Lotus Expeditor

Learn how to build a simple Web Services Resource and how to deploy it to IBM Lotus Expeditor. This article explains the WSRF Tools that are used to generate server- and client-side components and how to develop a test client that you can use to test the WS-Resource.

Sivananthan Perumal (siva.perumal@in.ibm.com), Senior Staff Software Engineer, IBM, Software Group

Sivananthan Perumal is a Senior Staff Software Engineer, working in IBM Software Labs India. He has been working on Web services and related technologies for over three years. You can reach him at siva.perumal@in.ibm.com.



05 December 2006

Also available in Russian Japanese

Web Services Resource Framework (WSRF) specifications standardize the mechanism to statefully access a resource through Web services. IBM Lotus Expeditor incorporates WSRF as a feature, letting you expose OSGi services as resources. This article introduces the concepts involved in WSRF and explains the steps involved in modeling and exposing a simple stateful resource, implemented as an OSGi bundle, using Web services. It further illustrates how to access this stateful resource using the standard set of message exchange patterns defined in the WSRF specifications. The sample code used in this article is developed for the OSGi runtime provided by IBM Lotus Expeditor Client for Desktop V6.1.0.

In this article, you learn how to:

  • Model a simple stateful resource.
  • Use Lotus Expeditor Toolkit to implement WS-Resource provider-side components.
  • Use Lotus Expeditor Toolkit to create WS-Resource client-side components.
  • Deploy WS-Resource in Lotus Expeditor Client.
  • Develop the application to work with WS-Resource.

This article assumes that you have core Java skills and a basic knowledge of Web services, XML, and OSGi technology. Also, to run the sample applications, you must have the following installed on a Windows/Linux system:

  • Java 1.4.2
  • Lotus Expeditor Client V6.1.0 (with the Web Services Resource Framework 6.1.0.0 feature)
  • Eclipse 3.2.0 and Web Tools Project (WTP) 1.5.1
  • Lotus Expeditor Toolkit (with the Mobile Web Services 6.1.0 feature)

WS-Resource in Lotus Expeditor

A WS-Resource is the composition of a resource and a Web service through which the resource can be accessed. Lotus Expeditor Client for Desktop uses the following component stereotypes to realize a WS-Resource:

  • Resource
    An OSGi bundle that encapsulates one or more stateful OSGi service objects that must be exposed as a WS-Resource. These service objects may be a view of a business entity, such as ShoppingCart or PrintJob, or be a software facade for a physical resource, such as Printer. You are expected to provide the implementation of the service object as an OSGi bundle.
  • Web service
    An OSGi bundle that acts as a Web service facade for the WS-Resource. This component exposes WSRF standard port types and the custom port types as described in the Web Services Description Language (WSDL) of the WS-Resource. You can use the Mobile Web Services generator wizards to generate the entire Web service bundle for a given resource description.
  • Adapter
    An OSGi bundle that acts as a bridge between the Web services bundle and the resource bundle. It routes the incoming Web service messages (both the WSRF standard port types and the custom port types) to the resource instance addressed by the requestor. Any responses from the resource (including exceptions) are routed back through the adapter and the Web service bundle to the requestor as normal responses or faults. When you generate the Web services bundle, the Mobile Web Services generator wizards also generate the adapter bundle with placeholders. You are expected to provide implementations that tie the adapter to the resource instances.
  • Client stubs
    A Java archive that can be used by the consuming application to access and work with a WS-Resource. This client-side component (also referred to as Web service client stubs) translates the Java API calls to SOAP messages that subscribe to the WSDL file published by the WS-Resource. You can use the generator wizards to generate these client stubs entirely.

Refer to the Lotus Expeditor Help section "Developing Applications for Lotus Expeditor" for more information.


Setting up and verifying the development environment (Lotus Expeditor Toolkit)

You use Lotus Expeditor Toolkit with the Mobile Web Services feature as the development platform for the WS-Resource provider components and WS-Resource client components and to test them.

Follow the steps below to set up the development environment:

  1. Install Eclipse 3.2.0 with the Web Tools Project (WTP) 1.5.1.
  2. Install Lotus Expeditor Toolkit.
  3. Restart Eclipse.

NOTE: The Mobile Web Services 6.1.0 feature is installed as part of the Lotus Expeditor Toolkit. Refer to the Lotus Expeditor Toolkit Help for more information.

Follow these steps to verify the development environment setup:

  1. Run Eclipse.
  2. Choose File - New - Other.
  3. In the Select a wizard window, expand Mobile Web Services.
  4. Verify that WS-Resource Client and WS-Resource Provider appear as the children of Mobile Web Services.

Building a sample WS-Resource

In this section, we introduce the method and tools that are used to develop a simple WS-Resource, and we test the same using Lotus Expeditor Toolkit. You can find the source code of the completely developed WS-Resource in the Download section of this article. In this section, you follow these steps to develop all the components of the WS-Resource from scratch:

  • Construct a design model for the sample WS-Resource.
  • Implement the resource bundle for the WS-Resource.
  • Use the generator tools to generate the provider-side components.
  • Implement the logic to tie the adapter component to the resource component.
  • Use the generator tools to generate the client-side components.
  • Develop and execute the test application.

In later sections of this article, we explain the steps to package and deploy the WS-Resource in Lotus Expeditor Client for Desktop and the client application component for the WS-Resource. Developing a secure WS-Resource and accessing it are beyond the scope of this article.

Modeling the sample WS-Resource

To focus the attention on the method and the tools used to develop a WS-Resource, let's use a very simple data object, such as Address, and model it as a WS-Resource. The properties of the resource include eMailID, preference, and personDetails (see figure 1). Notice that the PersonDetails and ContactInfo are stereotyped as resource properties of the Address resource. Also, to create (and work with) multiple instances of Address WS-Resource, we have included the AddressFactory class in the design model.

Figure 1. Address resource - design model
Address resource - design model

NOTE: When modeling your own WS-Resource, refer to the Lotus Expeditor Help section, "Developing Applications for Lotus Expeditor," for the supported data types.

Developing the resource bundle

The design model discussed in the previous section must now be implemented as an OSGi bundle using Lotus Expeditor Toolkit. The resource bundle is developed as an Eclipse plug-in, using the plug-in development wizard of Eclipse SDK 3.2.0 (or later). To do this, in the plug-in development wizard, choose the OSGi Framework as standard when creating a new plug-in project.

The complete source code for the resource bundle is provided in the Download section. Note that the resource properties of the Address resource have been encoded as get/set methods in the AddressInterface:

Listing 1. com.ibm.wsrf.sampleapp.address.service.AddressInterface

public interface AddressInterface {
public void setEmailId(String emailId);
public String getEmailId();
public boolean getStatus();
public void setStatus(boolean status);
public String getPreference();
public void setPreference(String pref) throws Exception;
public float getVersionNumber();
public void setVersionNumber(float VersionNumber);

public Date getValidUntil();
public void setValidUntil(Date ValidUntil);

public PersonDetails getPersonDetails();
public void setPersonDetails(PersonDetails pDetails);
public ContactInfo getContactInfo();

/*****************************************************
 * Service Methods 			  	 
*****************************************************/
public ContactDetails[] getContactDetails(int type) 
throws ContactDetailsNotFoundException, InvalidAddressTypeException;
public void addContactDetails(ContactDetails contactObj);
public void addDependents(String[] names);
}

Later, when you use the Mobile Web Services generator wizards, this bean-like interface is used to describe the Resource Property document of the WS-Resource.

The AddressFactoryInterface is used by the adapter component to either create a new Address resource instance or locate an Address instance:

Listing 2. com.ibm.wsrf.sampleapp.address.service.AddressFactoryInterface

public interface AddressFactoryInterface {
	public String createAddress(String eMailId) throws Exception;
	public void deleteAddress(String eMailId) throws Exception;
	public AddressInterface getAddress(String eMailId) throws Exception;
}

You must modify the generated activator to include the start() & stop() methods:

Listing 3. com.ibm.wsrf.sampleapp.address.bundle.AddressActivator

public class AddressActivator implements BundleActivator {
    private ServiceRegistration serviceRegistration = null;
    public AddressActivator() {
    }
   public void start(BundleContext context) throws Exception {
       Hashtable properties = new Hashtable();
       serviceRegistration =  context.registerService
         (AddressFactoryInterface.class.getName(), new  AddressFactoryImpl(), properties);
   }
   public void stop(BundleContext context) throws Exception {
        serviceRegistration.unregister();
   }
}

Note that the AddressFactoryImpl instance is registered as a service implementation (and not AddressImpl). This is to facilitate creating multiple Address resources and locating and working with the relevant Address resource instance.

Generating provider-side components for the resource bundle

You can use the Mobile Web Services feature of Lotus Expeditor Toolkit to generate the resource adapter and Web service bundles of a WS-Resource. Refer to the Lotus Expeditor Toolkit Help section, "Developing Applications for Lotus Expeditor," for instructions on how to use the generator wizards to generate the provider-side components.

When using the WS-Resource Provider wizard, specify AddressFactoryInterface as resource class. The wizard introspects the Java interface for bean properties and prompts them as prospective resource properties. You can either choose these resource properties or specify new resource property names. These properties are used to construct the Resource Property document.

In the WS-Resource Provider wizard, make sure that you:

  • Select the WS-Resource Lifetime and Expose Service Methods properties.
  • Do not select the Enable Security property.
  • Select all the resource properties listed in the Resource Property panel of the wizard.
  • Select only those methods identified as service methods in the Address resource design model (figure 1) in the Service Methods panel of the wizard.
  • Edit the plug-in properties and the project properties in the wizard as necessary.

Tying the generated code with the resource bundle

The WS-Resource Provider wizard generates two projects in the Eclipse workspace, one each of the two provider-side bundles, namely, the adapter bundle and the Web services bundle. The Web services bundle need not be modified and can be deployed as is; however, the adapter bundle must be edited and wired to the resource bundle.

If you scan the generated code for the adapter bundle, you notice the following Java classes have placeholders with TODO's:

<Address>LifeTimeManager.java
<Address>PropertyManager.java

In the AddressLifeTimeManager class, you must provide implementation for the createResource(), destroyResource(), and getResource() operations. These operations are wired to use the corresponding services offered by the AddressFactoryImpl in the Address resource bundle.

Tying the createResource() operation

When a client application wants to create a new Address resource, it sends a createResource() message to the WS-Resource provider. The WSRF routes this message to the AddressLifeTimeManager class of the adapter component. The initialization parameters for createResource() are sent as an XML document in the ConfigInfo parameter. This XML document is available in the createResource() operation of the AddressLifeTimeManager as ResourceConfiguration object.

Note that this initialization parameter is extracted from the ResourceConfiguration and sent with the createAddress() message to the AddressFactoryImpl:

Listing 4. createResource code snippet

public ResourceConfiguration createResource(Element configInfo) 
				_throws ResourceUnavailableFault, ResourceUnknownFault, Exception {
		Element ele = (Element)configInfo.getElementsByTagName("eMailID").item(0);
		System.out.println(ele.getFirstChild().getNodeValue());
		String emailIdfromClient = ele.getFirstChild().getNodeValue();

		String eMailIdValue = getAddressFactory().createAddress(emailIdfromClient);
		
		ResourceConfiguration resourceConfiguration = new ResourceConfiguration();
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		Document document = db.newDocument();
		Text text = document.createTextNode(eMailIdValue);
		resourceConfiguration.addConfigurationInfo(emailIdQName, text);	
		
		return resourceConfiguration;
	}

After creating the resource using the AddressFactory, the createResource operation of the LifeTimeManager responds to the client with a ResourceConfiguration that is used to identify the Address instance in the future. The ResourceConfiguration information is encapsulated in the ReferenceParameter of the EndPointReference that is returned to the client application.

Tying the getResource() operation

Similarly, when a client application wants to access the resource to work with its Resource Property document, to destroy a WS-Resource, or to invoke a service method on the WS-Resource, the WSRF first attempts to obtain the Address resource instance using the getResource() operation in the AddressLifeTimeManager. The ResourceConfiguration information is once again used to uniquely identify the Address resource instance with the help of the AddressFactoryImpl. Notice that the getResource() operation invokes the getAddress() method of the AddressFactoryImpl to locate the Address object:

Listing 5. getResource code snippet

public Object getResource(ResourceConfiguration resourceConfiguration) 
        
        throws ResourceUnavailableFault, Exception {
		Node emailIdValue = resourceConfiguration.getConfigurationInfo(emailIdQName);
		System.out.println(emailIdValue);
		Text textInfo = (Text) emailIdValue;
		System.out.println(textInfo);
		String eid = textInfo.getNodeValue();
		System.out.println("ID from getResource::AddressLifeTimeManager :"+eid);
		Object addressObj = getAddressFactory().getAddress(eid);
		if(addressObj == null){
			throw new ResourceUnavailableFault("Resource Not Available !!", new Exception());
		}else{
			return addressObj;
		}
	}

Tying the destroyResource() operation

The Address resource is destroyed either by the destroy() method from the client application or when the TerminationTime is reached. When the resource is destroyed, the framework invokes the destroyResource() method in the AddressLifeTimeManager class of the adapter component. The ResourceConfiguration information is used to uniquely identify the Address resource instance:

Listing 6. destroyResource code snippet

public void destroyResource(ResourceConfiguration resourceConfiguration)
        
     throws ResourceUnavailableFault, ResourceNotDestroyedFault,Exception {
		Node emailIdValue = resourceConfiguration.getConfigurationInfo(emailIdQName);
		Text textInfo = (Text) emailIdValue;
		String eid = textInfo.getNodeValue();
		System.out.println("ID from destroyResource::AddressLifeTimeManager :"+eid);
		getAddressFactory().deleteAddress(eid);
	}

Tying the PropertyManager operations

The resource property values of the Resource Property document are always held by the resource instance. The framework does not cache these values; however, the framework maintains a list of all valid resource property names in the Resource Property document for any given instance of the WS-Resource. All the WSRF messages that result in a change in the Resource Property document of WS-Resource are processed by the PropertyManager class of the adapter. You can choose to consume the message or forward the same to the resource bundle.

In the AddressPropertyManager class, the generated code has placeholders for the get/update/delete/insert operations for all the properties. As discussed, you may provide implementation to forward the get or update message to the Address resource. Similarly, you have the option to forward the delete and insert message to the Address resource instance.

In this example, notice that (a) the update operation for the preference property is sent to the Address resource instance as a setPreference() message, (b) the get operation is sent to the Address resource as a getPreference message, (c) the insert operation is sent to the Address resource instance as a setPreference() message, and (d) the delete operation has no additional implementation:

Listing 7. AddressPropertyManager code snippet

(a)	public void updatePreference(Object resource, Object value)
		throws ResourceUnavailableFault,
		UnableToModifyResourcePropertyFault,
		UpdateResourcePropertiesRequestFailedFault,
		InvalidModificationFault,
		BaseFault, Exception {

		com.ibm.wsrf.sampleapp.address.service.AddressInterface resourceRef = 
	(com.ibm.wsrf.sampleapp.address.service.AddressInterface) resource;
		java.lang.String inValue = (java.lang.String)value;
		resourceRef.setPreference(inValue);
	}

(b)	public Object getPreference(Object resource)
		throws ResourceUnavailableFault, Exception {

		com.ibm.wsrf.sampleapp.address.service.AddressInterface resourceRef = 
	(com.ibm.wsrf.sampleapp.address.service.AddressInterface) resource;
		java.lang.String retValue = resourceRef.getPreference();
		return retValue;
	}

(c)	public void insertPreference(Object resource, Object value)
		throws ResourceUnavailableFault,
		UnableToModifyResourcePropertyFault,
		InsertResourcePropertiesRequestFailedFault,
		InvalidModificationFault,
		BaseFault, Exception {

		com.ibm.wsrf.sampleapp.address.service.AddressInterface resourceRef = 
	(com.ibm.wsrf.sampleapp.address.service.AddressInterface) resource;
		java.lang.String inValue = (java.lang.String)value;
		resourceRef.setPreference(inValue);
	}

(d)	public void deletePreference(Object resource)
		throws ResourceUnavailableFault,
		DeleteResourcePropertiesRequestFailedFault, Exception {

		com.ibm.wsrf.sampleapp.address.service.AddressInterface resourceRef = 
	(com.ibm.wsrf.sampleapp.address.service.AddressInterface) resource;
	}

When a client application wants to obtain a resource property value of an Address pointed to by an EndPointReference, it sends the getResourceProperty message with the QName of the resource property as parameter. The framework routes this message to the adapter component to first obtain the Address resource instance. The AddressLifeTimeManager's getResource() operation obtains the Address resource instance. Subsequently, the framework invokes the getPreference() operation in the AddressPropertyManager. The getPreference() operation of the AddressPropertyManager forwards this message to the corresponding operation in the Address resource.

You must provide similar implementations for the rest of the resource properties.

TIP: If a resource property is modeled as a read-only property, then you can either consume the update and insert message by not providing any additional implementation for these operations or throw an exception (for instance, InvalidModificationFault) in the implementation of the update and insert operation. If a resource property is modeled as a mandatory property, then you can throw DeleteResourcePropertiesRequestFailedFault exception in the implementation of the delete operation.

Tying the service manager operations

The custom port types of the WS-Resource (also referred to as service methods) are generated as part of the AddressServiceManager of the adapter component. The code generator, by default, generates code that ties these operations to the respective methods of the Address resource. You do not need to make any changes to the generated code in this regard.

Generating client-side components for the sample WS-Resource

After you complete the development of all the provider-side components (the resource bundle, adapter bundle, and Web services bundle), deploy these WS-Resource provider components in Lotus Expeditor Toolkit as a WS-Resource. For more information, refer to the Lotus Expeditor Help section, "Developing Applications for Lotus Expeditor," to launch a Client Services Server with the WS-Resource provider bundles.

To determine whether or not the WS-Resource is ready for consumption, enter this URL in a browser: http://localhost/ws/pid/Address?wsdl, where the pid of the WS-Resource is Address. The browser should display the WSDL file describing the Address resource.

Now, you can use the Mobile Web Services tool to generate the client components. Use the WS-Resource Client wizard (of the Mobile Web Services toolkit) to generate the client stub code. Refer to the Lotus Expeditor Help section, "Developing Applications for Lotus Expeditor," for instructions on how to use the generator wizards to generate client-side components.

You are not required to make any changes to the generated code.

Developing a simple test client application for the WS-Resource

To test the WS-Resource, you must develop a test application. This test application uses the client-side component to:

  • Create a new WS-Resource (Address) instance.
  • Send a standard WSRF message.
  • Invoke an operation from the custom portType.

The main() method of the test client application is shown below:

Listing 8. Test client code snippet

public static void main(String[] args) {
		String resourceUniqueId = "wsrf_support@ibm.com";
		TestClient tc = new TestClient();
		EndpointReference resEPR = null;
		/**
		 * Creates the WS-Resource with the given resource configuration and
		 * returns the EPR for further interaction with the WS-Resource.
		 */
		try {
			resEPR = tc.createResource(resourceUniqueId);
			if (resEPR != null)System.out.println("Resource created !! \n");
		} catch (Exception e) {
			e.printStackTrace();
		}

		OperationContext opContextObj = new OperationContext(); 
		opContextObj.setToEPR(resEPR);  
		AddressSoap_Stub stubObj = new AddressSoap_Stub();
		stubObj.setCurrentOperationContext(opContextObj);

		boolean updateResult = tc.testUpdateResourceProperty();
		if(updateResult == true)System.out.println("Update Resource Property :: SUCCESS");
		else System.out.println("Update Resource Property :: FAILED");

		boolean addResult = tc.testAddDependants();
		if(addResult == true)System.out.println("Add Dependants :: SUCCESS");
		else System.out.println("Add Dependants :: FAILED");
	}
}

Notice that the above code includes the following steps to:

  1. Create a new Address resource and obtain the EndPointReference (EPR).
  2. Set up the OperationContext.
  3. Test a WSRF standard operation, namely updateResourceProperties for the preference resource property.
  4. Test a service method, namely addDependents of Address resource by adding one dependent.

Refer to the Download section for the complete code.

Also in the previous code snippet, the OperationContext has been used to set up the communication channel between the client and the WS-Resource. The OperationContext holds the source of the message (in fromEPR) and the target for the message (in toEPR). You must make sure that the OperationContext holds a valid toEPR. Before invoking any operation on a WS-Resource, set the current OperationContext by invoking the setCurrentOperationContext(opContextObj) operation of the stub object.

As previously discussed, to create a new Address resource, the initialization parameter must be sent as an XML document in the ConfigInfo parameter and the initial value for the TerminationTime property. Because the AddressLifeTimeManager has been implemented to parse the following ResourceConfiguration XML document, the ConfigInfo XML document has the same structure:

Listing 9. ConfigInfo XML document

<ConfigInfo>
          <AddressResource/>
          <eMailID>
wsrf_support@ibm.com
          </eMailID>
</ConfigInfo>

The code to create a WS-Resource is shown here:

Listing 10. createResourcein test client code snippet

public EndpointReference createResource(String uniqueId)
			throws Exception {

		String hostName = "localhost"; // Hostname of the WebService 
		String serviceName = "Address"; // Service Name of the Resource 
		String uriString = "http://" + hostName + "/ws/pid/" + serviceName+ "?wsdl";

		WSAddressingService addressingObj = new WSAddressingServiceImpl();
		// creating the EPR of resourceFactory
		EndpointReference resourceFactoryEPR = addressingObj.createEndpointReference(uriString);
		
		// prepare configInfo parameter for createResource()
		Node[] configInfo = getConfigInfo(uniqueId); 
		
		// prepare initTerminationTime parameter for createResource()
		Calendar initTermTime = Calendar.getInstance();
		int curr = initTermTime.get(Calendar.HOUR);
		initTermTime.set(Calendar.HOUR, curr + 1);

		// Prepare the channel for communicating with Resource Factory
		OperationContext opContextObj = new OperationContext(); 
		opContextObj.setToEPR(resourceFactoryEPR); // Set the resourceFactoryEPR as toEPR 
		stubObj.setCurrentOperationContext(opContextObj);// Set the current OperationContext

		// Send createResource() message to the resourceFactory
		EndpointReference resourceEPR = stubObj.createWSResource(configInfo, initTermTime); 

		return resourceEPR;
	}

Note the following in listing 10:

  • An EndpointPointReference object is constructed for the resource factory. In this case, the URL for the EndPointReference is the same as that of the Address resource itself.
  • A communication channel is created from the client to the resource factory. An OperationContext object is created, and the EndPointReference of the resource factory is set as the toEPR.
  • The stub object of the Address resource is used to send the createResource() message to the resource factory.
  • The resource factory responds with an EndPointReference of the newly constructed Address resource object.

Finally, when the test application is executed, you see the following results:

Listing 11. Output of test client

Start Of Program !!
	 Resource created !!
	 Update Resource Property :: SUCCESS
	 Add Dependants :: SUCCESS
End Of Program !!

Setting up the runtime environment (Lotus Expeditor Client V6.1.0)

Lotus Expeditor Client for Desktop is the runtime used to deploy the Address resource. In this section, we introduce the steps involved in setting up the runtime environment to run the sample WS-Resource.

To set up the runtime, refer to the installation instructions in the Lotus Expeditor Help to install Lotus Expeditor Client V6.1.0 on Windows / Linux and the WSRF V6.1.0.0 feature on Lotus Expeditor Client.

To verify the runtime setup, follow these steps:

  1. Start Lotus Expeditor Client, using the -console option.
  2. In the console window, type ss to see the status of all installed plug-ins.
  3. In the plug-in list, verify that the com.ibm.pvcws.osgi_6.1.0 plug-in and all WSRF plug-ins are in the active state. If not, start these plug-ins.

Deploying the sample WS-Resource in Lotus Expeditor

After you have Lotus Expeditor Client for Desktop up and running, follow the steps below to deploy the Address WS-Resource provider components. Refer to the README.txt in the Download section to deploy the pre-built feature of AddressResource.

Preparing an Address WS-Resource feature for deployment

To install the Address WS-Resource in Lotus Expeditor Client for Desktop, you must package the WS-Resource as a feature. Follow these steps to create a feature:

  1. Create a new feature project in Lotus Expeditor Toolkit by choosing File - New - AddressFeature (for example).
  2. Select AddressResource, AddressAdapter, and AddressWebservice plug-ins in the Referenced Plug-ins and Fragments window.
  3. Click Finish.
  4. Right-click the newly created feature project, and then choose Export from the menu.
  5. In the Export window, select the Deployable features option, and then click Next.
  6. Enter the directory and click Finish.

Deploying the WS-Resource as a feature

To deploy the WS-Resource as a feature, perform these steps:

  1. In Lotus Expeditor Client, choose File - Applications - Install.
  2. Select "Search for new features to install," and then click Next.
  3. Click Add Folder Location, select the location where you have exported the feature in step 5 previously, and then click Finish.
  4. Restart Lotus Expeditor Client to reflect the deployment.

Verifying the deployment of WS-Resource

After Lotus Expeditor Client is started (with the -console option), ensure that the newly installed plug-ins have started by checking in the console window.

You can verify that the WSDL for the Address resource is published properly by entering the following URL in the browser: http://HostAddress:Port/ws/pid/ResourcePID?wsdl, where HostAddress is the IP address of the node that hosts Lotus Expeditor Client, Port is the port on which the Web service is running, and ResourcePID is the name of the resource.

For example, a sample URL might be http://localhost/ws/pid/Address?wsdl, assuming that the Lotus Expeditor Client V6.1.0 Web container component is configured to run on port 80 and to accept all IP addresses.


Executing the sample client application

After deploying the Address resource in Lotus Expeditor Client for Desktop, you can execute the sample client application provided in this article. This sample application is a Standard Widget Toolkit (SWT)-based Java program that allows you to send the various WSRF standard messages and the custom messages defined by the Address resource.

The client application has been implemented to demonstrate all the API features of WSRF for Lotus Expeditor Client. The features can be explored using the menu options WSRF Standard Operations and WSRF Custom Operations. In the WSRF Custom Operations menu, you can experiment with the factory and service methods (see figure 2).

Figure 2. WSRF Custom Operations menu
WSRF Custom Operations menu

In the WSRF Standard Operations menu, you can experiment with all the WSRF resource properties operations and the WSRF lifetime operations (see figure 3).

Figure 3. WSRF Standard Operations menu
WSRF Standard Operations menu

Summary

You have learned how to build a simple WS-Resource and how to deploy it to Lotus Expeditor Client for Desktop. You've also learned about the tools that are used to generate the provider-side and client-side components and how to develop a test client that you can use to test the WS-Resource developed as part of this article.


Download

DescriptionNameSize
Sample WS-Resource filesWSRF_AddressResourceSample.zip287 KB

Resources

Learn

Discuss

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 IBM collaboration and social software on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Lotus, SOA and web services
ArticleID=175279
ArticleTitle=Building and deploying a simple Web Services Resource in IBM Lotus Expeditor
publish-date=12052006